Python常见面试题一

目录

1、大数据的文件读取

2、迭代器和生成器的区别

3、装饰器的作用和功能

4、简单谈下 Global Interpreter Lock(GIL,全局解释器锁)

5、find 和 grep

6、线上服务可能因为种种原因导致挂掉怎么办?

7、如何提高python的运行效率

8、常用 Linux 命令

9、Python 中的 yield 用法

10、Python是如何进行内存管理的

11、描述数组、链表、队列、堆栈的区别?

12、常见的几种排序,讲一讲你最熟悉的一种?


1、大数据的文件读取

1)利用生成器generator

2)迭代器进行迭代遍历:for line in file

2、迭代器和生成器的区别

1)迭代器是一个更抽象的概念,任何对象,如果它的类有 next 方法和 iter 方法返回自己本身。对于 string、list、dict、tuple 等这类容器对象,使用 for 循环遍历是很方便的。在后台 for 语句对容器对象调用 iter() 函数,iter() 是 python 的内置函数。iter() 会返回一个定义了 next() 方法的迭代器对象,它在容器中逐个访问容器内元素,next() 也是 python 的内置函数。在没有后续元素时,next() 会抛出一个 StopIteration 异常

2)生成器(Generator)是创建迭代器的简单而强大的工具。它们写起来就像是正规的函数,只是在需要返回数据的时候使用yield 语句。每次 next() 被调用时,生成器会返回它脱离的位置(它记忆语句最后一次执行的位置和所有的数据值)

区别:生成器能做到迭代器能做的所有事,而且因为自动创建了__iter__()和next()方法,生成器显得特别简洁,而且生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存。除了创建和保存程序状态的自动方法,当发生器终结时,还会自动抛出StopIteration异常

3、装饰器的作用和功能

  • 引入日志
  • 函数执行时间统计
  • 执行函数前预备处理
  • 执行函数后的清理功能
  • 权限校验等场景
  • 缓存

4、简单谈下 Global Interpreter Lock(GIL,全局解释器锁)

Python代码的执行由Python 虚拟机(也叫解释器主循环,CPython版本)来控制,Python 在设计之初就考虑到要在解释器的主循环中,同时只有一个线程在执行,即在任意时刻,只有一个线程在解释器中运行。对Python 虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。

在多线程环境中,Python 虚拟机按以下方式执行:

1). 设置GIL
2). 切换到一个线程去运行
3). 运行:指定数量的字节码指令,或者 ,线程主动让出控制(可以调用time.sleep(0))
4). 把线程设置为睡眠状态
5). 解锁GIL
6). 再次重复以上所有步骤

在调用外部代码(如C/C++扩展函数)的时候,GIL 将会被锁定,直到这个函数结束为止(由于在这期间没有Python 的字节码被运行,所以不会做线程切换)。

5、find 和 grep

grep 命令是一种强大的文本搜索工具,grep 搜索内容串可以是正则表达式,允许对文本文件进行模式查找。如果找到匹配模式,grep 打印包含模式的所有行。

find 通常用来在特定的目录下搜索符合条件的文件,也可以用来搜索特定用户属主的文件。

6、线上服务可能因为种种原因导致挂掉怎么办?

linux下的后台进程管理利器 supervisor

每次文件修改后再linux执行 service supervisord restart

7、如何提高python的运行效率

使用生成器;关键代码使用外部功能包(Cython,pylnlne,pypy,pyrex);针对循环的优化---尽量避免在循环中访问变量的属性

8、常用 Linux 命令

ls,help,cd,more,clear,mkdir,pwd,rm,grep,find,mv,su,date

9、Python 中的 yield 用法

yield 是一个类似 return 的关键字,return 返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后开始。重点是:下一次迭代时,从上一次迭代遇到的 yield 后面的代码开始执行。

10、Python是如何进行内存管理的

1). 垃圾回收:python不像C++,Java等语言一样,他们可以不用事先声明变量类型而直接对变量进行赋值。对Python语言来讲,对象的类型和内存都是在运行时确定的。这也是为什么我们称Python语言为动态类型的原因(这里我们把动态类型可以简单的归结为对变量内存地址的分配是在运行时自动判断变量类型并对变量进行赋值)。

2). 引用计数:Python采用了类似Windows内核对象一样的方式来对内存进行管理。每一个对象,都维护这一个对指向该对对象的引用的计数。当变量被绑定在一个对象上的时候,该变量的引用计数就是1,(还有另外一些情况也会导致变量引用计数的增加),系统会自动维护这些标签,并定时扫描,当某标签的引用计数变为0的时候,该对就会被回收。

3). 内存池机制: 

    Python 的内存机制以金字塔行,-1,-2层主要有操作系统进行操作;

 第 0 层是 C 中的malloc,free等内存分配和释放函数进行操作;

 第 1 层和第 2 层是内存池,有 Python 的接口函数 PyMem_Malloc 函数实现,当对象小于 256K 时由该层直接分配内存;

 第 3 层是最上层,也就是我们对 Python 对象的直接操作;

在 C 中如果频繁的调用 malloc 与 free 时,是会产生性能问题的.再加上频繁的分配与释放小块的内存会产生内存碎片. Python 在这里主要做的工作有:

如果请求分配的内存大小在 1~256 字节之间就使用自己的内存管理系统,否则直接使用 malloc.

这里还是会调用 malloc 分配内存,但每次会分配一块大小为256k的大块内存.

经由内存池登记的内存到最后还是会回收到内存池,并不会调用 C 的 free 释放掉.以便下次使用.对于简单的Python对象,例如数值、字符串,元组(tuple不允许被更改)采用的是复制的方式(深拷贝?),也就是说当将另一个变量B赋值给变量A时,虽然A和B的内存空间仍然相同,但当A的值发生变化时,会重新给A分配空间,A和B的地址变得不再相同

11、描述数组、链表、队列、堆栈的区别?

数组与链表是数据存储方式的概念,数组在连续的空间中存储数据,而链表可以在非连续的空间中存储数据;

队列和堆栈是描述数据存取方式的概念,队列是先进先出,而堆栈是后进先出;队列和堆栈可以用数组来实现,也可以用链表实现。

12、常见的几种排序,讲一讲你最熟悉的一种?

参考文献

猜你喜欢

转载自blog.csdn.net/Sun_Hui_/article/details/81737622