带*号的与python无关 只是一些面试中常见的问题
del
语句对对象别名显示的销毁
sys.getrefcount()函数,可以获得对象的当前引用计数。对于不可变数据(如数字和字符串)解释器会在程序的不同部分共享内存,以便节约内存
del
语句可以减少a和b的引用计数,并销毁用于引用底层对象的名称。然而由于每个对象都包含一个对其他对象的应用,因此引用计数不会归零,对象也不会销毁(从而导致内存泄漏),为解决这一问题,解释器会定期运行一个循环检测器,搜索不可访问对象的循环并删除它们Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统
Pymalloc
机制,为了加速Python
的执行效率,Python
引入了一个内存池机制,用于管理对小块内存的申请和释放Python
中所有小于256个字节的对象都使用Pymalloc
实现的分配器,而大的对象则使用系统的malloc
Python
对象,如整数,浮点数和List
,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配了又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数访问集合元素的一种方式
字符串,列表或元组对象都可用于创建迭代器[int
类型不可以],迭代器可以记住遍历的对象的上一个位置;从集合的第一个元素开始访问,直到所有的元素被访问结束,即只能往前不会后退
手动创建:
list
实现
items = [0, 1, 2, 3, 4]
it = list(iter(items))
print(it)
自定义迭代器:内建函数
iter()
可以从迭代对象中获得迭代器
通过yield
语句快速生成迭代器
模块:一个 .py
文件 包:一个文件夹包括一个__init__.py
文件
运行模块里的全部代码
从模块里单独引入一个变量/类,而不执行模块内其他语句
相当于引入包内的__init__
模块
引入包内的模块
基于AOP思想,面向切面编程:编译时,类和方法加载时,动态地将代码引入到类的指定法指定方法:指定位置的编程思想
装饰器是一个著名的设计模式,经典的有插入日志
/性能测试
/事务处理
在代码运行期间动态增加功能的方式
确保某个类只有一个实例存在
from functools import wraps
def Singleton(cls):
_instance = {}
@wraps(cls) # 保留原有函数的名称和docstring
def _singleton(*args, **kwargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kwargs)
return _instance[cls]
return _singleton
@Singleton
class Settings():
"""Docstring"""
def __init__(self):
self.a = 'xxx'
self.b = 'xxx'
settings = Settings()
print(settings.a)
print(Settings.__name__)
print(Settings.__doc__)
@wraps的作用
Python
装饰器在实现的时候,被装饰后的函数其实已经时另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python
的functools
包中提供了一个叫wraps
的decorator
来消除这样的副作用。写一个decprator
的时候,最好在实现之前加上functools
的wrap
,它保留原有函数的名称和docstring
__mor__方法可以查看继承顺序
(1) 函数使用上:epoll 使用一组函数来完成任务,而不是单个函数
(2) 效率:select 使用轮询来处理,随着监听 fd 数目的增加而降低效率。而 epoll 把用户关心的文件描述符事件放在内核里的一个事件表中,只需要一个额外的文件描述符来标识内核中的这个事件表即可。
uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。
要注意 WSGI / uwsgi / uWSGI 这三个概念的区分。
uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型描述,它与WSGI相比是两样东西。
为什么有了uWSGI为什么还需要nginx?因为nginx具备优秀的静态内容处理能力,然后将动态内容转发给uWSGI服务器,这样可以达到很好的客户端响应。
eval是Python的一个内置函数,这个函数的作用是,返回传入字符串的表达式的结果。即变量赋值时,等号右边的表示是写成字符串的格式,返回值就是这个表达式的结果。可实现list、dict、tuple与str之间的转化
快慢指针,例子:运动员赛跑 快的肯定会再次追上慢的
在C语言写的python解释器中存在全局解释器锁,由于全局解释器锁的存在,在同一时间内,python解释器只能运行一个线程的代码,这大大影响了python多线程的性能。而这个解释器锁由于历史原因,现在几乎无法消除。
python GIL 之所以会影响多线程等性能,是因为在多线程的情况下,只有当线程获得了一个全局锁的时候,那么该线程的代码才能运行,而全局锁只有一个,所以使用python多线程,在同一时刻也只有一个线程在运行,因此在即使在多核的情况下也只能发挥出单核的性能。
既然python在同一时刻下只能运行一个线程的代码,那线程之间是如何调度的呢?
对于有io操作的线程,当一个线程在做io操作的时候,因为io操作不需要cpu,所以,这个时候,python会释放python全局锁,这样其他需要运行的线程就会使用该锁。
对于cpu密集型的线程,比如一个线程可能一直需要使用cpu做计算,那么python中会有一个执行指令的计数器,当一个线程执行了一定数量的指令时,该线程就会停止执行并让出当前的锁,这样其他的线程就可以执行代码了。
由上面可知,至少有两种情况python会做线程切换,一是一但有IO操作时,会有线程切换,二是当一个线程连续执行了一定数量的指令时,会出现线程切换。当然此处的线程切换不一定就一定会切换到其他线程执行,因为如果当前线程 优先级比较高的话,可能在让出锁以后,又继续获得锁,并优先执行。
在做科学计算的时候是用的单线程,因为这种计算是需要CPU一直做计算的,如果用多线程反而会降低计算速度。
增强了图片渲染、数据存储、影音和多任务处理等功能
新加的属性是:
1.canvas动画
2.本地存储localstorage
3.时间监听 addeventlistener(window的对象)
4.sessionstorage数据在浏览器关闭后自动删除
5.媒体video和audio
需要第三方插件就能播放音频和视频了,可以直接插入,并且用同一的API接口控制。
6.语义化的标签
语义化的标签对搜索引擎优化有好处,更易被搜索到。其他的同事维护代码也很方便一点
7.表单的控制
email、time、search
8.Geolocation 地理定位
什么是page cache的机制
当APP需要读取磁盘文件数据时,linux先分配一些内存,将数据从磁盘读区到内存中,然后再将数据传给APP。
当APP需要写数据到磁盘文件时,linux先分配内存接受用户数据,然后再将数据从内存写到磁盘。
page cache的结构
linux的文件cache分为两层,一个是page cache,另一个是buffer cache;每一个page cache包含若干个buffer cache。真正指向磁盘block的其实是buffer cache里面的指针。
cache是如何提高性能的呢?
靠的是cache的预读
对于每个文件的第一次读请求,系统读入所请求的页面并读入紧随其后的的少数几个页面(不少于1个,通常是3个),此种读区成为同步预读;
第二次读取,如果页面不在cache中,说明不是顺序读取,继续重复第一次的同步预读过程。
第二次读取,如果页面在cache中,说明是顺序读取,会将预读group扩大一倍,将不在cache中的文件数据读进来。此为异步预读。
Shift+F5
int<中断向量号>
发出中断请求,设中断向量号为i,i∈{3,4,5,128}。从用户空间到内核空间并找到函数执行体
软中断:当用户空间使用系统调用的时候就会出发软中断。当要准备从用户态到内核态执行,就会有一个指令——SWI(software interrupt)被执行。进入内核态
判断不同的系统调用:当从用户空间进入到内核态,系统并不知道要执行哪个系统调用,为了解决这个问题,先将每个系统调用函数进行编号,再调用相应的函数的时候,将相应的编号进行放入寄存器r7.根据编码并查看相应的表。就得到相应的函数
#include
int main()
{
int a = 3, b = 5;
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("a = %d, b = %d\n", a, b);
return 0
}
1.局部变量
在一个函数内部定义的变量是内部变量,它只在本函数范围内有效,也就是说只有在本函数内才能使用它们,在此函数以外时不能使用这些变量的,它们称为局部变量。
局部变量保存在动态数据区的栈中,只有在所在函数被调用时才动态地为变量分配存储单元。
1).主函数main中定义的变量也只在主函数中有效.
2).不同函数中可以使用名字相同的变量,它们代表不同的对象,互不干扰.
3).形参也是局部变量.
4).在复合语句中定义的局部变量,这些变量只在本复合语句中有效.
2.全局变量
在函数外定义的变量是外部变量,外部变量是全局变量,全局变量可以为本文件中其它函数所共用,它的有效范围从定义变量的位置开始到本源文件结束。
全局变量位于静态数据区中。
1).设全局变量的作用:增加了函数间数据联系的渠道.
2).建议不再必要的时候不要使用全局变量,因为
a.全局变量在程序的全部执行过程中都占用存储单元.
b.它使函数的通用性降低了
3).如果外部变量在文件开头定义,则在整个文件范围内都可以使用该外部变量,如果不再文件开头定义,按上面规定作用范围只限于定义点到文件终了.如果在定义点之前的函数想引用该外部变量,则应该在该函数中用关键字extern作外部变量说明.
4).如果在同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量不起作用.
3.静态变量
静态变量并不是说其就不能改变值,不能改变值的量叫常量。 其拥有的值是可变的 ,而且它会保持最新的值。说其静态,是因为它不会随着函数的调用和退出而发生变化。即static局部变量只被初始化一次,下一次依据上一次结果值;
静态变量的作用范围要看静态变量的位置,如果在函数里,则作用范围就是这个函数。
静态变量属于静态存储方式,其存储空间为内存中的静态数据区(在静态存储区内分配存储单元),该区域中的数据在整个程序的运行期间一直占用这些存储空间(在程序整个运行期间都不释放),也可以认为是其内存地址不变,直到整个程序运行结束(相反,而auto自动变量,即动态局部变量,属于动态存储类别,占动态存储空间,函数调用结束后即释放)。静态变量虽在程序的整个执 行过程中始终存在,但是在它作用域之外不能使用。
另外,属于静态存储方式的量不一定就是静态变量。 例如:外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。
抽象 封装 继承 多态
对于
or
操作符
只要两边表达式为真,整个表达式的结果是左边表达式的值
1 or 3
#1
如果是一真一假,返回真值表达式的值
a= ''
a or -1
#-1
如果两个都是假,比如空值和0,返回的是右边的值
a = ''
a or 0
#0
def fib(n):
a = b = 1
for i in range(n):
yield a
a, b = b, a + b
for x in fib(num): #num为所求的数
print(x)
def fib(n):
a, b = 1, 1
for i in range(n-1):
a, b = b, a+b
return a
print(fib(num)) # num为所求的数
def fib(n):
if m == 1 or m == 2:
return 1
return fib(m -1) + fib(m - 2)
print(fib(num)) # num为所求的数
a = [1,2,3]
b = [4,5,6]
a.append(b)
# [1, 2, 3, [4, 5, 6]]
>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> a.extend(b)
>>> print(a)
# [1, 2, 3, 4, 5, 6]