接上篇。

网络

1 三次握手

  1. 客户端通过向服务器端发送一个SYN来创建一个主动打开,作为三路握手的一部分。客户端把这段连接的序号设定为随机数 A。

  2. 服务器端应当为一个合法的SYN回送一个SYN/ACK。ACK 的确认码应为 A+1,SYN/ACK 包本身又有一个随机序号 B。

  3. 最后,客户端再发送一个ACK。当服务端受到这个ACK的时候,就完成了三路握手,并进入了连接创建状态。此时包序号被设定为收到的确认号 A+1,而响应则为 B+1。

2 四次挥手

3 ARP协议

地址解析协议(Address Resolution Protocol): 根据IP地址获取物理地址的一个TCP/IP协议

4 urllib和urllib2的区别

这个面试官确实问过,当时答的urllib2可以Post而urllib不可以.

  1. urllib提供urlencode方法用来GET查询字符串的产生,而urllib2没有。这是为何urllib常和urllib2一起使用的原因。

  2. 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 网站用户密码保存

  1. 明文保存

  2. 明文hash后保存,如md5

  3. MD5+Salt方式,这个salt可以随机

  4. 知乎使用了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

  1. 请求头Host字段,一个服务器多个网站

  2. 长链接

  3. 文件断点续传

  4. 身份认证,状态管理,Cache缓存

21 Ajax

AJAX,Asynchronous JavaScript and XML(异步的 JavaScript 和 XML), 是与在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。

*NIX

unix进程间通信方式(IPC)

  1. 管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。

  2. 命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。

  3. 信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。

  4. 消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺

  5. 共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。

  6. 内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。

  7. 信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。

  8. 套接口(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()

print
l2

用字典并保持顺序

l1
= ['b','c','d','b','c','a','a']

l2
= list(set(l1))

l2.sort(key=l1.index)

print
l2

列表推导式

l1
= ['b','c','d','b','c','a','a']

l2
= []

[l2.append(i)
for
i
in
l1
if
not
i
in
l2]

面试官提到的,先排序然后删除.

6 链表成对调换

1->2->3->4转换成2->1->4->3.

class
ListNode:

def
__init__(self,
x):

self.val
= x

self.next
= None

class
Solution:

#
@param a ListNode

#
@return a ListNode

def
swapPairs(self,
head):

if
head
!= None
and
head.next
!= None:

next
= head.next

head.next
= self.swapPairs(next.next)

next.next
= head

return
next

return
head

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):

if
len(l1)
== 0
or
len(l2)
== 0:

tmp.extend(l1)

tmp.extend(l2)

return
tmp

else:

if
l1[0]
< l2[0]:

tmp.append(l1[0])

del
l1[0]

else:

tmp.append(l2[0])

del
l2[0]

return
_recursion_merge_sort2(l1,
l2,
tmp)

def
recursion_merge_sort2(l1,
l2):

return
_recursion_merge_sort2(l1,
l2,
[])

循环算法

def
loop_merge_sort(l1,
l2):

tmp
= []

while
len(l1)
> 0
and
len(l2)
> 0:

if
l1[0]
< l2[0]:

tmp.append(l1[0])

del
l1[0]

else:

tmp.append(l2[0])

del
l2[0]

tmp.extend(l1)

tmp.extend(l2)

return
tmp

9 交叉链表求交点

去哪儿的面试,没做出来.

class
ListNode:

def
__init__(self,
x):

self.val
= x

self.next
= None

def
node(l1,
l2):

length1,
lenth2
= 0,
0

#
求两个链表长度

while
l1.next:

l1
= l1.next

length1
+= 1

while
l2.next:

l2
= l2.next

length2
+= 1

#
长的链表先走

if
length1
> lenth2:

for
_
in
range(length1
- length2):

l1
= l1.next

else:

for
_
in
range(length2
- length1):

l2
= l2.next

while
l1
and
l2:

if
l1.next
== l2.next:

return
l1.next

else:

l1
= l1.next

l2
= l2.next

10 二分查找

def
binarySearch(l,
t):

low,
high
= 0,
len(l)
- 1

while
low
< high:

print
low,
high

mid
= (low
+ high)
/ 2

if
l[mid]
> t:

high
= mid

elif
l[mid]
< t:

low
= mid
+ 1

else:

return
mid

return
low
if
l[low]
== t
else
False

if
__name__
== '__main__':

l
= [1,
4,
12,
45,
66,
99,
120,
444]

print
binarySearch(l,
12)

print
binarySearch(l,
1)

print
binarySearch(l,
13)

print
binarySearch(l,
444)

11 快排

def
qsort(seq):

if
seq==[]:

return
[]

else:

pivot=seq[0]

lesser=qsort([x
for
x
in
seq[1:]
if
x<pivot])

greater=qsort([x
for
x
in
seq[1:]
if
x>=pivot])

return
lesser+[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所使用的硬币数目

for
cents
in
range(1,
money+1):

minCoins
= cents    
#从第一个开始到money的所有情况初始

for
value
in
values:

if
value
<= cents:

temp
= coinsUsed[cents
- value]
+ 1

if
temp
< 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:0
for
i
in
range(money+1)}

coinChange(values,
money,
coinsUsed)

13 广度遍历和深度遍历二叉树

给定一个数组,构建二叉树,并且按层次打印这个二叉树

## 14 二叉树节点

class
Node(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 层次遍历

def
lookup(root):

stack
= [root]

while
stack:

current
= stack.pop(0)

print
current.data

if
current.left:

stack.append(current.left)

if
current.right:

stack.append(current.right)

## 16 深度遍历

def
deep(root):

if
not
root:

return

print
root.data

deep(root.left)

deep(root.right)

if
__name__
== '__main__':

lookup(tree)

deep(tree)

17 前中后序遍历

深度遍历改变顺序就OK了

18 求最大树深

def
maxDepth(root):

if
not
root:

return
0

return
max(maxDepth(root.left),
maxDepth(root.right))
+ 1

19 求两棵树是否相同

def
isSameTree(p,
q):

if
p
== None
and
q
== None:

return
True

elif
p
and
q
:

return
p.val
== q.val
and
isSameTree(p.left,q.left)
and
isSameTree(p.right,q.right)

else
:

return
False

20 前序中序求后序

推荐: http://blog.csdn.net/hinyunsin/article/details/6315502

def
rebuild(pre,
center):

if
not
pre:

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:])

return
cur

def
deep(root):

if
not
root:

return

deep(root.left)

deep(root.right)

print
root.data

21 单链表逆置

class
Node(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)))))))))

def
rev(link):

pre
= link

cur
= link.next

pre.next
= None

while
cur:

tmp
= cur.next

cur.next
= pre

pre
= cur

cur
= tmp

return
pre

root
= rev(link)

while
root:

print
root.data

root
= root.next

Python 面试题(下)的更多相关文章

  1. Python面试题 —— 获取列表中位数

    中位数是一个可将数值集合划分为相等的上下两部分的一个数值.如果列表数据的个数是奇数,则列表中间那个数据就是列表数据的中位数:如果列表数据的个数是偶数,则列表中间那2个数据的算术平均值就是列表数据的中位 ...

  2. python公司面试题集锦 python面试题大全

    问题一:以下的代码的输出将是什么? 说出你的答案并解释. class Parent(object): x = 1 class Child1(Parent): pass class Child2(Par ...

  3. python笔试题(1)

            为了充实自己,小编决定上传自己见到的笔试题和面试题.可能要写好长时间,一时半会写不了多少,只能说遇到多少写多少吧,但是只要小编有时间,会持续上传(但是答案却不能保证,所以有看到错误的及 ...

  4. 【Python】【面试必看】Python笔试题

    前言 现在面试测试岗位,一般会要求熟悉一门语言(python/java),为了考验求职者的基本功,一般会出 2 个笔试题,这些题目一般不难,主要考察基本功.要是给你一台电脑,在编辑器里面边写边调试,没 ...

  5. Python面试题整理-更新中

    几个链接: 编程零基础应当如何开始学习 Python ? - 路人甲的回答 网易云课堂上有哪些值得推荐的 Python 教程? - 路人甲的回答 怎么用最短时间高效而踏实地学习 Python? - 路 ...

  6. python 面试题4

    Python面试题 基础篇 分类: Python2014-08-08 13:15 2071人阅读 评论(0) 收藏 举报 最近,整理了一些python常见的面试题目,语言是一种工具,但是多角度的了解工 ...

  7. 很全的 Python 面试题

    很全的 Python 面试题 Python语言特性 1 Python的函数参数传递 看两个例子:           Python   1 2 3 4 5 a = 1 def fun(a):      ...

  8. 震惊!几道Python 理论面试题,Python面试题No18

    本面试题题库,由公号:非本科程序员 整理发布 第1题: 简述解释型和编译型编程语言? 解释型语言编写的程序不需要编译,在执行的时候,专门有一个解释器能够将VB语言翻译成机器语言,每个语句都是执行的时候 ...

  9. 面试前赶紧看了5道Python Web面试题,Python面试题No17

    目录 本面试题题库,由公号:非本科程序员 整理发布 第1题: Flask中的请求上下文和应用上下文是什么? 第2题:django中间件的使用? 第3题: django开发中数据做过什么优化? 第4题: ...

  10. 千万不要错过这几道Python面试题,Python面试题No16

    第1题: python下多线程的限制以及多进程中传递参数的方式? python多线程有个全局解释器锁(global interpreter lock),简称GIL,这个GIL并不是python的特性, ...

随机推荐

  1. 《学习bash》笔记--进程处理

    1.进程ID和作业编号  当通过附加&号后执行命令时.shell会响应例如以下: $ ls & [1] 3318 当中[1]是作业号,3318是进程号. 一个后台进程完毕时.shell ...

  2. JQuery修改对象的属性值

    JQuery修改对象的属性值 用到的便是JQuery提供的attr方法,获取属性值的基本结构为:$(obj).attr("属性名"):修改属性值的结构为:$(obj).attr(& ...

  3. react-native 常用组件的用法(一)

    1.View组件 View是一个支持Flexbox布局.样式.一些触摸处理.和一些无障碍功能的容器,并且它可以放到其它的视图里,也可以有任意多个任意类型的子视图. View的设计初衷是和StyleSh ...

  4. STL学习笔记(仿函数)

    仿函数(Functors) 仿函数(functor),就是使一个类的使用看上去象一个函数.其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了. 例如我们定义一个 ...

  5. ibatis 读写clob数据

      ibatis 读写clob数据 CreationTime--2018年7月1日09点57分 Author:Marydon 1.从数据库读取数据 <!-- 根据主键查询患者信息.申请单.报告单 ...

  6. Chrome 完整版官方下载

    Chrome下载默认不是完整版本,需要长久等等.so... 在下载地址后加参数:?standalone=1  解决问题.

  7. git个人使用总结(命令版)

    一.基础命令 快照类操作:add.status.diff.commit.reset.rm.mv 分支类基本操作:branch.checkout.log.stash 分享及更新项目基本操作:pull.p ...

  8. 操作log.py

    # 把双数日期的日志,里面给随便写点东西# 1.获取到log目录下的所有文件os.walk()# 2.根据文件名来判断,是否是双数日期,分割字符串,取到日期# 3.12%2==0# 4.打开这个文件 ...

  9. java 根据生日计算年龄 Java问题通用解决代码

    根据生日计算年龄可以通过Calendar实现.最简单可以考虑get(Calendar.DAY_OF_YEAR)来简单修正年龄,但是遇到生日在闰年的2月29之后,或者今年是闰年的2月29之后可能出现计算 ...

  10. jsp页面JSTL标签 <c:fn:>

    函数名 函数说明 使用举例 fn:contains 判断字符串是否包含另外一个字符串 <c:if test="${fn:contains(name, searchString)}&qu ...