python面试题库_v2.0

1.如何遍历一个内部未知的文件夹?

常用的有以下这几种方法:
os.path.walk(),os.walk,listdir
以os.walk()为例:
os.walk(top, topdown=True, onerror=None, followlinks=False)
参数:
top 是你所要遍历的目录地址
topdown 为真,则优先遍历top目录,否则优先遍历top的子目录(默认开启)
onerror 需要一个callable对象,当walk需要异常时,会调用
followlinks如果为真,则会遍历目录下的快捷方式(linux下是symbolic link)实际所指的目录(默认关闭)
os.walk()的返回值是一个生成器,也就是说我需要不断的遍历它,来获得所有的内容。
每次遍历的对象都返回的是一个三元组(root,dirs,file)
root 所指的是的那个钱正在遍历的这个文件夹的本身所在的地址
dirs 是一个list,内容是该文件夹中所有的目录的名字(不包括子目录)
files 同样是lsit,内容是该文件夹中所有的文件(不包括子目录)

2.mysql数据库如何分区、分表?

分表可以通过三种方式:mysql集群、自定义规则和merge存储引擎。
分区有四类:
RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区。
LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。
HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。
KEY 分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL 服务器提供其自身的哈希函数。必须有一列或多列包含整数值。

3.如何对查询命令进行优化?

(1).应尽量避免全表扫描,首先应该考虑在where及order by涉及的列上建立索。
(2).应尽量避免在where子句中对字段进行null值判断,避免使用!=或操作符,避免使用or连接条件,或在where子句中使用参数、对字段进行表达式或函数操作,否则会导致权标扫描
(3).不要在where子句中的“=”左边进行函数、算数运算或其他表达式运算,否则系统将可能使用无法正确使用索引。
(4).使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用。
(5).很多时候可以考虑使用exists代替in
(6).尽量使用数字型字段
(7).尽可能的使用varchar/nvarchar代替char/nchar
(8).任何地方都不要使用select * from t,用具体的字段列表代替"*",不要返回用不到的任何字段。
(9).尽量使用表变量来代替临时表。
(10).避免频繁创建和删除临时表,以减少系统表资源的消耗。
(11).尽量避免使用游标,因为游标的效率较差。
(12).在所有的存储过程和触发器的开始处设置SET NOCOUNT ON,在结束时设置SET NOCOUNT OFF
(13).尽量避免大事务操作,提高系统并发能力。
(14).尽量避免向客户端分拿回大数据量,若数据量过大,应该考虑相应需求是否合理。

4.如何理解开源?

开源,即开放源代码。开源诞生于软件行业,它不仅仅代表软件源代码的开放,本身即意味着自由、共享和充分利用资源。开源是一种精神,是一种文化,如今已经成为软件业发展的大势所趋。

5.如何理解MVC/MVT框架?

MVC:是一种传统的流程处理模式,是一种编程思想,主要由数据模型Model、控制器Controller以及视图View组成的一个完成流程处理模式,首先由和用户直接交互展示的视图View可以发起请求,由控制器Controller进行请求的分发,调用制定的数据处理函数对数据Model进行增删改查操作,完成一个功能的完整处理过程!
MVT处理模式,是在MVC处理模式上,升级得到的一种更加符合实际项目开发流程的处理思路;在这种处理模式中,将功能比较单一的控制器Controller部分,封装成了路由!
由路由来完成请求的分发操作[路由是通过配置实现的]
更多详情可以参考我的这篇文章:
https://www.jianshu.com/p/9d12aeb8e417

6.死锁是如何产生的,以及如何防止?

原因:竞争资源和程序推进顺序不当。
死锁产生的四个必要条件:
互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其他进程请求资源,则请求者只能等待,直到占有资源的进程用毕释放。
请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,......,Pn正在等待已被P0占用的资源。
处理死锁的基本方法:
(1).预防死锁(摒弃除1以外的条件)
(2).避免死锁(银行家算法)
(3).检测死锁(资源分配图)
(4).解除死锁(剥夺资源、撤销进程)

7. sql注入是如何产生的,如何防止?

程序开发过程中不注意规范书写sql语句和对特殊字符进行过滤,导致客户端可以通过全局变量POST和GET提交一些sql语句正常执行。产生sql注入。下面是防止办法:
(1).过滤掉一些常见的数据库操作关键字,或者通过系统函数来进行过滤。
(2).sql语句书写的时候尽量不要省略小引号(tab键上面那个)和单引号
(3).提高数据库命名机巧,对于一些重要的字段根据程序的特点命名,取不易被猜到的名字。
(4).对于常用的方法加以封装,避免直接暴漏sql语句
(5).控制错误信息:关闭错误提示信息,将错误信息写到系统日志。
(6).使用mysqli或者pdo预处理。

8.如何管理不同版本的代码?

进行版本管理。可以举例告知如何使用Git(或是其他工具(SVN等))进行追踪。
当然,版本管理工具有很多,挑自己了解的或是自己在公司使用的简单说一下即可。
为什么会提这个问题呢(版本管理有什么好处呢)?
因为没有版本控制的代码,就像没有杯子的咖啡。有时候我们需要写一些一次性的、可以随手扔掉的脚本,这种情况下不作版本控制没关系。但是如果你面对的是大量的代码,使用版本控制系统是有利的。版本控制能够帮你追踪谁对代码库做了什么操作;发现新引入了什么bug;管理你的软件的不同版本和发行版;在团队成员中分享源代码;部署及其他自动化处理。它能让你回滚到出现问题之前的版本,单凭这点就特别棒了。还有其他的好功能。怎么一个棒字了得!

9."猴子补丁"(monkey patching)指的是什么?这种做法好吗?

猴子补丁:是指在函数或对象已经定义之后,再去改变它们的行为。
举例:

import datetime
datetime.datetime.now = lambda: datetime.datetime(2012, 12, 12)

大部分情况下,这是种很不好的做法,因为函数代码库中的行为最好是都保持一致。打“猴子补丁”的原因可能是为了测试。mock包对实现这个目的很有帮助。
为什么提这个问题?
答对这个问题说明你对单元测试的方法有一定了解。你如果提到要避免“猴子补丁”,可以说明你不是那种喜欢花里胡哨的程序员(公司里就有这种人,跟他们共事真是糟糕透了),而是更注重可维护性。
另外:如果你没读过mock模块的话,真的值得花时间读一读。这个模块非常有用。

10 select,poll和epoll

其实所有的I/O都是轮询的方法,只不过实现的层面不同罢了.
这个问题可能有点深入了,但相信能回答出这个问题是对I/O多路复用有很好的了解了.其中tornado使用的就是epoll的.
基本上select有3个缺点:
(1).连接数受限
(2).查找配对速度慢
(3).数据由内核拷贝到用户态
poll改善了第一个缺点。
epoll改了三个缺点。

11.简单介绍一下调度算法

(1).先来先服务(FCFS, First Come First Serve)
(2).短作业优先(SJF, Shortest Job First)
(3).最高优先权调度(Priority Scheduling)
(4).时间片轮转(RR, Round Robin)
(5).多级反馈队列调度(multilevel feedback queue scheduling)
实时调度算法:
(1).最早截至时间优先EDF
(2).最低松弛度优先LLF

12.简单描述下程序编译与链接

Bulid过程可以分解为4个步骤:预处理(Prepressing)、编译(Compilation)、汇编(Assembly)、链接(Linking)
以c语言为例:
(1).预处理
预编译过程主要处理那些源文件中的以“#”开始的预编译指令,主要处理规则有:
a.将所有的“#define”删除,并展开所用的宏定义
b.处理所有条件预编译指令,比如“#if”、“#ifdef”、 “#elif”、“#endif”
c.处理“#include”预编译指令,将被包含的文件插入到该编译指令的位置,注:此过程是递归进行的
d.删除所有注释
e.添加行号和文件名标识,以便于编译时编译器产生调试用的行号信息以及用于编译时产生编译错误或警告时可显示行号
f.保留所有的#pragma编译器指令。
(2).编译
编译过程就是把预处理完的文件进行一系列的词法分析、语法分析、语义分析及优化后生成相应的汇编代码文件。这个过程是整个程序构建的核心部分。
(3).汇编
汇编器是将汇编代码转化成机器可以执行的指令,每一条汇编语句几乎都是一条机器指令。经过编译、链接、汇编输出的文件成为目标文件(Object File)
(4).链接
链接的主要内容就是把各个模块之间相互引用的部分处理好,使各个模块可以正确的拼接。
链接的主要过程包块 地址和空间的分配(Address and Storage Allocation)、符号决议(Symbol Resolution)和重定位(Relocation)等步骤。

13简述静态链接和动态链接

静态链接方法:静态链接的时候,载入代码就会把程序用到的动态代码或动态代码的地址确定下来。(事先把需要的东西都准备好)
静态库的链接可以使用静态链接,动态链接库也可以使用这种方法链接导入库。
动态链接方法:使用这种方式的程序并不在一开始就完成动态链接,而是直到真正调用动态库代码时,载入程序才计算(被调用的那部分)动态代码的逻辑地址,然后等到某个时候,程序又需要调用另外某块动态代码时,载入程序又去计算这部分代码的逻辑地址,所以,这种方式使程序初始化时间较短,但运行期间的性能比不上静态链接的程序。(先跑起来再说,需要什么再去取)

14.简述虚拟内存计数

虚拟存储器是指具有请求调入功能和置换功能,能从逻辑上对内存容量加以扩充的一种存储系统。

15.分页与分段的主要区别

(1).页是信息的物理单位,分页是为了实现非连续分配,以便解决内存碎片问题,或者说分页是由于系统管理的需要。段是信息的逻辑单位,它含有一组意义相对完整的信息,分段的目的是为了更好地实现共享,满足用户的需要。
(2).页的大小固定,由系统确定,将逻辑地址划分为页号和页内地址是由机器硬件实现的。而段的长度却不固定,决定于用户所编写的程序,通常由编译程序在对源程序进行编译时根据信息的性质来划分。

16.简述页面置换算法

(1).最佳置换算法OPT:不可能实现
(2).先进先出FIFO
(3).最近最久未使用算法LRU:最近一段时间里最久没有使用过的页面予以置换
(4).clock算法

16.简述边沿触发和水平触发

边沿触发是指每当状态变化时发生一个io事件,条件触发是只要满足条件就发生一个io事件。


python面试题库_v2.0_第1张图片
heike4.jpg

你可能感兴趣的:(python面试题库_v2.0)