Python面试笔记二

一、算法

1、归并排序

2、快速排序

3、算法复杂度

4、哈希表数据结构

二、数据库

1、设计一个用户关注系统的数据库表

1、设计一个用户关注系统的数据库表,写三个相关的SQL语句
两张表,一张user表,一张relation表

# 建立user表

create table user(name varchar(30) not null)

# 建立relation表:uid--用户ID,rid--用户关注的人ID

create table relation(uid int not null,rid int not null)

# 1.查询用户a关注的人

select name from user where id in (select rid from relation where uid = a)

# 2.查询关注用户a的人

select name from user where id in (select uid from relation where rid = a)

# 3.查询和a相互关注的人

select name from user where id in (select uid from relation where rid = a and uid in (select rid from relation where uid = a))

3、创建索引

# 普通索引
INDEX index_emp_name (name)
或者
KEY index_dept_name (dept_name)

# 唯一索引
UNIQUE INDEX index_emp_name (name)

# 全文索引
FULLTEXT INDEX index_resume (resume)

#多列索引(联合索引)
INDEX index_name_resume (name, resume)

#CREATE在已存在的表上创建索引
CREATE  [UNIQUE | FULLTEXT | SPATIAL ]  INDEX  索引名 ON 表名 (字段名[(长度)]  [ASC |DESC]) ;
    
#ALTER TABLE在已存在的表上创建索引
 ALTER TABLE 表名 ADD  [UNIQUE | FULLTEXT | SPATIAL ] INDEX索引名 (字段名[(长度)]  [ASC |DESC]) ;

# 删除索引
DROP INDEX index_emp_name on emp1

4、MySQL引擎

  MySQL数 据库引擎取决于MySQL在安装的时候是如何被编译的。要添加一个新的引擎,就必须重新编译MYSQL。在缺省情况下,MYSQL支持三个引擎:ISAM、MYISAM和HEAP。另外两种类型INNODB和BERKLEY(BDB),也常常可以使用。

  ISAM:ISAM是一个定义明确且历经时间考验的数据表格管理方法,它在设计之时就考虑到 数据库被查询的次数要远大于更新的次数。因此,ISAM执行读取操作的速度很快,而且不占用大量的内存和存储资源。ISAM的两个主要不足之处在于,它不 支持事务处理,也不能够容错:如果你的硬盘崩溃了,那么数据文件就无法恢复了。如果你正在把ISAM用在关键任务应用程序里,那就必须经常备份你所有的实 时数据,通过其复制特性,MYSQL能够支持这样的备份应用程序。

    MyISAM:MyISAM是MySQL的ISAM扩展格式和缺省的数据库引擎。除了提供ISAM里所没有的索引和字段管理的大量功能,MyISAM还使用一种表格锁定的机制,来优化多个并发的读写操作,其代价是你需要经常运行OPTIMIZE TABLE命令,来恢复被更新机制所浪费的空间。MyISAM还有一些有用的扩展,例如用来修复数据库文件的MyISAMCHK工具和用来恢复浪费空间的 MyISAMPACK工具。MYISAM强调了快速读取操作,这可能就是为什么MySQL受到了WEB开发如此青睐的主要原因:在WEB开发中你所进行的大量数据操作都是读取操作。所以,大多数虚拟主机提供商和INTERNET平台提供商只允许使用MYISAM格式。MyISAM格式的一个重要缺陷就是不能在表损坏后恢复数据。

    HEAP:HEAP允许只驻留在内存里的临时表格。驻留在内存里让HEAP要比ISAM和MYISAM都快,但是它所管理的数据是不稳定的,而且如果在关机之前没有进行保存,那么所有的数据都会丢失。在数据行被删除的时候,HEAP也不会浪费大量的空间。HEAP表格在你需要使用SELECT表达式来选择和操控数据的时候非常有用。要记住,在用完表格之后就删除表格。

    InnoDB:InnoDB数据库引擎都是造就MySQL灵活性的技术的直接产品,这项技术就是MYSQL++ API。在使用MYSQL的时候,你所面对的每一个挑战几乎都源于ISAM和MyISAM数据库引擎不支持事务处理(transaction process)也不支持外来键。尽管要比ISAM和 MyISAM引擎慢很多,但是InnoDB包括了对事务处理和外来键的支持,这两点都是前两个引擎所没有的。如前所述,如果你的设计需要这些特性中的一者 或者两者,那你就要被迫使用后两个引擎中的一个了。 

    MySQL 官方对InnoDB是这样解释的:InnoDB给MySQL提供了具有提交、回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎。InnoDB锁定在行级并且也在SELECT语句提供一个Oracle风格一致的非锁定读,这些特色增加了多用户部署和性能。没有在InnoDB中扩大锁定的需要,因为在InnoDB中行级锁定适合非常小的空间。InnoDB也支持FOREIGN KEY强制。在SQL查询中,你可以自由地将InnoDB类型的表与其它MySQL的表的类型混合起来,甚至在同一个查询中也可以混合。

    InnoDB是为处理巨大数据量时的最大性能设计,它的CPU效率可能是任何其它基于磁盘的关系数据库引擎所不能匹敌的。

    InnoDB存储引擎被完全与MySQL服务器整合,InnoDB存储引擎为在主内存中缓存数据和索引而维持它自己的缓冲池。InnoDB存储它的表&索引在一个表空间中,表空间可以包含数个文件(或原始磁盘分区)。这与MyISAM表不同,比如在MyISAM表中每个表被存在分离的文件中。InnoDB 表可以是任何尺寸,即使在文件尺寸被限制为2GB的操作系统上。

    InnoDB默认地被包含在MySQL二进制分发中。

    InnoDB被用来在众多需要高性能的大型数据库站点上产生。著名的Internet新闻站点Slashdot.org运行在InnoDB上。 Mytrix, Inc.在InnoDB上存储超过1TB的数据,还有一些其它站点在InnoDB上处理平均每秒800次插入/更新的 

    MyISAM适合:(1)做很多count 的计算;(2)插入不频繁,查询非常频繁;(3)没有事务。

    InnoDB适合:(1)可靠性要求比较高,或者要求事务;(2)表更新和查询都相当的频繁,并且表锁定的机会比较大的情况。

    一般情况下,MySQL会默认提供多种存储引擎,可以通过下面的查看:

    (1)看你的MySQL现在已提供什么存储引擎: mysql> show engines;

    (2)看你的MySQL当前默认的存储引擎: mysql> show variables like '%storage_engine%';

    (3)你要看某个表用了什么引擎(在显示结果里参数engine后面的就表示该表当前用的存储引擎): mysql> show create table 表名;

5、MySQL优化

对mysql优化是一个综合性的技术,主要包括

  • 表的设计合理化(符合3NF)
  • 添加适当索引(index) [四种: 普通索引、主键索引、唯一索引unique、全文索引]
  • 分表技术(水平分割、垂直分割)
  • 读写[写: update/delete/add]分离
  • 存储过程 [模块化编程,可以提高速度]
  • 对mysql配置优化 [配置最大并发数my.ini, 调整缓存大小 ]
  • mysql服务器硬件升级
  • 定时的去清除不需要的数据,定时进行碎片整理(MyISAM)

三、操作系统和网络编程

1、TCP/IP协议,TCP和UDP的区别

互联网协议(Internet Protocol Suite)是一个网络通信模型,以及一整个网络传输协议家族,为互联网的基础通信架构。它常被通称为TCP/IP协议族,简称TCP/IP。

TCP协议是面向连接,保证高可靠性(数据无丢失,数据无失序,数据无错误,数据无重复达到)
UDP:面向无连接的通讯协议,不可靠的传输,数据丢失,不管数据包的顺序、错误或重发(qq基于udp协议)

2、HTTP协议

HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型,是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用。 
HTTP连接最显著的特点是:

  1. 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。

  2. 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。

  3. 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

  4. 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

  5. 支持B/S及C/S模式。

HTTPS和HTTP的区别

  1. https协议需要到CA申请证书,一般免费证书很少,需要交费。

  2. http是超文本传输协议,信息是明文传输;https 则是具有安全性的ssl加密传输协 议。

  3. http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

三次握手

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据

四次挥手

  1. 客户端先发送FIN,进入FIN_WAIT1状态

  2. 服务端收到FIN,发送ACK,进入CLOSE_WAIT状态,客户端收到这个ACK,进入FIN_WAIT2状态

  3. 服务端发送FIN,进入LAST_ACK状态

  4. 客户端收到FIN,发送ACK,进入TIME_WAIT状态,服务端收到ACK,进入CLOSE状态

一次完整的HTTP请求过程

域名解析 --> 发起TCP的3次握手 --> 建立TCP连接后发起http请求 --> 服务器响应http请求,浏览器得到html代码 --> 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) --> 浏览器对页面进行渲染呈现给用户

3、应用层实现协议的细节,比如HTTPS,DNS

HTTPS协议 = HTTP协议 + SSL/TLS协议,在HTTPS数据传输的过程中,需要用SSL/TLS对数据进行加密和解密,需要用HTTP对加密后的数据进行传输,由此可以看出HTTPS是由HTTP和SSL/TLS一起合作完成的。 
  SSL的全称是Secure Sockets Layer,即安全套接层协议,是为网络通信提供安全及数据完整性的一种安全协议。SSL协议在1994年被Netscape发明,后来各个浏览器均支持SSL,其最新的版本是3.0。 
  TLS的全称是Transport Layer Security,即安全传输层协议。在TLS与SSL3.0之间存在着显著的差别,主要是它们所支持的加密算法不同,所以TLS与SSL3.0不能互操作。虽然TLS与SSL3.0在加密算法上不同,但是在我们理解HTTPS的过程中,我们可以把SSL和TLS看做是同一个协议。

dns是一个域名系统,是万维网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。

通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。在解析域名时,可以首先采用静态域名解析的方法,如果静态域名解析不成功,再采用动态域名解析的方法,域名是互联网上的身份标识,是不可重复的唯一标识资源; 互联网的全球化使得域名成为标识一国主权的国家战略资源。

应用层常用协议

1 、DNS:域名系统DNS是因特网使用的命名系统,用来把便于人们使用的机器名字转换为IP地址。

现在顶级域名TLD分为三大类:国家顶级域名nTLD;通用顶级域名gTLD;基础结构域名

域名服务器分为四种类型:根域名服务器;顶级域名服务器;本地域名服务器;权限域名服务器。

2、FTP:文件传输协议FTP是因特网上使用得最广泛的文件传送协议。FTP提供交互式的访问,允许客户指明文件类型与格式,并允许文件具有存取权限。FTP其于TCP。

3、telnet远程终端协议:telnet是一个简单的远程终端协议,它也是因特网的正式标准。又称为终端仿真协议。

4、HTTP:超文本传送协议,是面向事务的应用层协议,它是万维网上能够可靠地交换文件的重要基础。http使用面向连接的TCP作为运输层协议,保证了数据的可靠传输。
5、电子邮件协议SMTP:即简单邮件传送协议。SMTP规定了在两个相互通信的SMTP进程之间应如何交换信息。SMTP通信的三个阶段:建立连接、邮件传送、连接释放。
6 、POP3:邮件读取协议,POP3(Post Office Protocol 3)协议通常被用来接收电子邮件。

4、多线程、多进程、协程

1、并发:系统具有处理多个任务的能力;

2、并行:系统具有同时处理多个任务的能力;并行是并发的子集;

3、同步:当进程执行到一个IO(等待外部数据)的时候,必须等待;比如打电话,一直等到对方接听;

4、异步:当进程执行到一个IO(等待外部数据)的时候,不等待,直到数据接收成功,再回来处理;比如发短信,不需要等到对方回复,可以先去做别的,收到后再来回复短信;

5、IO多路复用:监听多个socket对象(while循环),谁有变化就处理谁,利用这个特性,可以开发出很多操作,比如异步IO模块;

6、异步IO:当进程执行到一个IO(等待外部数据)的时候,不等待,直到数据接收成功,再回来处理,其实就是回调;

7、利用非阻塞的socket+IO多路复用,可以实现伪并发;

8、协程:

  • 线程和进程的操作是由程序触发系统接口,最后的执行者是系统;协程的操作则是程序员;

  • 协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。协程,则只使用一个线程,在一个线程中规定某个代码块执行顺序。

  • 协程的适用场景:当程序中存在大量不需要CPU的操作时(IO),适用于协程,即高并发的io操作,协程比多线程节省时间;

9、线程

  • 一个应用程序可以有多进程、多线程;默认是单进程、单线程;

  • 每一个进程有一个全局解释器锁(GIL),每一次CPU调用只能调用一条线程;

  • 如果是IO操作,不占用CPU,单进程,多线程可以提高并发;

  • 如果是计算型操作,占用CPU,多进程提高并发;

10、线程锁:由于线程之间是进行随机调度,当多个线程同时修改同一条数据时可能会出现脏数据,所以出现了线程锁同一时刻只允许一个线程执行操作

11、进程

  • 进程本质上就是一个程序运行的过程;进程一般由程序、数据集、进程控制块三部分组成;

  • 一个程序至少有一个进程,一个进程至少有一个线程;

  • 进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。

  • 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈)但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源. 一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行。

6、长链接换短连接的技术实现

  用一个递增的数字去维护数据库,只需要把数字转换成字母的编码格式,就能得到相应的key,然后再把value存成长链接,就实现了短链接和长链接的对应关系。

通过发号策略,给每一个过来的长地址,发一个号即可,小型系统直接用mysql的自增索引就搞定了。如果是大型应用,可以考虑各种分布式key-value系统做发号器。不停的自增就行了。第一个使用这个服务的人得到的短地址是 http://xx.xx/0 第二个是 http://xx.xx/1 第11个是 http://xx.xx/a 第依次往后,相当于实现了一个62进制的自增字段即可。

6.1、62进制如何用数据库或者KV存储来做?

其实我们并不需要在存储中用62进制,用10进制就好了。比如第10000个长地址,我们给它的短地址对应的编号是9999,我们通过存储自增拿到9999后,再做一个10进制到62进制的转换,转成62进制数即可。这个10~62进制转换,你完全都可以自己实现。

6.2、如何保证同一个长地址,每次转出来都是一样的短地址

用key-value存储,保存“最近”生成的长对短的一个对应关系。注意是“最近”,也就是说,我并不保存全量的长对短的关系,而只保存最近的。比如采用一小时过期的机制来实现LRU淘汰。

这样的话,长转短的流程变成这样:

  • 在这个“最近”表中查看一下,看长地址有没有对应的短地址
    • 有就直接返回,并且将这个key-value对的过期时间再延长成一小时
    • 如果没有,就通过发号器生成一个短地址,并且将这个“最近”表中,过期时间为1小时

所以当一个地址被频繁使用,那么它会一直在这个key-value表中,总能返回当初生成那个短地址,不会出现重复的问题。如果它使用并不频繁,那么长对短的key会过期,LRU机制自动就会淘汰掉它。

当然,这不能保证100%的同一个长地址一定能转出同一个短地址,比如你拿一个生僻的url,每间隔1小时来转一次,你会得到不同的短地址。但是这真的有关系吗?

6.3、如何保证发号器的大并发高可用

上面设计看起来有一个单点,那就是发号器。如果做成分布式的,那么多节点要保持同步加1,多点同时写入,这个嘛,以CAP理论看,是不可能真正做到的。其实这个问题的解决非常简单,我们可以退一步考虑,我们是否可以实现两个发号器,一个发单号,一个发双号,这样就变单点为多点了?依次类推,我们可以实现1000个逻辑发号器,分别发尾号为0到999的号。每发一个号,每个发号器加1000,而不是加1。这些发号器独立工作,互不干扰即可。而且在实现上,也可以先是逻辑的,真的压力变大了,再拆分成独立的物理机器单元。1000个节点,估计对人类来说应该够用了。如果你真的还想更多,理论上也是可以的。

6.4、跳转用301还是302

301是永久重定向,302是临时重定向。短地址一经生成就不会变化,所以用301是符合http语义的,同时对服务器压力也会有一定减少。

但是如果使用了301,我们就无法统计到短地址被点击的次数了。而这个点击次数是一个非常有意思的大数据分析数据源。能够分析出的东西非常非常多。所以选择302虽然会增加服务器压力,但是我想是一个更好的选择。

7、Redis和Memcached

Memcache 是一个开源、高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。它可以应对任意多个连接,使用非阻塞的网络IO。由于它的工作机制是在内存中开辟一块空间,然后建立一个存储键/值对的HashTable,Memcache这个软件项目一般叫Memcache,但项目的主程序文件叫memcached.exe(字母d可以理解为daemon),是靠服务端的这个守护进程管理这些HashTable。由于这个命名问题,所以很多人把这个软件系统叫memcache,想叫成memcached也没什么问题!其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

使用Redis有哪些好处?

(1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)

(2) 支持丰富数据类型,支持string,list,set,sorted set,hash,memcached所有的值均是简单的字符串

(3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行

(4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

Memcache与Redis的区别都有哪些?

1)、存储方式 Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。 Redis有部份存在硬盘上,这样能保证数据的持久性。

2)、数据支持类型 Memcache对数据类型支持相对简单。 Redis有复杂的数据类型。

3)value大小 redis最大可以达到1GB,而memcache只有1MB

 redis常见性能问题和解决方案:

(1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件

(2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次

(3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内

(4) 尽量避免在压力很大的主库上增加从库

(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3... 这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。

 redis 最适合的场景

(1)、会话缓存(Session Cache)

(2)、全页缓存(FPC)

(3)、队列

(4),排行榜/计数器

(5)、发布/订阅

四、web开发

1、web开发优化上的细节,比如如何处理长时间响应

分表分库,小图片规整,css/js合并压缩,Redis缓存热点数据,使用浏览器的缓存功能

处理长时间响应:

  • 首先,可以调整webserver配置,修改页面响应时间的参数,延长timeout时间

  • 第二,采用异步方式加载,就是ajax,请求时传递参数到后台,页面显示等待信息,等后台处理完成返回结果再展示

  • 第三,优化你的程序或sql,找出慢的原因,数据量大只是一个方面,很多大型数据库用的时候也不会慢到哪里去

web开发优化:

1、Sql 依赖缓存

对于所有用户读到相同结果的数据,改为从内存中读取,减少数据库访问的次数,降低数据库CPU的压力,但会提高Web服务器的一些压力,和增加少量的内存占用量。

2、页面缓存、控件缓存的技巧

对于所有用户得到相同页面结果的页面来说,可以采用页面缓存的方式,比如我们在首页上展示公告信息的结果,这些结果对于所有用户来说是一样的,可以采用页面缓存的方式,同时通过设置页面缓存的失效机制保证所有用户得到最新的结果,比如后台代码增加新的公告内容时可以设置一个Application的值,告诉页面缓存失效。

 3、智能的静态页面处理技巧

          一些已经处理完成的页面展示的时候,系统已经不再有交互的动作,对于用户来说,仅仅只是查看结果的情况下,可以智能的生成静态页面文件,只有一个用户是通过.NET计算去获得展示,其它用户访问的则是生成的静态页面,这样也可以减少非常大数据量的.NET计算,提高性能。 比如E8.Net工作流平台中展示流程结束后的结果就有客户使用到了这些技巧,大大减少了服务器的压力。

2、函数new和init的区别

class Person(object):
"""Silly Person"""

def __new__(cls, name, age):
    print '__new__ called.'
    return super(Person, cls).__new__(cls, name, age)

def __init__(self, name, age):
    print '__init__ called.'
    self.name = name
    self.age = age

def __str__(self):
    return '<Person: %s(%s)>' % (self.name, self.age)

if name == 'main':
piglei = Person('piglei', 24)
print piglei
执行结果:
piglei@macbook-pro:blog$ python new_and_init.py
new called.
init called.
<Person: piglei(24)>

通过运行这段代码,我们可以看到,new方法的调用是发生在init之前的。其实当 你实例化一个类的时候,具体的执行逻辑是这样的:

  • 1.p = Person(name, age)

  • 2.首先执行使用name和age参数来执行Person类的new方法,这个new方法会 返回Person类的一个实例(通常情况下是使用 super(Persion, cls).new(cls, ... ...) 这样的方式),

  • 3.然后利用这个实例来调用类的init方法,上一步里面new产生的实例也就是 init里面的的 self

所以,initnew 最主要的区别在于:

  • 1.init 通常用于初始化一个新实例,控制这个初始化的过程,比如添加一些属性, 做一些额外的操作,发生在类实例被创建完以后。它是实例级别的方法。

  • 2.new 通常用于控制生成一个新实例的过程。它是类级别的方法。

但是说了这么多,new最通常的用法是什么呢,我们什么时候需要new?依照Python官方文档的说法,new方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径。还有就是实现自定义的metaclass。

  • 1、继承自object的新式类才有__new__

  • 2、__new__至少要有一个参数cls,代表当前类,此参数在实例化时由Python解释器自动识别

  • 3、__new__必须要有返回值,返回实例化出来的对象,这点在自己实现__new__时要特别注意,可以return父类(通过super(当前类名, cls))__new__出来的实例,或者直接是object的__new__出来的实例

  • 4、__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值

  • 5、如果__new__创建的是当前类的实例,会自动调用__init__函数,通过return语句里面调用的__new__函数的第一个参数是cls来保证是当前类实例,如果是其他类的类名,;那么实际创建返回的就是其他类的实例,其实就不会调用当前类的__init__函数,也不会调用其他类的__init__函数。

3、Python的优缺点

优点:

  • 1.简洁易懂

  • 2.跨平台

  • 3.可扩展性

  • 可移植性

  • 既支持面向过程的函数编程也支持面向对象的抽象编程

  • 丰富的标准库和第三方库

缺点:

  • Python 的执行速度不够快,和C相差五倍,如果是大规模计算问题,大约能差10倍以上,python的效率问题也不是技术原因导致的,而且python也对这方面有所弥补,那就是对效率敏感的地方可以用C重写,以达到预期的效率需求,但是治标不治本,追求python的高开发效率的同时,就得舍弃一些性能上的追求。

  • 全局解释器锁GIL(Global Interpreter Lock),导致计算密集型任务效率低下;以至于我现在对高并发计算都采取多进程的模式。多进程模式的通讯效率肯定比多线程低,而且麻烦。

  • Python 2 与 Python 3 不兼容:如果一个普通的软件或者库,不能够做到后向兼容,那么,它会被用户无情的抛弃了。因为 Python 没有向后兼容,给所有的 Python 工程师带来了无数的烦恼。

解释性语言和编译型语言的区别:

  • 1.编译型语言在程序执行之前,有一个单独的编译过程,将程序翻译成机器语言,以后执行这个程序的时候,就不用再进行翻译了。

  • 2.解释型语言,是在运行的时候将程序翻译成机器语言,所以运行速度相对于编译型语言要慢。

  • 3.C/C++ 等都是编译型语言,而Java,C#等都是解释型语言。

原文地址:https://www.cnblogs.com/charliedaifu/p/10555668.html