python常见面试题

1.python中可变对象和不可变对象:

可变对象:list dict set

不可变对象:int float bool string tuple

文章链接: https://www.jianshu.com/p/c5582e23b26c — 仔细看

2.python的垃圾回收机制:

文章链接: https://www.cnblogs.com/kumata/p/9099134.html

或者看我自己的博客

3.如何判断单链表中是否有环和找出环的出口:

文章链接: https://blog.csdn.net/yangnianjinxin/article/details/79025768

4.十大排序算法:必须掌握

文章链接: https://blog.csdn.net/qq_42166308/article/details/103356606

5.闭包和装饰器(面向切面编程AOP)实现与区别:

装饰器本质上是一个Python函数,它可以让其它函数在不作任何变动的情况下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景。比如:插入日志、性能测试、事务处理、缓存、权限校验等。有了装饰器我们就可以抽离出大量的与函数功能无关的雷同代码进行重用。

视频链接: https://www.bilibili.com/video/av18586448?from=search&seid=10638981423280212097

6.*args和**kwargs的理解:

文章链接: https://blog.csdn.net/leviopku/article/details/83580138

7.python伪线程解释:

文章链接: https://blog.csdn.net/G_SANGSK/article/details/80867629

8.一行代码实现9*9乘法表:

print("\n".join("\t".join("%s*%s=%s" %(x,y,x*y) for y in range(1, x+1)) for x in range(1, 10)))

10.深浅拷贝原理

import copy
a = [1, 2, 3, 4, ['a', 'b']]  #原始对象b = a  #赋值,传对象的引用
c = copy.copy(a)  #对象拷贝,浅拷贝
d = copy.deepcopy(a)  #对象拷贝,深拷贝a.append(5)  #修改对象a
a[4].append('c')  #修改对象a中的['a', 'b']数组对象print 'a = ', a
print 'b = ', b
print 'c = ', c
print 'd = ', d输出结果:
a =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
b =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
c =  [1, 2, 3, 4, ['a', 'b', 'c']]
d =  [1, 2, 3, 4, ['a', 'b']]

11.python中的新式继承(C3算法),菱形继承 自己找答案

新式类是采用广度优先搜索,旧式类采用深度优先搜索。

12.生成器、迭代器: https://www.runoob.com/python3/python3-iterator-generator.html

13.一行代码实现1-100的加和

sun(range(1,101))

14.字典如何删除和合并两个字典:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aetKMR7v-1584576197094)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1577689875331.png)]

15.python中datetime内置函数和pandas中datetime的相关知识:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yewGs1Rs-1584576197096)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1577696916198.png)]

https://www.cnblogs.com/nxf-rabbit75/p/10660317.html

16…现有字典 d= {‘a’:24,‘g’:52,‘i’:12,‘k’:33}请按value值进行排序?

sorted(d.items(),key=lambda x :x[1])

17.将字符串 “k:1 |k1:2|k2:3|k3:4”,处理成字典 {k:1,k1:2,…}

str1 = "k:1|k1:2|k2:3|k3:4"
#第一种
def str2dict(str1):dict1 = {}for iterms in str1.split('|'):key,value = iterms.split(':')dict1[key] = valuereturn dict1#第二种 重点!!!  t.split(':'),加了逗号就可以 相当于解包以为求出来需要[]取出,这里直接就可以加逗号解包
print({k:int(v) for t in str1.split('|') for k,v in (t.split(':'),)})

18.请按alist中元素的age由大到小排序

alist = [{'name':'a','age':20},{'name':'b','age':30},{'name':'c','age':25}]
def sort_by_age(list1):return sorted(alist,key=lambda x:x['age'],reverse=True)

19.什么是单例模式?python如何实现单例模式?请写出两种实现方式?

https://www.cnblogs.com/huchong/p/8244279.html

第一种方法:使用装饰器

def singleton(cls):instances = {}def wrapper(*args, **kwargs):if cls not in instances:instances[cls] = cls(*args, **kwargs)return instances[cls]return wrapper@singleton
class Foo(object):pass
foo1 = Foo()
foo2 = Foo()
print(foo1 is foo2)  # True

第二种方法:使用基类 New 是真正创建实例对象的方法,所以重写基类的new 方法,以此保证创建对象的时候只生成一个实例

class Singleton(object):def __new__(cls, *args, **kwargs):if not hasattr(cls, '_instance'):cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)return cls._instanceclass Foo(Singleton):passfoo1 = Foo()
foo2 = Foo()print(foo1 is foo2)  # True

第三种方法:元类,元类是用于创建类对象的类,类对象创建实例对象时一定要调用call方法,因此在调用call时候保证始终只创建一个实例即可,type是python的元类

class Singleton(type):def __call__(cls, *args, **kwargs):if not hasattr(cls, '_instance'):cls._instance = super(Singleton, cls).__call__(*args, **kwargs)return cls._instance# Python2
class Foo(object):__metaclass__ = Singleton# Python3
class Foo(metaclass=Singleton):passfoo1 = Foo()
foo2 = Foo()
print(foo1 is foo2)  # True

20.反转一个整数,例如-123 --> -321

class Solution(object):def reverse(self,x):if -10<x<10:return xstr_x = str(x)if str_x[0] !="-":str_x = str_x[::-1]x = int(str_x)else:str_x = str_x[1:][::-1]x = int(str_x)x = -xreturn x if -2147483648<x<2147483647 else 0 #2^31-1
if __name__ == '__main__':s = Solution()reverse_int = s.reverse(-120)print(reverse_int)

21.设计实现遍历目录与子目录,抓取.pyc文件

import os#os.walk()方法
#参考https://blog.csdn.net/bagboy_taobao_com/article/details/8938126
def get_files(dir,suffix):res = []for root,dirs,files in os.walk(dir):for filename in files:name,suf = os.path.splitext(filename) #取出后缀文本if suf == suffix:res.append(os.path.join(root,filename))print(res)get_files("./",'.pyc')

22.Python中变量的作用域?(变量查找顺序)

函数作用域的LEGB顺序

1.什么是LEGB?

L: local 函数内部作用域

E: enclosing 函数内部与内嵌函数之间

G: global 全局作用域

B: build-in 内置作用

python在函数里面的查找分为4种,称之为LEGB,也正是按照这是顺序来查找的

23.字符串 "123" 转换成 123,不使用内置api,例如 int()

#1.str函数
def get_value(s):num = 0for i in s:for j in range(10):if i == str(j):num = num * 10 +jreturn num#2.巧妙利用ord()函数
def get_value(s):num = 0for i in s:num = num * 10 +ord(i) - ord('0')return num#3.使用reduce方法
#参考https://www.runoob.com/python/python-func-reduce.html
from functools import reduce
def get_value(s):return reduce(lambda num, i: num * 10 + ord(i) - ord('0'), s, 0)#这里第三个参数是初始化num=0定义为整数,你可以自己试一试修改这个值
def get_value(s):return reduce(lambda num, i: num * 10 + ord(i) - ord('0'), s, 1)
#答案为1123

24. 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。示例:给定nums = [2,7,11,15],target=9 因为 nums[0]+nums[1] = 2+7 =9,所以返回[0,1]

def func1(nums,target):for i in range(len(nums)):num = target - nums[i]if num in nums:return [i, nums.index(num,i+1)] #从i+1之后开始找
#这里是让掌握.index()函数
#list.index(x[, start[, end]])
#x-- 查找的对象。
#start-- 可选,查找的起始位置。
#end-- 可选,查找的结束位置。

25.统计一个文本中单词频次最高的10个单词?(不懂!!)

# 使用 built-in 的 Counter 里面的 most_common
import re
from collections import Counterdef test2(filepath):with open(filepath) as f:return list(map(lambda c: c[0], Counter(re.sub("\W+", " ", f.read()).split()).most_common(10)))

26…两个有序列表,l1,l2,对这两个列表进行合并不可使用extend

def loop_merge_sort(l1,l2):tmp = []while len(l1)>0 and len(l2)>0:if l1[0] <l2[0]:tmp.append(l1[0])del l1[0]else:tmp.append(l2[0])del l2[0]while len(l1)>0:tmp.append(l1[0])del l1[0]while len(l2)>0:tmp.append(l2[0])del l2[0]return tmp

27. 让所有奇数都在偶数前面,而且奇数升序排列,偶数降序排序,如字符串’1982376455’,变成’1355798642’

#第一种方法
l1 = sorted([x for x in s if int(x) % 2 == 0],reverse=True)
l2 = sorted([x for x in s if int(x) % 2 != 0])
out = l2 + l1#第二种方法!!!(重点)
print("".join(sorted(l, key=lambda x: int(x) % 2 == 0 and 20 - int(x) or int(x))))

28.闭包影响

def multi():return [lambda x : i*x for i in range(4)]
print([m(3) for m in multi()]) #正确答案是[9,9,9,9],而不是[0,3,6,9]产生的原因是Python的闭包的后期绑定导致的,这意味着在闭包中的变量是在内部函数被调用的时候被查找的,因为,最后函数被调用的时候,for循环已经完成, i 的值最后是3,因此每一个返回值的i都是3,所以最后的结果是[9,9,9,9]

29.判断一个数为奇数、偶数

#1.条件  x % 2 == 0发现新大陆 偶数和1做与运算为0  奇数为1
#2.条件  x & 1 != 0(奇数)   3&1输出1  4&1输出0

30.map filter reduce方法使用:

文章链接: https://www.jianshu.com/p/44981aba7b1c

其中有个发现点:

>>> list1 = [11,22,33]
>>> map(None,list1)
[11, 22, 33]
>>> list1 = [11,22,33]
>>> list2 = [44,55,66]
>>> list3 = [77,88,99]
>>> map(None,list1,list2,list3)
[(11, 44, 77), (22, 55, 88), (33, 66, 99)]#和zip(list1,list2,list3)使用一样

31.python中静态方法、类方法、实例方法:

文章链接: https://blog.csdn.net/lihao21/article/details/79762681

32.优化 Python 性能:PyPy、Numba 与 Cython,谁才是目前最优秀的 Python 运算解决方案?

文章链接: https://www.zhihu.com/question/24695645

33.Python中如何动态获取和设置对象的属性?(作为了解)

if hasattr(Parent, 'x'):print(getattr(Parent, 'x'))setattr(Parent, 'x',3)
print(getattr(Parent,'x'))

34…哪些操作会导致Python内存溢出,怎么处理?

文章链接: https://www.cnblogs.com/xybaby/p/7491656.html 很全面,认真看!!

35.函数调用参数的传递方式是值传递还是引用传递?

Python的参数传递有:位置参数、默认参数、可变参数、关键字参数。

函数的传值到底是值传递还是引用传递、要分情况:

不可变参数用值传递:像整数和字符串这样的不可变对象,是通过拷贝进行传递的,因为你无论如何都不可能在原处改变不可变对象。

可变参数是引用传递:比如像列表,字典这样的对象是通过引用传递、和C语言里面的用指针传递数组很相似,可变对象能在函数内部改变。

36.一句话解决阶乘函数?

reduce(lambda x,y : x*y,range(1,n+1))

37.请用一行代码 实现将1-N 的整数列表以3为单位分组

N =100
print ([[x for x in range(1,100)] [i:i+3] for i in range(0,N,3)])

38…面向对象中怎么实现只读属性?(两种方法)

  1. 将对象私有化,通过共有方法提供一个读取数据的接口

    class person:def __init__(self, x):self.__age = 10def age(self):return self.__age
    t = person(22)
    # t.__age =100
    print(t.age())
    
  2. 最好的方法

    class MyCls(object):__weight = 50@propertydef weight(self):return self.__weight
    

39.什么是面向对象?

面向对象是相当于面向过程而言的,面向过程语言是一种基于功能分析的,以算法为中心的程序设计方法,而面向对象是一种基于结构分析的,以数据为中心的程序设计思想。在面向对象语言中有一个很重要的东西,叫做类。面向对象有三大特性:封装、继承、多态。

知乎: 把一组数据结构和处理它们的方法组成对象(object), 把相同行为的对象归纳为(class), 通过类的封装(encapsulation)隐藏内部细节, 通过继承(inheritance)实现类的特化(specialization)/泛化(generalization), ,通过多态(polymorphism)实现基于对象类型的动态分派(dynamic dispatch)。

40.a = “abbbccc”,用正则匹配为abccc,不管有多少b,就出现一次?

#思路:不管有多少个b替换成一个re.sub(r'b+', 'b', a)#re.sub()补充看这个文章https://blog.csdn.net/lovemianmian/article/details/8867613

41.正则表达式贪婪与非贪婪模式的区别

贪婪模式:
定义:正则表达式去匹配时,会尽量多的匹配符合条件的内容
标识符:+,?,*,{n},{n,},{n,m}
匹配时,如果遇到上述标识符,代表是贪婪匹配,会尽可能多的去匹配内容非贪婪模式:
定义:正则表达式去匹配时,会尽量少的匹配符合条件的内容 也就是说,一旦发现匹配符合要求,立马就匹配成功,而不会继续匹配下去(除非有g,开启下一组匹配)
标识符:+?,??,*?,{n}?,{n,}?,{n,m}?
可以看到,非贪婪模式的标识符很有规律,就是贪婪模式的标识符后面加上一个?

42.进程总结

进程:程序运行在操作系统上的一个实例,就称之为进程。进程需要相应的系统资源:内存、时间片、pid。 创建进程: 首先要导入multiprocessing中的Process: 创建一个Process对象; 创建Process对象时,可以传递参数;

p = Process(target=XXX,args=(tuple,),kwargs={key:value})
#target = XXX 指定的任务函数,不用加(),
#args=(tuple,)kwargs={key:value}给任务函数传递的参数

在初始化Queue()对象时(例如q=Queue(),若在括号中没有指定最大可接受的消息数量,获数量为负值时,那么就代表可接受的消息数量没有上限一直到内存尽头)

Queue.qsize():返回当前队列包含的消息数量

Queue.empty():如果队列为空,返回True,反之False

Queue.full():如果队列满了,返回True,反之False

Queue.get([block[,timeout]]):获取队列中的一条消息,然后将其从队列中移除,

block默认值为True。

如果block使用默认值,且没有设置timeout(单位秒),消息队列如果为空,此时程序将被阻塞(停在读中状态),直到消息队列读到消息为止,如果设置了timeout,则会等待timeout秒,若还没读取到任何消息,则抛出“Queue.Empty"异常:

Queue.get_nowait()相当于Queue.get(False)

Queue.put(item,[block[,timeout]]):将item消息写入队列,block默认值为True; 如果block使用默认值,且没有设置timeout(单位秒),消息队列如果已经没有空间可写入,此时程序将被阻塞(停在写入状态),直到从消息队列腾出空间为止,如果设置了timeout,则会等待timeout秒,若还没空间,则抛出”Queue.Full"异常 如果block值为False,消息队列如果没有空间可写入,则会立刻抛出"Queue.Full"异常; Queue.put_nowait(item):相当Queue.put(item,False)

from multiprocessing import Process,Queue
import os,time,random
#写数据进程执行的代码:
def write(q):for value in ['A','B','C']:print("Put %s to queue..."%(value))q.put(value)time.sleep(random.random())
#读数据进程执行的代码
def read(q):while True:if not q.empty():value = q.get(True)print("Get %s from queue."%(value))time.sleep(random.random())else:break
if __name__=='__main__':#父进程创建Queue,并传给各个子进程q = Queue()pw = Process(target=write,args=(q,))pr = Process(target=read,args=(q,))#启动子进程pw ,写入:pw.start()#等待pw结束pw.join()#启动子进程pr,读取:pr.start()pr.join()#pr 进程里是死循环,无法等待其结束,只能强行终止:print('所有数据都写入并且读完')

进程池:

from multiprocessing import Pool
import os,time,randomdef worker(msg):t_start = time.time()print("%s 开始执行,进程号为%d"%(msg,os.getpid()))# random.random()随机生成0-1之间的浮点数time.sleep(random.random()*2)t_stop = time.time()print(msg,"执行完毕,耗时%0.2f”%(t_stop-t_start))po = Pool(3)#定义一个进程池,最大进程数3
for i in range(0,10):po.apply_async(worker,(i,))
print("---start----")
po.close()
po.join()
print("----end----")

如果要使用Pool创建进程,就需要使用multiprocessing.Manager()中的Queue(),而不是multiprocessing.Queue(),否则会得到如下的错误信息:

RuntimeError: Queue objects should only be shared between processs through inheritance

from multiprocessing import Manager,Pool
import os,time,random
def reader(q):print("reader 启动(%s),父进程为(%s)"%(os.getpid(),os.getpid()))for i in range(q.qsize()):print("reader 从Queue获取到消息:%s"%q.get(True))def writer(q):print("writer 启动(%s),父进程为(%s)"%(os.getpid(),os.getpid()))for i ini "itcast":q.put(i)
if __name__ == "__main__":print("(%s)start"%os.getpid())q = Manager().Queue()#使用Manager中的Queuepo = Pool()po.apply_async(wrtier,(q,))time.sleep(1)po.apply_async(reader,(q,))po.close()po.join()print("(%s)End"%os.getpid())

43.谈谈你对多进程,多线程,以及协程的理解,项目是否用?

这个问题被问的概念相当之大, 进程:一个运行的程序(代码)就是一个进程,没有运行的代码叫程序,进程是系统资源分配的最小单位,进程拥有自己独立的内存空间,所有进程间数据不共享,开销大。

线程: cpu调度执行的最小单位,也叫执行路径,不能独立存在,依赖进程存在,一个进程至少有一个线程,叫主线程,而多个线程共享内存(数据共享,共享全局变量),从而极大地提高了程序的运行效率。

协程: 是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操中栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。

44.多线程共同操作同一个数据互斥锁同步?(线程锁)

import threading
import time
class MyThread(threading.Thread):def run(self):global numtime.sleep(1)if mutex.acquire(1):num +=1msg = self.name + 'set num to ' +str(num)print(msg)mutex.release()
num = 0
mutex = threading.Lock()
def test():for i in range(5):t = MyThread()t.start()
if __name__=="__main__":test()

45.什么是多线程竞争?

线程是非独立的,同一个进程里线程是数据共享的,当各个线程访问数据资源时会出现竞争状态即:数据几乎同步会被多个线程占用,造成数据混乱,即所谓的线程不安全

那么怎么解决多线程竞争问题?—锁

锁的好处: 确保了某段关键代码(共享数据资源)只能由一个线程从头到尾完整地执行能解决多线程资源竞争下的原子操作问题。

锁的坏处: 阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了

锁的致命问题: 死锁

46.请介绍一下Python的线程同步?

一、 setDaemon(False) 当一个进程启动之后,会默认产生一个主线程,因为线程是程序执行的最小单位,当设置多线程时,主线程会创建多个子线程,在Python中,默认情况下就是setDaemon(False),主线程执行完自己的任务以后,就退出了,此时子线程会继续执行自己的任务,直到自己的任务结束。

例子

import threading
import timedef thread():time.sleep(2)print('---子线程结束---')def main():t1 = threading.Thread(target=thread)t1.start()print('---主线程--结束')if __name__ =='__main__':main()
#执行结果
---主线程--结束
---子线程结束---

二、 setDaemon(True) 当我们使用setDaemon(True)时,这是子线程为守护线程,主线程一旦执行结束,则全部子线程被强制终止

例子

import threading
import time
def thread():time.sleep(2)print(’---子线程结束---')
def main():t1 = threading.Thread(target=thread)t1.setDaemon(True)#设置子线程守护主线程t1.start()print('---主线程结束---')if __name__ =='__main__':main()
#执行结果
---主线程结束--- #只有主线程结束,子线程来不及执行就被强制结束

三、 join(线程同步) join 所完成的工作就是线程同步,即主线程任务结束以后,进入堵塞状态,一直等待所有的子线程结束以后,主线程再终止。

当设置守护线程时,含义是主线程对于子线程等待timeout的时间将会杀死该子线程,最后退出程序,所以说,如果有10个子线程,全部的等待时间就是每个timeout的累加和,简单的来说,就是给每个子线程一个timeou的时间,让他去执行,时间一到,不管任务有没有完成,直接杀死。

没有设置守护线程时,主线程将会等待timeout的累加和这样的一段时间,时间一到,主线程结束,但是并没有杀死子线程,子线程依然可以继续执行,直到子线程全部结束,程序退出。

例子

import threading
import timedef thread():time.sleep(2)print('---子线程结束---')def main():t1 = threading.Thread(target=thread)t1.setDaemon(True)t1.start()t1.join(timeout=1)#1 线程同步,主线程堵塞1s 然后主线程结束,子线程继续执行#2 如果不设置timeout参数就等子线程结束主线程再结束#3 如果设置了setDaemon=True和timeout=1主线程等待1s后会强制杀死子线程,然后主线程结束print('---主线程结束---')if __name__=='__main___':main()

47.什么是死锁?

死锁是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

原因和解决方案: https://baike.baidu.com/item/%E6%AD%BB%E9%94%81

扩展:GIL锁 全局解释器锁

作用: 限制多线程同时执行,保证同一时间只有一个线程执行,所以cython里的多线程其实是伪多线程!

所以python里常常使用协程技术来代替多线程,协程是一种更轻量级的线程。

进程和线程的切换时由系统决定,而协程由我们程序员自己决定,而模块gevent下切换是遇到了耗时操作时才会切换

三者的关系:进程里有线程,线程里有协程。

48.说说下面几个概念:同步,异步,阻塞,非阻塞?

同步: 多个任务之间有先后顺序执行,一个执行完下个才能执行。

异步: 多个任务之间没有先后顺序,可以同时执行,有时候一个任务可能要在必要的时候获取另一个同时执行的任务的结果,这个就叫回调!

阻塞: 如果卡住了调用者,调用者不能继续往下执行,就是说调用者阻塞了。

非阻塞: 如果不会卡住,可以继续执行,就是说非阻塞的。

同步异步相对于多任务而言,阻塞非阻塞相对于代码执行而言。

49.python中进程与线程的使用场景?

多进程适合在CPU密集操作(cpu操作指令比较多,如位多的的浮点运算)。

多线程适合在IO密性型操作(读写数据操作比多的的,比如爬虫)

50.线程是并发还是并行,进程是并发还是并行?

并行: 同一时刻多个任务同时在运行

并发:不会在同一时刻同时运行,存在交替执行的情况。

实现并行的库有:multiprocessing

实现并发的库有: threading

程序需要执行较多的读写、请求和回复任务的需要大量的IO操作,IO密集型操作使用并发更好。

CPU运算量大的程序,使用并行会更好

所以:线程是并发,进程是并行;

进程之间互相独立,是系统分配资源的最小单位,同一个线程中的所有线程共享资源。

51.数据库三范式: https://www.jianshu.com/p/3e97c2a1687b 详细解释

第一范式:要求有主键,并且要求每一个字段原子性不可再分
第二范式:要求所有非主键字段完全依赖主键,不能产生部分依赖
第三范式:所有非主键字段和主键字段之间不能产生传递依赖

52.MySql视图知识

文章链接: https://blog.csdn.net/moxigandashu/article/details/63254901

了解:视图是虚拟的表,与包含数据的表不一样,视图只包含使用时动态检索数据的查询;不包含任何列或数据。使用视图可以简化复杂的sql操作,隐藏具体的细节,保护数据;视图创建后,可以使用与表相同的方式利用它们。

视图不能被索引,也不能有关联的触发器或默认值,如果视图本身内有order by则对视图再次order by将被覆盖。

创建视图: create view xxx as xxxxxx

对于某些视图比如未使用联结子查询分组聚集函数Distinct Union等,是可以对其更新的,对视图的更新将对基表进行更新;但是视图主要用于简化检索,保护数据,并不用于更新,而且大部分视图都不可以更新。

53.数据库优化的思路

文章链接:https://blog.csdn.net/qq_36145093/article/details/88327148

54…存储过程与触发器的区别

文章链接: https://www.cnblogs.com/LILi666/p/10930309.html

55.Redis常见知识:(了解+自己总结的redis知识)

文章链接: https://www.cnblogs.com/jasontec/p/9699242.html

56.青蛙跳台阶问题

一只青蛙要跳上n层高的台阶,一次能跳一级,也可以跳两级,请问这只青蛙有多少种跳上这个n层台阶的方法?

方法1:递归

设青蛙跳上n级台阶有f(n)种方法,把这n种方法分为两大类,第一种最后一次跳了一级台阶,这类共有f(n-1)种,第二种最后一次跳了两级台阶,这种方法共有f(n-2)种,则得出递推公式f(n)=f(n-1) + f(n-2),显然f(1)=1,f(2)=2,这种方法虽然代码简单,但效率低,会超出时间上限

class Solution:def climbStairs(self,n):if n ==1:return 1elif n==2:return 2else:return self.climbStairs(n-1) + self.climbStairs(n-2)

方法2:用循环来代替递归

class Solution:def climbStairs(self,n):if n==1 or n==2:return na,b,c = 1,2,3for i in range(3,n+1):c = a+ba = bb = creturn c

57.序列化和反序列化:

文章链接: https://www.cnblogs.com/yyds/p/6563608.html

注意:

Python dict中的非字符串key被转换成JSON字符串时都会被转换为小写字符串;Python中的tuple,在序列化时会被转换为array,但是反序列化时,array会被转化为list;由以上两点可知,当Python对象中包含tuple数据或者包含dict,且dict中存在非字符串的key时,反序列化后得到的结果与原来的Python对象是不一致的;
对于Python内置的数据类型(如:str, unicode, int, float, bool, None, list, tuple, dict)json模块可以直接进行序列化/反序列化处理;对于自定义类的对象进行序列化和反序列化时,需要我们自己定义一个方法来完成定义object和dict之间进行转化

58.python二分法查找:

#第一种 非递归方法
def binary_search(alist,item):n = len(alist)start = 0end = len(alist) - 1while start <= end:mid = (start + end) // 2if alist[mid] == item:return midelif item < alist[mid]:end = mid - 1else:start = mid + 1return Falseprint(binary_search([1,2,3,34,56,57,78,87],3))
#第二种  递归方法
def binary_search(alist,item):n = len(alist)if 0 == n:return Falsemid = n // 2if alist[mid] == item:return midelif item < alist[mid]:return binary_search(alist[:mid], item)else:return binary_search(alist[mid + 1:], item)print(binary_search([1,2,3,34,56,57,78,87],3))

59.python实现Stack、Queue、链表、树:

一、实现栈的方法:

class Stack():def __init__(self, size):self.size = sizeself.stack = []self.top = -1def push(self, x):if self.isfull():raise Exception('stack is full')else:self.stack.append(x)self.top += 1def pop(self):if self.isempty():raise Exception('stack is empty')else:self.top -= 1self.stack.pop()def isfull(self):return self.top + 1 == self.sizedef isempty(self):return self.top == -1def showstack(self):print(self.stack)s = Stack(10)
for i in range(6):s.push(i)
s.showstack()
for i in range(3):s.pop()
s.showstack()

二、实现单向队列:【day22数据结构视频!!】

class Queue():def __init__(self, size):self.size = sizeself.queue = []self.rear = -1self.front = -1def enqueue(self, ele):if self.isfull():raise Exception('queue is full')else:self.queue.append(ele)self.rear += 1def denqueue(self):if self.isempty():raise Exception('queue is empty')else:self.queue.pop(0)self.front += 1def isfull(self):return self.rear - self.front + 1 == self.sizedef isempty(self):return self.front == self.reardef showenqueue(self):print(self.queue)queue = Queue(10)
for i in range(5):queue.enqueue(i)
queue.showenqueue()
for i in range(3):queue.denqueue()
queue.showenqueue()

三、实现双向队列:

'''
双端队列:(deque,全名double-ended queue),是一种具有队列和栈的性质的数据结构。
双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。双端队列可以在队列任意一端入队和出队。
'''
from collections import dequeclass Deque:def __init__(self):self.items = []def isEmpty(self):return self.items == []def add_front(self, item):# 从头部添加self.items.insert(0, item)def add_rear(self, item):self.items.append(item)def remove_front(self):return self.items.pop(0)def remove_rear(self):return self.items.pop()def size(self):return len(self.items)def print_all(self):for item in self.items:print(item)if __name__ == '__main__':dq = Deque()dq.add_front(8)dq.add_front(9)dq.add_front(0)dq.print_all()dq.add_rear(6)dq.print_all()print('-----------remove---------')dq.remove_front()dq.print_all()

四、实现单链表 【对应day21数据结构视频】

class Node:def __init__(self, data):self.data = dataself.next = Nonedef __str__(self):return str(self.data)class SingleList:def __init__(self, node=None):self._head = nodedef isEmpty(self):return self._head == Nonedef append(self, item):# 尾部添加node = Node(item)if self.isEmpty():self._head = nodeelse:cur = self._headwhile cur.next != None:cur = cur.nextcur.next = node# 求长度def len(self):cur = self._headcount = 0while cur != None:count += 1cur = cur.nextreturn count# 遍历def print_all(self):cur = self._headwhile cur != None:print(cur)cur = cur.nextdef pop(self, index):if index < 0 or index >= self.len():raise IndexError('index Error')if index == 0:self._head = self._head.nextelse:cur = self._head# 找到当前下标的前一个元素!!while index - 1:cur = cur.nextindex -= 1# 修改的next的指向位置cur.next = cur.next.nextdef insert(self, index, item):if index < 0 or index >= self.len():raise IndexError('index Error')if isinstance(item, Node):raise TypeError('不能是Node类型')else:node = Node(item)if index == 0:node.next = self._headself._head = nodeelse:cur = self._headwhile index - 1:cur = cur.nextindex -= 1node.next = cur.nextcur.next = nodedef update(self, index, new_item):passdef remove(self, item):passif __name__ == '__main__':slist = SingleList()print(slist.isEmpty())  # Trueprint(slist.len())slist.append(5)print(slist.isEmpty())  # Falseprint(slist.len())  # 1slist.append(8)slist.append(6)slist.append(3)slist.append(1)print(slist.isEmpty())  # Trueprint(slist.len())print('---------------------')slist.print_all()print('----------pop-------------')slist.pop(2)slist.print_all()print('--------insert-------')slist.insert(1, 19)slist.print_all()

五、实现双向链表

class Node:def __init__(self, data):self.data = dataself.next = Noneself.prev = Nonedef __str__(self):return str(self.data)class DoubleList:def __init__(self):self._head = Nonedef isEmpty(self):return self._head == Nonedef append(self, item):# 尾部添加node = Node(item)if self.isEmpty():self._head = nodeelse:cur = self._headwhile cur.next != None:cur = cur.nextcur.next = node# 求长度def add(self, item):node = Node(item)if self.isEmpty():self._head = nodeelse:node.next = self._headself._head.prev = nodeself._head = nodedef len(self):cur = self._headcount = 0while cur != None:count += 1cur = cur.nextreturn countdef print_all(self):cur = self._headwhile cur != None:print(cur)cur = cur.nextdef insert(self, index, item):if index < 0 or index >= self.len():raise IndexError('Index Error')if index == 0:node = Node(item)node.next = self._headself._head.prev = nodeself._head = nodeelse:node = Node(item)cur = self._head# 也是找到前一个元素while index - 1:cur = cur.nextindex -= 1# 下面这四句顺序无所谓node.prev = curnode.next = cur.next# 因为是双向的,所以反方向也得写cur.next.prev = nodecur.next = nodedef remove(self, item):if self.isEmpty():raise ValueError('item not in doublelinklist')else:cur = self._headif cur.data == item:# 删除的是头结点if cur.next == None:# 只有头部节点self._head = Noneelse:# 还有其他节点cur.next.prev = Noneself._head = cur.nextelse:while cur != None:if cur.data == item:cur.prev.next = cur.nextcur.next.prev = cur.prevbreakcur = cur.nextdef update(self, index, item):passif __name__ == '__main__':dlist = DoubleList()print(dlist.len())print(dlist.isEmpty())# dlist.append(6)# dlist.append(9)# dlist.append(5)# print(dlist.len())# print(dlist.isEmpty())# dlist.print_all()dlist.add(6)dlist.add(9)dlist.add(5)dlist.print_all()

六、实现树结构:

class Node:def __init__(self, data):self.data = dataself.lchild = Noneself.rchild = Noneclass Tree:def __init__(self):self.root = Nonedef add(self, data):node = Node(data)if self.root is None:self.root = nodereturnqueue = [self.root]while queue:cur = queue.pop(0)if cur.lchild is None:cur.lchild = nodereturnelse:queue.append(cur.lchild)if cur.rchild is None:cur.rchild = nodereturnelse:queue.append(cur.rchild)# 广度优先def breadth_travel(self):if self.root is None:returnqueue = [self.root]while queue:cur = queue.pop(0)print(cur.data, sep=' ', end="")if cur.lchild is not None:queue.append(cur.lchild)if cur.rchild is not None:queue.append(cur.rchild)# 先序遍历def front_travel(self, node):if node is None:returnprint(node.data, end=' ')self.front_travel(node.lchild)self.front_travel(node.rchild)# 中序遍历def mid_travel(self, node):if node is None:returnself.mid_travel(node.lchild)print(node.data, end=' ')self.mid_travel(node.rchild)def rear_travel(self, node):if node is None:returnself.rear_travel(node.lchild)self.rear_travel(node.rchild)print(node.data, end=' ')if __name__ == '__main__':t = Tree()for i in range(10):t.add(i)t.breadth_travel()print()# 执行先序遍历t.front_travel(t.root)print()# 中序遍历t.mid_travel(t.root)print()# 后序遍历t.rear_travel(t.root)

59.单链表翻转:没有很懂!!

文章链接: https://blog.csdn.net/u011452172/article/details/78127836

60.Python自省

这个也是python彪悍的特性.

自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型.简单一句就是运行时能够获得对象的类型.比如type(),dir(),getattr(),hasattr(),isinstance().

61. 迭代器和生成器重要面试题:

这里有个关于生成器的创建问题面试官有考: 问: 将列表生成式中[]改成() 之后数据结构是否改变? 答案:是,从列表变为生成器

>>> L = [x*x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x*x for x in range(10))
>>> g
<generator object <genexpr> at 0x0000028F8B774200>

通过列表生成式,可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含百万元素的列表,不仅是占用很大的内存空间,如:我们只需要访问前面的几个元素,后面大部分元素所占的空间都是浪费的。因此,没有必要创建完整的列表(节省大量内存空间)。在Python中,我们可以采用生成器:边循环,边计算的机制—>generator

62.*号巧妙使用:还可以看cookbook第一节

>>> def print_three_things(a, b, c):
...     print 'a = {0}, b = {1}, c = {2}'.format(a,b,c)
...
>>> mylist = ['aardvark', 'baboon', 'cat']
>>> print_three_things(*mylist)a = aardvark, b = baboon, c = cat

63.鸭子类型: “当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”

文章链接: https://blog.csdn.net/handsomekang/article/details/40270009

class Duck:def quack(self):print "这鸭子正在嘎嘎叫"def feathers(self):print "这鸭子拥有白色和灰色的羽毛"class Person:def quack(self):print "这人正在模仿鸭子"def feathers(self):print "这人在地上拿起1根羽毛然后给其他人看"def in_the_forest(duck):duck.quack()duck.feathers()def game():donald = Duck()john = Person()in_the_forest(donald)in_the_forest(john)game()

64.为什么 Python 不支持函数重载?其他语言大部分都支持的?

文章链接: https://www.zhihu.com/question/20053359

65. IO多路复用的机制 selectpoll、epoll之间的区别(搜狗面试)

文章链接: https://www.cnblogs.com/aspirant/p/9166944.html

66. 腾讯面试题:给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在40亿个数当中? (可以考虑作为项目经验!!)

文章链接: https://blog.csdn.net/v123411739/article/details/86652806?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

其中还涉及到bitmap算法、hashmap算法。

https://juejin.im/post/5c4fd2af51882525da267385

67.算法:海量日志数据,提取出某日访问百度次数最多的那个IP

文章链接: https://blog.csdn.net/tayanxunhua/article/details/20528389

68.什么是用户画像,一般用户画像的作用是什么?

文章链接: https://www.zhihu.com/question/19853605

69.协同过滤:下面只是参考,自己多查

协同过滤简单来说是利用某兴趣相投、拥有共同经验之群体的喜好来推荐用户感兴趣的信息,个人通过合作的机制给予信息相当程度的回应(如评分)并记录下来以达到过滤的目的进而帮助别人筛选信息,回应不一定局限于特别感兴趣的,特别不感兴趣信息的纪录也相当重要。

协同过滤又可分为评比(rating)或者群体过滤(social filtering)协同过滤以其出色的速度和健壮性,在全球互联网领域炙手可热。

文章链接: https://blog.csdn.net/yimingsilence/article/details/54934302

https://www.jianshu.com/p/5463ab162a58

70.抖音平台的推荐机制: https://www.kuaidou8.com/135

71.数据分析面试总结(经典)

文章链接: https://www.nowcoder.com/discuss/100521?type=2

72.数据分析必备算法 — TOP- K算法

文章链接: https://juejin.im/entry/5c565fb7f265da2d84105958

https://blog.csdn.net/luochoudan/article/details/53736752

73.动态规划:讲的特别好(这个老师有很多讲),进入个人空间里面还有深度遍历和广度遍历,这个老师的算法都要看,别偷懒

视频链接: https://space.bilibili.com/24014925/channel/detail?cid=44716

74.excel中的vlookup函数,输出后先右拉再下拉。—参考本文件夹下的vlookup.xlsx

75、空数据如何补充?看这篇博客 https://blog.csdn.net/Soft_Po/article/details/89302887

23411739/article/details/86652806?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

其中还涉及到bitmap算法、hashmap算法。

https://juejin.im/post/5c4fd2af51882525da267385

67.算法:海量日志数据,提取出某日访问百度次数最多的那个IP

文章链接: https://blog.csdn.net/tayanxunhua/article/details/20528389

68.什么是用户画像,一般用户画像的作用是什么?

文章链接: https://www.zhihu.com/question/19853605

69.协同过滤:下面只是参考,自己多查

协同过滤简单来说是利用某兴趣相投、拥有共同经验之群体的喜好来推荐用户感兴趣的信息,个人通过合作的机制给予信息相当程度的回应(如评分)并记录下来以达到过滤的目的进而帮助别人筛选信息,回应不一定局限于特别感兴趣的,特别不感兴趣信息的纪录也相当重要。

协同过滤又可分为评比(rating)或者群体过滤(social filtering)协同过滤以其出色的速度和健壮性,在全球互联网领域炙手可热。

文章链接: https://blog.csdn.net/yimingsilence/article/details/54934302

https://www.jianshu.com/p/5463ab162a58

70.抖音平台的推荐机制: https://www.kuaidou8.com/135

71.数据分析面试总结(经典)

文章链接: https://www.nowcoder.com/discuss/100521?type=2

72.数据分析必备算法 — TOP- K算法

文章链接: https://juejin.im/entry/5c565fb7f265da2d84105958

https://blog.csdn.net/luochoudan/article/details/53736752

73.动态规划:讲的特别好(这个老师有很多讲),进入个人空间里面还有深度遍历和广度遍历,这个老师的算法都要看,别偷懒

视频链接: https://space.bilibili.com/24014925/channel/detail?cid=44716

74.excel中的vlookup函数,输出后先右拉再下拉。—参考本文件夹下的vlookup.xlsx

75、空数据如何补充?看这篇博客 https://blog.csdn.net/Soft_Po/article/details/89302887

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wX75QSNX-1584576197101)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1583136797062.png)]

python常见知识相关推荐

  1. python基础知识资料-python基础知识整理(值得收藏)

    近些年python语言非常流行,许多开发者都会学习一些python相关知识,本文为大家整理了python的一些基础知识,希望对大家有一定的帮助. 注:下文Python代指Python3. 基本信息和J ...

  2. python中var是什么_这些Python Number 知识你需要了解!

    原标题:这些Python Number 知识你需要了解! 如果把编程比作建房子,那么数据就是建材.而建材有砖头.水泥.木头.钢材等,不同类型的建材配合工作,才能把房子建好.编程也一样,不同类型的数据类 ...

  3. 来自 Facebook 内部的 Python 学习知识图谱,太全了!

    这几年,学 Python 的程序员越来越多了,甚至不少人把 Python 当作第一语言来学习.也难怪,Python 的优点太多了,它语言简洁.开发效率高.可移植性强,并且可以和其他编程语言(比如C++ ...

  4. 第二篇 python基础知识总结:数据、运算符

    引子 我们跟任何人交流,说的每一句都是都一些文字组成,包含名词.动词.语句.标点符号等,组成我们说普通话构成的基本要素.同理我们学习python语言也要明白这些基本要素,也就是我们常说的基本语法,这是 ...

  5. Python基础知识-05-数据类型总结字典

    python其他知识目录 1.一道题,选择商品的序号.程序员和用户各自面对的序号起始值 如有变量 googs = ['汽车','飞机','火箭'] 提示用户可供选择的商品: 0,汽车 1,飞机 2,火 ...

  6. python常见排序算法解析

    python--常见排序算法解析 算法是程序员的灵魂. 下面的博文是我整理的感觉还不错的算法实现 原理的理解是最重要的,我会常回来看看,并坚持每天刷leetcode 本篇主要实现九(八)大排序算法,分 ...

  7. 万字精华——Python常见的60+面试题合集双手奉上!

    嘿~大家好,我是小编软件测试君: 本次呢,小编给大家发送一篇面试题,一共有60多道题~ 咱们一起来看看吧,请耐心阅读,可能会有点长长长长长长长长- 一.一行代码输出九九乘法表 print ('\n'. ...

  8. python基础知识-python基础知识整理(值得收藏)

    近些年python语言非常流行,许多开发者都会学习一些python相关知识,本文为大家整理了python的一些基础知识,希望对大家有一定的帮助. 注:下文Python代指Python3. 基本信息和J ...

  9. 初学者入门级!Python基础知识学习,纯干货【建议收藏】

    注释方法 # 单行注释 ''' 多行注释 ''' 数据类型 关键字 名称 示例 chr 单个字符 '', 'd' str 字符串(多个chr) 'dd', '你好' int 整数 1,2,3,4 fl ...

最新文章

  1. linux下移动c盘文件位置,问个问题我在unbuntu下为何找不到windows c盘文件
  2. 参加第十六届智能车竞赛学生提出的问题-05-10
  3. Java学习之for---each语句
  4. linux中rev命令详解,详解Linux中输出文件内容的rev与tac命令使用
  5. android:descendantFocusability用法简析
  6. php获取当前周得周一_php一行代码获取本周一,本周日,上周一,上周日,本月一日,本月最后一日,上月一日,上月最后一日日期...
  7. 【BZOJ3590】[Snoi2013]Quare 状压DP
  8. 吴恩达《机器学习》学习笔记六——过拟合与正则化
  9. AutoLISP绘制圆DCL对话框
  10. C++ 编译运行报错 error: stray ‘\200’ in program 解决方案
  11. 如何快速查看Oracle的安装目录
  12. ffmpeg推流错误
  13. [网络安全自学篇] 八十七.恶意代码检测技术详解及总结
  14. CDA Level1 考试心得
  15. 【学习笔记】C51 keil v4 流水灯简单代码的编写
  16. mumu 模拟器连不上adb
  17. 详解安全测试工具:SAST、DAST、IAST、SCA的异同
  18. 【数据结构】一张图让你读懂:树的高度、深度、层的区别
  19. 让Mac文本编辑器成为HTML编辑器
  20. python爬虫爬取微信_Python爬虫爬取微信公众号历史文章全部链接

热门文章

  1. 开始→运行(cmd)命令大全
  2. 怎样正确运用正当防卫?
  3. Android自定义View高级动效---粒子动效实现|音乐播放器粒子动效|实现酷我网易云粒子动效
  4. 说说缓存,说说Redis
  5. HTTP400 的坑
  6. 小企业如何挑选在线客服系统
  7. 【Android -- RxJava】RxJava2.0 教程(七),如何使用 Flowable
  8. 向日葵黑屏驱动导致亮度无法调节的解决方法
  9. 虚拟运营商到底给不给力?
  10. 绝了!华为技术专家居然把安全测试讲解这么细致!