基础不牢,地动山摇,面试的时候经常会被问到一些平时基础的很容易被忽视的知识点,所以重在积累,多看多背深入理解,才能在某一天工作中豁然开朗恍然大悟。
面试题不仅仅为了应付面试,更是知识点的一个梳理总结归类和拔高,正所谓巧妇难为无米之炊,寒冬之下多屯粮,勤练兵,一份努力一分收获。
最重要的放前头:
☆♠☆♠☆♠Python是如何进行内存管理的☆♠☆♠☆♠
较长,先记住在理解------------------------------------------------
一、垃圾回收:
python不像C++,Java等语言一样,他们可以不用事先声明变量类型而直接对变量进行赋值。对python语言来讲,对象的类型和内存都是在运行时确定的。这也是为什么我们称python语言为动态类型的原因(这里我们把动态类型语言可以简单的归结为对变量内存地址的分配是在运行时自动判断变量类型并对变量进行赋值)。
二、引用计数:
python采用了类似windows内核对象一样的方式来对内存进行管理。每一个对象,都维护这一个对指向该对象的引用的计数。当变量被绑定在一个对象上的时候,该变量的引用计数就是1,(还有另外一些情况也会导致变量引用计数的增加),系统会自动维护这些标签,并定时扫描,当某标签的引用计数变为0的时候,该对象就会被回收。
三、内存池机制
python的内存机制成金字塔形:
第-1,-2层主要有操作系统进行操作;
第0层是C中的malloc,free等内存分配和释放函数进行操作;
第1层和第2层是内存池,有python的接口函数PyMem_Malloc函数实现,当对象小于256字节时由该层直接分配内存;
第三层是最上层,也就是我们对python对象的直接操作;
在C中如果频繁的调用malloc与free时,是会产生性能问题的,在加上频繁的分配和释放小块的内存会产生内存碎片。
python在这里主要干的工作有:
如果请求分配的内存在1~256字节之间就使用自己的内存管理系统,否则直接使用malloc。
这里还是会调用malloc分配内存,但每次回分配一块大小为256字节的大块内存。
经由内存池登记的内存到最后还是会回收到内存池,并不会调用C的free释放掉,以便下次使用。对于简单的python对象,例如数值、字符串、元组(tuple不允许被更改)采用的是复制的方式(深拷贝),也就是说当讲另一个变量B赋值给变量A时,虽然A和B的内存空间仍然相同,但是当A的值发生变化时,会重新给A分配空间,A和B的地址变得不再相同。
一、Python中yield 的作用:
yield简单来说就是一个生成器,这样函数它记住上次返回时在函数中的位置。对于生成器第二次(或n次)调用跳转至该函数。
二、如何提高python的运行效率
1 使用生成器; 2 关键代码使用外部功能包(Cython,pylnlne,pypy,pyrex); 3 针对循环的优化--尽量避免在循环中访问变量的属性。
三、线上服务可能因为种种原因导致挂掉怎么办?
Linux下的后台进程管理利器supervisor
每次文件修改后在linux执行service supervisord restart
四、find和grep区别:
grep命令是一种强大的文本搜索工具,grep所有内容串可以是正则表达式,允许对文本文件进行模式查找。如果找到匹配模式,grep打印包含模式的所有行。
find通常用来在特定的目录下搜索符合条件的文件,也可以用来搜索特定用户属主的文件。
五、装饰器的作用和功能:
- 引入日志
- 函数执行时间统计
- 执行函数钱预备处理
- 执行函数后的清理功能
- 权限校验等场景
- 缓存
六、大数据的文件读取:
- 利用生成器generator
- 迭代器进行迭代遍历:for line in file
七、迭代器和生成器的区别:
- 迭代器是一个更加抽象的概念,任何对象,如果它的类有next方法和iter方法返回自身。对于string、list、dict、tuple等这类容器对象,使用for循环遍历是很方便的。在后台for语句对容器对象调用iter()函数,iter()是Python的内置函数。iter()会返回一个定义了next()方法的迭代器对象,它在容器中逐个访问容器内元素,next()也是python的内置函数。在没有后续元素时,next()会抛出一个StopIterration的异常。
- 生成器(Generator)是创建迭代器的简单而强大的工具。它们写起来就像是正规的函数,只是在返回数据的时候需要使用yield语句。每次next()被调用时,生成器会返回它脱离的位置(它记忆语句最后一次执行的位置和所有的数据值)
区别:生成器能做到迭代器能做的所有事,而且因为自动创建了__iter__()和next()方法,生成器显得特别简洁,而且生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存。除了创建和保持程序状态的自动生成,当发生器终结时,还会自动跑出StopIterration异常。
八、简单谈下GIL:
Global Interpreter Lock(全局解释器锁)
Python代码的执行由python虚拟机(也叫解释器主循环,CPython版本)来控制,Python在设计之初就考虑到要在解释器的主循环中,同时只有一个线程在执行,即任意时刻,只有一个线程在解释器中运行。对Python虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。
在多线程环境中,Python虚拟机按以下方式执行:
1.设置GIL
2.切换到一个线程去运行
3.运行:
a.指定数量的字节码指令,或者
b.线程主动让出控制(可以调用time.sleep(0))
4.把线程设置为睡眠状态
5.解锁GIL
6.再次重复以上所有步骤
再调用外部代码(如C/C++扩展函数)的时候,GIL讲会被锁定,直到这个函数结束为止(由于在这期间没有Python的字节码被运行,所以不会做线程切换)。
九、描述数组、链表、队列、堆栈的区别?
数组和链表是数据存储方式的概念,数组在连续的空间中存储数据,而链表可以在非连续的空间中存储数据;
队列和堆栈是描述数据存取方式的概念,队列是先进先出,而堆栈是后进先出;队列和堆栈可以用数组来实现,也可以用链表实现。
十、Python常见的标准库和第三方库:
=====第三方库======:
- Scrapy 快速/高级的web爬虫框架
- Numpy 科学计算和数学工作基础包,包括统计学、线性代数、矩阵数学、金融操作等等。
- Pillow 图像“无痛”处理库,易用版的 PIL。
- Pygame 一个高可移植性的游戏开发模块。
- Gooey 一条命令,将命令行程序变成一个 GUI 程序。
- Apache Libcloud 一个为各种云设计的 Python 库,通过单一、一致和统一的 API 访问各个云提供商。
- PyFilesystem 一个为所有文件系统提供的通用 Pythonic 接口。
- Cypthon Python 的 C 语言扩展工具,使用类型混合使 Python 编译成 C 模块来获得性能的提升。
- Behold 一款强大的支持 print-style 的调试工具。
- 等等--《https://blog.csdn.net/qq_18941425/article/details/79732712》
=====标准库======:
- re: 正则匹配threading和multiprocessing 多线程
- os/sys 系统,环境相关
- cvs
- Queue 队列
- math: 数学运算
- datetime:处理日期时间
- logging 日志
- pdb 调试
- traceback 调试
- pprint 漂亮的输出threading和multiprocessing 多线程url/urllib2/httplibhttp库,httplib底层一点,推荐第三方的库requests
- pickle/cPickle 序列化工具
- hashlib md5, sha等hash算法
- json/simplejson python的json库,据so上的讨论和benchmark,simplejson的性能要高于json
- timeit 计算代码运行的时间等等
- datetime:处理日期时间
- cProfile python性能测量模块
- glob 类似与listfile,可以用来查找文件
- atexit 有一个注册函数,可用于正好在脚本退出运行前执行一些代码
- dis python 反汇编,当对某条语句不理解原理时,可以用dis.dis 函数来查看代码对应的python 解释器指令等等。
Practice makes perfect.
==========================================================
书山有路,学海无涯,慢慢补吧,加油!