概念
Python有什么优势
解释性语言,语法简单易懂,可读性强
自动内存管理,基于引用计数法等可以对垃圾进行自动回收;内存池机制,提前申请好小内存,内存分配效率更高。让程序员可以更加专注代码的实现。
有很多库可以调用,站在巨人的肩膀上简单的实现想要的功能
可扩展,和其他编程语言或者软件有可连接的接口
免费开源
Python和Java的对比
编译型语言:经过一次编译之后,由操作系统直接执行。如c++和c

解释型语言:读一行,解释执行一行

Java:现将程序编译成字节码文件,然后字节码文件在虚拟机上运行,虚拟机从字节码文件读一行解释执行一行。

所以Java是结合了编译型和解释型语言的特点。

语言特点:Python是强类型的动态语言,是解释性语言;Java是强类型的静态语言,结合了解释性语言和编译型语言的特点。所以Java的运行速度要快一些。
多线程模型:python的多线程不能实现多CPU条件下的并行运行,每个线程在运行时首先需要获得GIL,Python的多线程是通过协程或者多进程的机制来实现。但是Java的多线程编程很强大,支持真正的多线程并发操作。
垃圾回收:Python的垃圾回收机制以引用计数法为主,标记清除和分代回收为辅。
语法基础
is和==的区别
is表示两个对象是否指向同一块地址空间,若为true,表示指向同一地址空间,且值一定相等。(Java的==)

==表示值是否相等。(Java的equals)

“hello world” 有空格,为非标识符允许的字符,不驻留内存。

a = "hello world"
b = "hello world"
print(id(a)) # 输出 140506208811952
print(id(b)) # 输出 140506208812208
print(a is b) # 输出 False
print(a == b) # 输出 True

a = "hello"
b = "hello"
print(id(a)) # 输出 140506224367496
print(id(b)) # 输出 140506224367496
print(a is b) # 输出 True
print(a == b) # 输出 True
1
2
3
4
5
6
7
8
9
10
11
12
13
元组、列表和字典的区别
列表:可重复,类型可不同

元组:结构和列表类似,但是是不可变对象

字典:定义了键和值之间一对一的关系,但是是以无序的方式存储的。键值不可以重复。但是python3.7以后变成有序了。

深拷贝和浅拷贝
对于不可变对象(元组、字符串等),python采用的是引用计数法,不管是深拷贝还是浅拷贝,作用都是一致的,相当于复制了一份副本,当原对象内部的对象发生改变时,不会影响到幅值对象。

等号赋值:相当于给给原来对象贴一个新标签,当其中一个标签被改变的时候,另一个标签也会随之变化。

对于浅拷贝,分两种情况:

1)一种是不可变对象,和等号赋值一样。

2)一种是可变对象,这里又分两种情况:

​ 可变对象内部无复杂子元素:原来值的改变不会影响浅拷贝的值

​ 可变对象内部有复杂子元素:如果改变原来值中复杂子对象的值,会影响浅拷贝的值。

对于深拷贝,对一个对象所有层次的拷贝,作为一个新的个体单独存在,所以不管原本对象怎么改变,都不会改变拷贝副本的值。相当于备份。

浅拷贝占用空间小,拷贝层次低,拷贝速度快,因此效率高。一般默认就是浅拷贝。

位置参数和关键字参数的区别(*args,**kw)
函数参数可为分如下几种:必选参数、默认参数、可变参数、命名关键字参数和关键字参数

*args:可变参数,args接收的是一个tuple

**kw:关键字参数,kw接收的是一个kw。比如我们要实现用户注册,有必输项和非必输项,这些非必输项就可以用关键字参数来接受。

对于任意函数都可以通过类似func(*args,**kw)的形式来调用,无论他的参数是怎么定义的。

装饰器
装饰器本身是一个函数,可以让已有的函数再不改变的情况下增加功能。适合有切面需求的场景,比如权限校验,日志记录等。

和Java里面的动态代理实现方式有点类似。

生成器和迭代器
迭代器
是访问集合元素的一种方式,用iter()创建迭代器,调用next()函数获取对象。(迭代器只能往前不能往后)

生成器
是一种特殊的迭代器,生成一系列的值用于迭代。

使用了yield函数,返回迭代器。

区别
创建:生成器创建一个函数,用yield返回对象;迭代器用内置函数iter()和next();
线程
多线程的创建
使用threading的模块,启动一个线程就是把一个函数传入并创建thread实例,然后调用start( )开始执行。

GIL
python中线程通信的方式是通过GIL(全局解释锁)来实现的,任何python的线程执行前必须先获得GIL锁,然后每执行100个字节,解释器就释放GIL锁,让别的线程有机会执行。所以多线程在python中只能交替执行,Python的多线程只能利用一个核。

Python多线程模型
Python由于GIL锁的设计,导致多线程无法利用多核。

对于CPU密集型的任务,主要是消耗CPU资源,Python这样的脚本语言运行效率很低,完全不适合这种计算密集型的任务。

Python适合IO密集型的任务,开发效率最高(代码最少)

内存管理与垃圾回收
内存管理
python有内存池机制,小内存使用内存池进行分配,大内存使用malloc进行分配。当创建大量消耗小内存的对象时,频繁调用new/malloc会导致大量的内存碎片,同时效率较低。内存池就是先申请一定数量的内存块作为备用,当有内存需求时,就从内存池中分配内存给这个需求。

垃圾回收
以引用计数为主,标记清除和分代回收为辅。

引用计数
每个对象都会有一个引用计数,当一个对象有新的引用时就计数加一,当引用它的对象被删除,计数就减一。一旦一个对象的引用计数为0,该对象就被回收,对象占用的内存空间被释放。

优点:简单,一旦没有被引用,内存就直接释放了。

缺点:需要额外的空间维护引用计数;同时不能解决对象的循环引用。

标记清除www.snfwrx.com
解决循环引用的问题。先根据可达性分析把活动对象标记,再把没有标记的对象进行回收。

分代回收
把内存分成三代,年轻代、中年代、老年代。新建的对象呗分配到年轻代,年轻代回收之后,没有被回收的对象被挪到老年代。