Python 面试题(下)
来源:互联网 发布:大数据的未来前景 编辑:程序博客网 时间:2024/03/29 17:35
接上篇。
网络
1 三次握手
客户端通过向服务器端发送一个SYN来创建一个主动打开,作为三路握手的一部分。客户端把这段连接的序号设定为随机数 A。
服务器端应当为一个合法的SYN回送一个SYN/ACK。ACK 的确认码应为 A+1,SYN/ACK 包本身又有一个随机序号 B。
最后,客户端再发送一个ACK。当服务端受到这个ACK的时候,就完成了三路握手,并进入了连接创建状态。此时包序号被设定为收到的确认号 A+1,而响应则为 B+1。
2 四次挥手
3 ARP协议
地址解析协议(Address Resolution Protocol): 根据IP地址获取物理地址的一个TCP/IP协议
4 urllib和urllib2的区别
这个面试官确实问过,当时答的urllib2可以Post而urllib不可以.
urllib提供urlencode方法用来GET查询字符串的产生,而urllib2没有。这是为何urllib常和urllib2一起使用的原因。
urllib2可以接受一个Request类的实例来设置URL请求的headers,urllib仅可以接受URL。这意味着,你不可以伪装你的User Agent字符串等。
5 Post和Get
GET和POST有什么区别?及为什么网上的多数答案都是错的(http://www.cnblogs.com/nankezhishi/archive/2012/06/09/getandpost.html)
get: RFC 2616 – Hypertext Transfer Protocol — HTTP/1.1(http://tools.ietf.org/html/rfc2616#section-9.3)
post: RFC 2616 – Hypertext Transfer Protocol — HTTP/1.1(http://tools.ietf.org/html/rfc2616#section-9.5)
6 Cookie和Session
session技术是要使用到cookie的,之所以出现session技术,主要是为了安全。
7 apache和nginx的区别
nginx 相对 apache 的优点:
轻量级,同样起web 服务,比apache 占用更少的内存及资源
抗并发,nginx 处理请求是异步非阻塞的,支持更多的并发连接,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能
配置简洁
高度模块化的设计,编写模块相对简单
社区活跃
apache 相对nginx 的优点:
rewrite ,比nginx 的rewrite 强大
模块超多,基本想到的都可以找到
少bug ,nginx 的bug 相对较多
超稳定
8 网站用户密码保存
明文保存
明文hash后保存,如md5
MD5+Salt方式,这个salt可以随机
知乎使用了Bcrypy(好像)加密
9 HTTP和HTTPS
403: Forbidden
404: Not Found
HTTPS握手,对称加密,非对称加密,TLS/SSL,RSA
10 XSRF和XSS
CSRF(Cross-site request forgery)跨站请求伪造
XSS(Cross Site Scripting)跨站脚本攻击
CSRF重点在请求,XSS重点在脚本
11 幂等 Idempotence
HTTP方法的幂等性是指一次和多次请求某一个资源应该具有同样的副作用。(注意是副作用)
GET http://www.bank.com/account/123456,不会改变资源的状态,不论调用一次还是N次都没有副作用。请注意,这里强调的是一次和N次具有相同的副作用,而不是每次GET的结果相同。GET http://www.news.com/latest-news这个HTTP请求可能会每次得到不同的结果,但它本身并没有产生任何副作用,因而是满足幂等性的。
DELETE方法用于删除资源,有副作用,但它应该满足幂等性。比如:DELETE http://www.forum.com/article/4231,调用一次和N次对系统产生的副作用是相同的,即删掉id为4231的帖子;因此,调用者可以多次调用或刷新页面而不必担心引起错误。
POST所对应的URI并非创建的资源本身,而是资源的接收者。比如:POST http://www.forum.com/articles的语义是在http://www.forum.com/articles下创建一篇帖子,HTTP响应中应包含帖子的创建状态以及帖子的URI。两次相同的POST请求会在服务器端创建两份资源,它们具有不同的URI;所以,POST方法不具备幂等性。
PUT所对应的URI是要创建或更新的资源本身。比如:PUT http://www.forum/articles/4231的语义是创建或更新ID为4231的帖子。对同一URI进行多次PUT的副作用和一次PUT是相同的;因此,PUT方法具有幂等性。
12 RESTful架构(SOAP,RPC)
推荐: http://www.ruanyifeng.com/blog/2011/09/restful.html
13 SOAP
SOAP(原为Simple Object Access Protocol的首字母缩写,即简单对象访问协议)是交换数据的一种协议规范,使用在计算机网络Web服务(web service)中,交换带结构信息。SOAP为了简化网页服务器(Web Server)从XML数据库中提取数据时,节省去格式化页面时间,以及不同应用程序之间按照HTTP通信协议,遵从XML格式执行资料互换,使其抽象于语言实现、平台和硬件。
14 RPC
RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
总结:服务提供的两大流派.传统意义以方法调用为导向通称RPC。为了企业SOA,若干厂商联合推出webservice,制定了wsdl接口定义,传输soap.当互联网时代,臃肿SOA被简化为http+xml/json.但是简化出现各种混乱。以资源为导向,任何操作无非是对资源的增删改查,于是统一的REST出现了.
进化的顺序: RPC -> SOAP -> RESTful
15 CGI和WSGI
CGI是通用网关接口,是连接web服务器和应用程序的接口,用户通过CGI来获取动态数据或文件等。
CGI程序是一个独立的程序,它可以用几乎所有语言来写,包括perl,c,lua,python等等。
WSGI, Web Server Gateway Interface,是Python应用程序或框架和Web服务器之间的一种接口,WSGI的其中一个目的就是让用户可以用统一的语言(Python)编写前后端。
官方说明:PEP-3333
16 中间人攻击
在GFW里屡见不鲜的,呵呵.
中间人攻击(Man-in-the-middle attack,通常缩写为MITM)是指攻击者与通讯的两端分别创建独立的联系,并交换其所收到的数据,使通讯的两端认为他们正在通过一个私密的连接与对方直接对话,但事实上整个会话都被攻击者完全控制。
17 c10k问题
所谓c10k问题,指的是服务器同时支持成千上万个客户端的问题,也就是concurrent 10 000 connection(这也是c10k这个名字的由来)。
推荐: http://www.kegel.com/c10k.html
18 socket
推荐: http://www.cnblogs.com/bingyun84/archive/2009/10/16/1584387.html
Socket=Ip address+ TCP/UDP + port
19 浏览器缓存
推荐: http://web.jobbole.com/84367/
304 Not Modified
20 HTTP1.0和HTTP1.1
推荐: http://blog.csdn.net/elifefly/article/details/3964766
请求头Host字段,一个服务器多个网站
长链接
文件断点续传
身份认证,状态管理,Cache缓存
21 Ajax
AJAX,Asynchronous JavaScript and XML(异步的 JavaScript 和 XML), 是与在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。
*NIX
unix进程间通信方式(IPC)
管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。
信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。
消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺
共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。
信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。
数据结构
1 红黑树
红黑树与AVL的比较:
AVL是严格平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多;
红黑是用非严格的平衡来换取增删节点时候旋转次数的降低;
所以简单说,如果你的应用中,搜索的次数远远大于插入和删除,那么选择AVL,如果搜索,插入删除次数几乎差不多,应该选择RB。
编程题
1 台阶问题/斐波纳挈
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
fib = lambda n: n if n <= 2 else fib(n - 1) + fib(n - 2)
第二种记忆方法
def memo(func):
cache = {}
def wrap(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrap
@ memo
def fib(i):
if i < 2:
return 1
return fib(i-1) + fib(i-2)
第三种方法
def fib(n):
a, b = 0, 1
for _ in xrange(n):
a, b = b, a + b
return b
2 变态台阶问题
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
fib = lambda n: n if n < 2 else 2 * fib(n - 1)
3 矩形覆盖
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
第2*n个矩形的覆盖方法等于第2*(n-1)加上第2*(n-2)的方法。
f = lambda n: 1 if n < 2 else f(n - 1) + f(n - 2)
4 杨氏矩阵查找
在一个m行n列二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
5 去除列表中的重复元素
用集合
list(set(l))
用字典
l1 = ['b','c','d','b','c','a','a']
l2 = {}.fromkeys(l1).keys()
printl2
用字典并保持顺序
l1 = ['b','c','d','b','c','a','a']
l2 = list(set(l1))
l2.sort(key=l1.index)
printl2
列表推导式
l1 = ['b','c','d','b','c','a','a']
l2 = []
[l2.append(i)foriinl1ifnotiinl2]
面试官提到的,先排序然后删除.
6 链表成对调换
1->2->3->4转换成2->1->4->3.
classListNode:
def__init__(self,x):
self.val = x
self.next = None
classSolution:
# @param a ListNode
# @return a ListNode
defswapPairs(self,head):
ifhead != Noneandhead.next != None:
next = head.next
head.next = self.swapPairs(next.next)
next.next = head
returnnext
returnhead
7 创建字典的方法
1 直接创建
dict = {'name':'earth', 'port':'80'}
2 工厂方法
items=[('name','earth'),('port','80')]
dict2=dict(items)
dict1=dict((['name','earth'],['port','80']))
3 fromkeys()方法
dict1={}.fromkeys(('x','y'),-1)
dict={'x':-1,'y':-1}
dict2={}.fromkeys(('x','y'))
dict2={'x':None,'y':None}
8 合并两个有序列表
知乎远程面试要求编程
尾递归
def_recursion_merge_sort2(l1,l2,tmp):
iflen(l1) == 0orlen(l2) == 0:
tmp.extend(l1)
tmp.extend(l2)
returntmp
else:
ifl1[0] < l2[0]:
tmp.append(l1[0])
dell1[0]
else:
tmp.append(l2[0])
dell2[0]
return_recursion_merge_sort2(l1,l2,tmp)
defrecursion_merge_sort2(l1,l2):
return_recursion_merge_sort2(l1,l2,[])
循环算法
defloop_merge_sort(l1,l2):
tmp = []
whilelen(l1) > 0andlen(l2) > 0:
ifl1[0] < l2[0]:
tmp.append(l1[0])
dell1[0]
else:
tmp.append(l2[0])
dell2[0]
tmp.extend(l1)
tmp.extend(l2)
returntmp
9 交叉链表求交点
去哪儿的面试,没做出来.
classListNode:
def__init__(self,x):
self.val = x
self.next = None
defnode(l1,l2):
length1,lenth2 = 0,0
# 求两个链表长度
whilel1.next:
l1 = l1.next
length1 += 1
whilel2.next:
l2 = l2.next
length2 += 1
# 长的链表先走
iflength1 > lenth2:
for_inrange(length1 - length2):
l1 = l1.next
else:
for_inrange(length2 - length1):
l2 = l2.next
whilel1andl2:
ifl1.next == l2.next:
returnl1.next
else:
l1 = l1.next
l2 = l2.next
10 二分查找
defbinarySearch(l,t):
low,high = 0,len(l) - 1
whilelow < high:
printlow,high
mid = (low + high) / 2
ifl[mid] > t:
high = mid
elifl[mid] < t:
low = mid + 1
else:
returnmid
returnlowifl[low] == telseFalse
if__name__ == '__main__':
l = [1,4,12,45,66,99,120,444]
printbinarySearch(l,12)
printbinarySearch(l,1)
printbinarySearch(l,13)
printbinarySearch(l,444)
11 快排
defqsort(seq):
ifseq==[]:
return[]
else:
pivot=seq[0]
lesser=qsort([xforxinseq[1:]ifx<pivot])
greater=qsort([xforxinseq[1:]ifx>=pivot])
returnlesser+[pivot]+greater
if__name__=='__main__':
seq=[5,6,78,9,0,-1,2,3,-65,12]
print(qsort(seq))
12 找零问题
def coinChange(values,money,coinsUsed):
#values T[1:n]数组
#valuesCounts 钱币对应的种类数
#money 找出来的总钱数
#coinsUsed 对应于目前钱币总数i所使用的硬币数目
forcentsinrange(1,money+1):
minCoins = cents #从第一个开始到money的所有情况初始
forvalueinvalues:
ifvalue <= cents:
temp = coinsUsed[cents - value] + 1
iftemp < minCoins:
minCoins = temp
coinsUsed[cents] = minCoins
print('面值为:{0} 的最小硬币数目为:{1} '.format(cents,coinsUsed[cents]))
if__name__ == '__main__':
values = [25,21,10,5,1]
money = 63
coinsUsed = {i:0foriinrange(money+1)}
coinChange(values,money,coinsUsed)
13 广度遍历和深度遍历二叉树
给定一个数组,构建二叉树,并且按层次打印这个二叉树
## 14 二叉树节点
classNode(object):
def__init__(self,data,left=None,right=None):
self.data = data
self.left = left
self.right = right
tree = Node(1,Node(3,Node(7,Node(0)),Node(6)),Node(2,Node(5),Node(4)))
## 15 层次遍历
deflookup(root):
stack = [root]
whilestack:
current = stack.pop(0)
printcurrent.data
ifcurrent.left:
stack.append(current.left)
ifcurrent.right:
stack.append(current.right)
## 16 深度遍历
defdeep(root):
ifnotroot:
return
printroot.data
deep(root.left)
deep(root.right)
if__name__ == '__main__':
lookup(tree)
deep(tree)
17 前中后序遍历
深度遍历改变顺序就OK了
18 求最大树深
defmaxDepth(root):
ifnotroot:
return0
returnmax(maxDepth(root.left),maxDepth(root.right)) + 1
19 求两棵树是否相同
defisSameTree(p,q):
ifp == Noneandq == None:
returnTrue
elifpandq :
returnp.val == q.valandisSameTree(p.left,q.left)andisSameTree(p.right,q.right)
else :
returnFalse
20 前序中序求后序
推荐: http://blog.csdn.net/hinyunsin/article/details/6315502
defrebuild(pre,center):
ifnotpre:
return
cur = Node(pre[0])
index = center.index(pre[0])
cur.left = rebuild(pre[1:index + 1],center[:index])
cur.right = rebuild(pre[index + 1:],center[index + 1:])
returncur
defdeep(root):
ifnotroot:
return
deep(root.left)
deep(root.right)
printroot.data
21 单链表逆置
classNode(object):
def__init__(self,data=None,next=None):
self.data = data
self.next = next
link = Node(1,Node(2,Node(3,Node(4,Node(5,Node(6,Node(7,Node(8,Node(9)))))))))
defrev(link):
pre = link
cur = link.next
pre.next = None
whilecur:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
returnpre
root = rev(link)
whileroot:
printroot.data
root = root.next
- Python 面试题(下)
- Python 面试题(上)
- Python面试题(二)
- Python 面试题(全面)
- python面试题(2)
- python面试题(3)
- Python面试题(原创)
- java面试题(下)
- 综合面试题(下)
- Java面试题(下)
- java面试题(下)
- 关于Python的面试题 (github)
- Python面试题大全(一)
- Python面试题大全(二)
- python面试题大全(一)
- python面试题大全(二)
- python面试题大全(一)
- python面试题大全(二)
- Python 面试题(上)
- PHP in_array的性能问题
- Python操作splite3的例子
- 【折腾日记GEN8_3】VMware vSphere Client的安装
- 编写php扩展的问题
- Python 面试题(下)
- 20个经典管理学定律
- centos7设备命名
- Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
- Leetcode 138. Copy List with Random Pointer
- CentOS7安装openjdk、tomcat和mysql流程介绍
- 面试题
- SQL注入攻防入门详解
- 如何在Linux下编译Cocos2dx3.11项目(主要是添加源文件喇~)