3、Python和Java、PHP、C、C#、C++等其他语言的对比? python语言,是一种面向对象、直译式计算机程序设计语言,Python语法简洁而清晰,具有丰富和强大的类库。它常被昵称为胶水语言,它能够很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松地联结在一起。常见的一种应用情形是,使用python快速生成程序的原型(有时甚至是程序的最终界面),然后对其中有特别要求的部分,用更合适的语言改写。 4、简述解释型和编译型编程语言? 执行效率:解释器 < 编译 开发效率:解释器 > 编译 解释型不需要编译,在运行程序时才逐行翻译,只要安装了解释器,在任何环境下都可以运行,每次运行的时候都要解释一次,性能上不如编译型。 编译型存在预编译的过程,,运行时不需要编译,所以执行的效率高。编译之后如果需要修改就需要整个模块重新编译 5、Python解释器种类以及特点? CPython 在命令行运行python,就是启动CPython解释器 IPython 基于CPython上的一个交互式计时器,交互方式增加,功能和CPython一样 PyPy 目标是执行效率 采用JIT技术 对python代码进行动态编译,提高执行效率 JPython 运行在Java上的解释器,直接把pyhton代码编译为java字节码执行。 6、位和字节的关系? 位 bit 字节 byte 1byte = 8bit 计算机以字节为单位储存和解释信息,是计算机中处理数据的基本单位。 7、b、B、KB、MB、GB 的关系? 1GB = 1024MB 1MB = 1024KB 1KB = 1024B 1B = 8b 8、请至少列举5个 PEP8 规范(越多越好)。 代码编排: 缩进,需要4个 空格的缩进 每行长度最大为79 类和类之间的距离空两行;类中的方法之间空一行; 文档编排: 不要在依据import 里导入多个库,例如 import os,sys 注释: 原则,错误的注释不如没有注释,所以代码修改后,需要去修改注释。注释最好使用英文,完整的句子。 命名规范: 尽量单独使用小写字母'l',大写字母'O'等容易混淆的字母 命名函数使用全部小写的方式,可以使用下划线 9、通过代码实现如下转换: 二进制转换成十进制:v = “0b1111011” v = '0b1111011' print(int(v,2)) #123 十进制转换成二进制:v = 18 v = 18 print(bin(v)) #0b10010 八进制转换成十进制:v = “011” v = '011' print(int(v,8)) # 9 十进制转换成八进制:v = 30 v = 30 print(oct(v)) #0o36 十六进制转换成十进制:v = “0x12” v = '0x12' print(eval(v)) #18 print(int(v,16)) # 18 十进制转换成十六进制:v = 87 v = 87 print(hex(v)) #0x57 10、请编写一个函数实现将IP地址转换成一个整数。即将当个整数转变为二进制数据。 ip = 47.102.133.138 如 10.3.9.12 转换规则为: 10 00001010 3 0000001 9 00001001 12 00001100 拿到最后拼接的二进制数据,将其装换为10进制数据 print('{:b}'.format(47)) # 二进制 print('{:d}'.format(47)) # 十进制 print('{:o}'.format(47)) # 八进制 print('{:x}'.format(47)) # 16进制 解答如下:借用format实现,int实现 a = '47.102.133.138' b = [] for i in a.split('.'): b.append('{:b}'.format(int(i))) st = '' for i in b: st += i print(st) #10111111001101000010110001010 print(int(st,2)) #400983434 python递归的最大层数? 其最大递归层数是可以设置的,默认在window上为998层, import sys sys.setrecursionlimit(n) 可设置 求10的阶乘 def multiplicate(num): if num == 1: return 1 temp = multiplicate(num-1)*num res = multiplicate(10) print(res) 11、求结果: v1 = 1 or 3 1 v2 = 1 and 3 3 v3 = 0 and 2 and 1 0 v4 = 0 and 2 or 1 1 v5 = 0 and 2 or 1 or 4 1 v6 = 0 or Flase and 1 False 均为假的话,返回最后一个值 ascii、unicode、utf-8、gbk 区别? python3中采用utf-8 python2中采用unique 先有的ascii,再有的gbk,统一后的unicode,最后的utf-8 unicode 用两个字节来存储汉子和英文字母,占有空间较大,读取速度快,utf-8 用一个字节储存英文单词,3-6个字节存储汉字,占有空间较少,英文大量数据都是以英文单词存在,传输速度快,读取效率低。 14、列举 Python2和Python3的区别? 1) 语法: python3中去除 <> ,改为了 != 整形除法得到的是浮点数,要得到整形,需要 // 去除了print 语句,加入了print()函数去实现相同的功能。 2.x: 使用逗号结尾禁止换行 3.x:使用空格代替换行,print(x,end='') 2.x 直接python关键字就可以输出新行 3.x 需要print()函数就可以输出新行 2) 数据类型: python3.x 去除了long,自动整合为了int() 3) 面向对象: 迭代器的next()方法改名为__next__(),增加内置 函数next(),用于调用迭代器的__next__()方法 4) 异常 所有异常都从BaseException继承,删除了StardardError 5)、其他 xrange()改名为range(),要获得一个list,需要显式调用: list(range(10)) 16、Python3和Python2中 int 和 long的区别? 对于int类型的数据: a = 11 b = 2 c = a/b 在python3中得到的是float类型的数据 5.5,而python2中得到的是int类型的5. 对于long(长整形)的数据: python2中独有的,python3中没有long.long可以将数字和字符串装换为一个长整型。和python3的int整合在一起了。在python3中,int类型是动态长度的,理论上支持无限大的数字。 17、xrange和range的区别? xrange只存在python2里 range返回的是一个列表对象,而xrange()返回的是一个xrange对象,类似于生成器。 二者都是在循环的时候去使用,但是xrange的性能比range好一些,因为不需要上来就开辟一块很大的内存空间。 当返回值很大时,建议使用xrange,除非要拿到的是一个列表。 18、文件操作时:xreadlines和readlines的区别? 补充:read,readline,readlines的区别: read():一次将文件读完,生成的文件内容是一个字符串类型,里面的参数可以指定一次读取数据的长度 readline():一次只读一行数据,返回的是list类型 readlines():将剩下的所有数据,每次按行读取整个文件内容 ,将读取到的内容放到一个列表中,返回的是list类型 xreadlines():python2中的,python3中删除掉了 xreadlines返回的是一个生成器类型。 20、字符串、列表、元组、字典每个常用的5个方法? 字符串:str join() 将序列中元素以指定的字符连接生成一个新的字符串。 需要注意:序列中的每一个元素都应该是字符串类型。 eg: a = '-' b = 'michael' c = ['change','everyehing'] print(a.join(b)) # m-i-c-h-a-e-l print(a.join(c)) # change-everyehing split() 按字符串切分 strip() 去除指定的字符串 endwith() startwith() replace() 替换 列表:list append() 尾部追加,成建制的追加 extend() 打散追加,个体化扩编 pop() 从列表里取出最后一个值 del list[0] 删除指定的索引 sort(reverse=True) 当列表里的数据类型一致时,正向排序 reverse() 直接倒序 insert(0,value) 指定索引插入值 remove() 直接删除具体的值,而非索引 元组:tuple 与列表很像,只不过元组是不可变类型 count() 统计元素的出现次数 index() 查找指定元素的索引,只返回满足要求的索引 len() 元组里元素的个数 字典:dist items() 解压赋值拿到key与value get(key,default) get取值,存在拿到值,不存在拿默认值 update({'name':'michel','age':24}) 更新,若存在键,则覆盖 pop('key') 根据key删除指定对象,返回key对应的值 popitem() 随即返回并删除字典中的一对键值,为空后直接报错 {}.fromkeys('键列表/元组',default) 创建一个新的字典 setdefault(key,default) 类似于get方法,查询指定key值,存在返回key值,不存在返回默认值 集合:set p_set = {'a','b','c','egon'} l_set = {'x','y','z','egon'} # 交集 res = p_set & l_set print(res) # {'egon'} # 用函数表示 res = p_set.intersection(l_set) print(res) # {'egon'} # 差集 res = p_set - l_set print(res) # {'c', 'a', 'b'} res = p_set.difference(l_set) print(res) # {'c', 'a', 'b'} #对称差集 res = p_set ^ l_set print(res) # {'b', 'x', 'z', 'a', 'y', 'c'} res = p_set.symmetric_difference(l_set) print(res) # {'b', 'x', 'z', 'a', 'y', 'c'} #赋值 p_set = p_set - l_set print(p_set) # {'b', 'a', 'c'} p_set.difference_update(l_set) print(p_set) # {'b', 'a', 'c'} s = set() s.add('abc') s.add('xyz') print(s) res = s.pop() print(res) # 随机删除一个ele元素 print(s.remove('abc')) # 有ele删除,无ele抛异常 21、lambda表达式格式以及应用场景? lambda x:x 没有函数名,函数体,一个返回值 应用场景:与内置函数搭配使用 ,起到筛选排序的作用 22、pass的作用? 空语句 do nothing 保证格式完整 保证语义完整 23、*arg和**kwarg作用 *args 接收位置参数 可以将元组类型的 数据打散交给位置参数 **kwargs 接收关键字参数 将字典数据类型转换为=号赋值语句 24、is和==的区别 is 比较的是id值 == 比较的是具体的值 25、简述Python的深浅拷贝以及应用场景? 涉及深浅拷贝时,需要先了解可变与不可变类型 可变类型:值改变,id不会改变, 例如列表,字典 不可变类型:值改变,id会改变,唯一 id变,意味着创建了一个新的内存空间。 复制:二者指向同一个内存空间,始终保持一致性 浅拷贝:二者的ip不同,但是始终共用同一个容器类型里的数据,不管其是不是不可变类型 深拷贝:二者的ip不同,之间再无瓜葛。 深拷贝的使用:定义一个模板,其他的去使用 26、Python垃圾回收机制? 以引用计数为主,标记清除、分代回收为辅的垃圾回收机制 引用计数:每个对象维护一个ob_ref字段,记录当前对象被引用的次数,每当新的应用指向该对象,则该字段的计数加一,当其的引用失效时,其计数字段对应的值减少1,一旦计数为0,该对象立即被回收。 缺点:需要额外的空间去维护引用计数,消耗资源。还有一点:无法解决对象的‘循环引用’。会导致内存泄露。 def f2(): '''循环引用''' while True: c1=A() c2=A() c1.t=c2 c2.t=c1 del c1 此时的c1的引用计数还剩下1,导致无法销毁该对象 del c2 此时的c1的引用计数还剩下1,同样导致无法销毁该对象 class T: def __init__(self): pass def func(self): pass import sys for i in range(3): T() a2 = T() print('a1的引用计数为{}'.format(sys.getrefcount(T()))) 1 print('a2的引用计数为{}'.format(sys.getrefcount(a2))) 2 补充: 因为没有生成单例,所以 此处每次循环时,生成的对象都是新的一个对象。 引用计数加1的情况: 1)、实例化产生一个对象时 a = T() 2)、对象被引用时,b = a 3)、对象作为一个参数传入到一个函数里 4)、对象作为一个元素,储存在容器里 引用计数减1的情况: 1)、对象的别名被显示销毁 2)、对象的别名赋予新的对象 3)、一个对象离开其的作用域 4)、对象所在容器 被销毁,或从容器中删除对象 分代回收: 根据对象的存活时间划分为不同的集合,每个集合为一个代,分别为 年轻代,中年代,老年代,其垃圾收集频率随着对象的存活时间的增大而减少。年轻代里的表的总数达到上限时,垃圾回收机制被触发,将可回收对象回收掉,不可回收对象移到中年代里,类推往复。 分代回收是建立在标记清除的基础上的。二者作为辅助垃圾回收去处理。 标记清除: 是基于追踪回收技术实现的垃圾回收算法。第一阶段是标记阶段,给所有的活动对象打上标记,第二阶段,将没有标记的对象进行回收。 最终版:垃圾回收 触发垃圾回收: 1、调用gc.collect(),需要先导入gc模块。 2、gc模块的计数器达到阀值 3、程序退出的时候。 解决循环引用的问题: 导入gc模块,gc模块提供一个接口给开发者设置垃圾回收的选项,一个主要功能就是解决循环引用的问题。 27、Python的可变类型和不可变类型? 可变类型:值改变,id保持不变,如列表,字典 不可变类型:值改变,id会改变,相当于重新开辟了一块新的内存空间。 28、求结果: v = dict.fromkeys(['k1','k2'],[]) v[‘k1’].append(666) print(v) # v = {'k1':[666],'k2':[666]} v[‘k1’] = 777 print(v) # v = {'k1':[777],'k2':[666]} 分析:在创建字典时,两个键的值指向的是同一个内存空间,所以相当于二者的值是复制,当append时,二者的值应该保持一致。当出现 复制语句时,k1所对应的value,却已不在当初的内存空间里了,因此导致k1的value改变,而k2的value没有改变。 29、列举常见的内置函数? lis = [1,2,4,6,8,3] res1 = max(lis,key=lambda x:x) res2 = min(lis,key=lambda x:x) res3 = sorted(lis,key=lambda x:x) res4 = sorted(liskey=lambda x:x,reverse=True) # map的使用 #map的使用 映射 # 与函数搭配使用 def fn(x): return x*x res = map(fn,[1,2,3,45,6]) print(list(res)) # 与lambda搭配 res = map(lambda x:x*x,[1,2,3,4,5]) print(list(res)) # 复杂版 res = map(lambda x,y:x+y,[1,2,3,4],[5,6,7,8]) print(list(res)) # 需要注意的是,得到的是map类型的对象,可以利用list去取值。 reduce 合并 虽然reduce是functools里的模块,但是还是的需要介绍一下其作用。 # 与函数搭配使用 from functools import reduce def func(x,y): return x+y res = reduce(func,[1,2,3,4,5]) print(res) # 与lambda搭配使用 res = reduce(lambda x,y:x+y,[1,2,3,4,5,6]) print(res) #给定默认值 res = reduce(lambda x,y:x*y,[1,2,3,4,5],10) print(res) # 代替递归函数实现阶乘 res = reduce(lambda x,y:x*y,[i for i in range(1,11)]) print(res) # filter()的用法 def is_odd(n): return n%2==0 newlist = filter(is_odd,range(1,11)) print(list(newlist)) # 结合lambda使用 newlist = filter(lambda x:x%2 == 1,range(1,11)) print(list(newlist)) 总结:即存在min,max,filter,map,sorted 30、filter、map、reduce的作用? filter 过滤 map 映射 生成的是map对象,需要用list去取值 reduce 合并 reduce的用法: from functools import reduce res = reduce(lambda x,y:x*y,[i for i in range(1,11)]) print(res) # 也能实现阶乘的效果 filter的用法: filter(function or None,iterable) 返回的 是可迭代对象里的元素。 同样需要list去取值 31、一行代码实现9*9乘法表 原始版: def func(num): for i in range(1,num): for j in range(1,i+1): print('%s*%s=%s'%(j,i,j*i),end=' ') print() func(10) 一步到位: print( ' '.join([' '.join(["%s*%s=%s"%(j,i,j*i) for j in range(1,i+1)]) for i in range(1,10)])) 32、实现金字塔 max_level = 10 for current_level in range(1,max_level+1): for i in range(max_level-current_level): print(' ',end='') for j in range(2*current_level-1): print('*',end='') print() 33、至少列举8个常用模块都有那些? time datetime json 序列化 pickle 序列化 shelve 可以用来读写文件 shutil 移动复制压缩文件 os sys logging 日志 re 正则 35、什么是正则的贪婪匹配? 尽可能的多去获取值 ? 0-1个 + 1-n个 * 0-n个 38、def func(a,b=[]) 这种写法有什么坑? 后面每次传值的时候,变量b一直使用的是第一次内存空间里的list, 因此b的值会一直增加,类似于外界给其一直append. 39、如何实现 “1,2,3” 变成 [‘1’,’2’,’3’] ? a = "1,2,3" b = a.split(',') print(b) 40、如何实现[‘1’,’2’,’3’]变成[1,2,3] ? a = ['1','2','3'] b = [] for i in a: b.append(int(i)) a = b 41、如何用一行代码生成[1,4,9,16,25,36,49,64,81,100] ? 列表生成式: a = [x**2 for x in range(1,11)] 42、一行代码实现删除列表中重复的值 ? a = [1,2,3,4,4,3,2,1,5] a = list(set(a)) 即用set去实现。 44、logging模块的作用?以及应用场景? 用来生成日志,记录日常操作,报错信息 46、常用字符串格式化哪几种? %s,format,%d 47、简述 生成器、迭代器、可迭代对象 以及应用场景? 迭代:循环反馈(一次从容器 里获取一个值) 迭代器:从装有多个值的容器里取出一个值给外界 可迭代对象:对象有__iter__方法 常见 的list,tuple,dict,set 迭代器对象:存在__next__方法,每次获取容器里的值,一次一个,不需依赖索引取值。 可迭代对象通过调用__iter__得到的是一个迭代器对象。 a = [1,2,3,4,5] a_iter = a.__iter__() while True: try: print(a_iter.__next__()) except StopIteration: print('值已取完') break 读取文件时,可以直接利用f.__next__一次拿一行的数据。 生成器:file enumerate() 生成器:就是一个迭代器对象,函数内部存在yield关键字 可以利用for直接循环生成器,拿到里面yield的返回值,也可以用list去拿到。 enumerate的用法:拿到的是索引及其对应的值 for i in enumerate([1,2,3]): print(i) # 一个值去接收,拿到的(index,value) for i,v in enumerate((1,2,3)): print(i,v) # 两个值接收,拿到的是索引与值 48、用Python实现一个二分查找的函数。 递归实现: def func(li,middle): n = len(li) if n > 0: mid = n//2 if li[mid] > middle: return func(li[:mid],middle) elif li[mid] < middle: return func(li[mid+1:],middle) else: return True,li[mid] else: return False li = [i for i in range(1,100)] result = func(li,66) print(result) 常规实现: def func(li,middle): n = len(li) first = 0 last = n-1 while first <= last: mid = (first + last) // 2 if li[mid] == middle: return True elif li[mid] > middle: last = mid - 1 else: first = mid + 1 return False result = func(li,45) print(result) 49、谈谈你对闭包的理解? 被包裹的函数,内部函数对象作为外部函数的返回值,使用外层函数的变量。为什么外层函数执行完后,内部函数还能使用外层函数的变量,因为闭包函数作为一种函数对象,里面的属性会保存自己使用到的外层函数的局部变量,学术名为自由变量。 avg.__closure__[0].cell_contents可以查看这些自由变量。 50、os和sys模块的作用? os负责程序与操作系统的交互,提供访问操作系统底层的接口;日常用来创建文件,操作文件 sys负责程序与python解释器的交互,提供了许多的函数和变量,用来操控python运行时的环境;常用来获取操作系统的相关信息 51、如何生成一个随机数? import random random.randint(1,10) 52、如何使用python删除一个文件? os.remove() 54、写代码并实现: Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would have exactly one solution, and you may not use the same element twice. Example: Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1] def solution(nums,target): dict1 = {} for i in range(0,len(nums)): num = target-nums[i] if num not in dict1: dict1[nums[i]] = i # 将当前索引与值放入字典 else: return [dict1[num],i] # 匹配之前存入的另外一个数 nums = [1,2,5,9] target = 10 result = solution(nums,target) print(result) 55、json序列化时,可以处理的数据类型有哪些?如何定制支持datetime类型? 常见数据类型的数据都可以处理,但是json不支持序列化datetime类型的数据。 import json import time from datetime import datetime a = { 'name':'michael', 'age':24 } b = [1,2,3,4,'a','chang'] c = time.time() print(c) d = datetime.now() print(d) class ComplexEncoder(json.JSONEncoder): def default(self, o): if isinstance(o,datetime): return o.strftime('%Y-%m-%d %H:%M:%S') else: return json.JSONEncoder.default(self,o) with open('json序列化','w',encoding='utf-8') as f: f.write(json.dumps(a)) f.write(json.dumps(b)) f.write(json.dumps(c)) f.write(json.dumps(d,cls=ComplexEncoder)) 56、json序列化时,默认遇到中文会转换成unicode,如果想要保留中文怎么办? import jsonn a = '好好赚钱,上海买套房' with open('test','w',encoding='utff-8') as f: f.write(json.dumps(a,ensure_ascii=False)) 57、什么是断言?应用场景? 符合条件,程序才继续往下走。 应用场景:当判断 某个条件为真时,可以选择使用assert, 对于报错信息,可以使用异常捕获去处理。 58、有用过with statement吗?它的好处是什么? 59、使用代码实现查看列举目录下的所有文件。 import os def func(file_name): a = os.listdir(file_name) return a file_name = input('请输入想查找的目录:') print(func(file_name)) 60、简述 yield和yield from关键字。 yield:在函数里使用该关键字,那么该函数就成为了生成器。 yield可以接受值,也可以返回值 当yield接收值时,需要先调用next(c)或者send(None)方法,执行到yield语句,等待接收数据,否则会报错。 def consumer(): r = '' while True: n = yield r if not n: return print('[consumer]Consuming%s'%(n)) r = '200OK' def producer(c): c.send(None) # next(c) n = 0 while n < 5: n += 1 print('[PRODUCER]Producer%s'%(n)) r = c.send(n) print('[PRODUCER]Consumer return %s'%(r)) c.close() c = consumer() producer(c) 为了让生成器直接 在其他函数内部直接调用。产生了yield from