面试题汇总(四)

1.请解释TCP/IP协议

TCP/IP 协议栈是一系列网络协议的总和,是构成网络通信的核心骨架,它定义了电子设备如何连入因特网,以及数据如何在它们之间进行传输。TCP/IP 协议采用4层结构,分别是应用层、传输层、网络层和链路层,每一层都呼叫它的下一层所提供的协议来完成自己的需求。由于我们大部分时间都工作在应用层,下层的事情不用我们操心;其次网络协议体系本身就很复杂庞大,入门门槛高,因此很难搞清楚TCP/IP的工作原理,通俗一点讲就是,一个主机的数据要经过哪些过程才能发送到对方的主机上。

 

 

2.请列出你知道的HTTP状态码

2开头 (请求成功)表示成功处理了请求的状态代码。3开头 (请求被重定向)表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。4开头 (请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理.

200 (成功)201 (已创建) 202 (已接受) 203 (非授权信息)204 (无内容) 205 (重置内容)206 (部分内容)300 (多种选择)301 (永久移动)302 (临时移动)303 (查看其他位置)304 (未修改)305 (使用代理)307 (临时重定向)400 (错误请求)401 (未授权)403 (禁止)404 (未找到)405 (方法禁用) 406 (不接受) 407 (需要代理授权)408 (请求超时) 409 (冲突) 410 (已删除)411 (需要有效长度)

 

3.一行代码实现1-100之和

 

num = sum(range(1,101))

 

 

4.如何在一个函数内部修改去全局变量?

a = 1
def add():
  global a
  a = a + 1
  print(a)
add()

 

 

5.列出5个常用Python标准库

os操作系统
time 时间
random 随机
pymysql 连接数据库
threading 线程
multiprocessing 进程
queue 队列

 

6.如何合并两个字典

#方法一:
d1 = {'usr':'zhangxin', 'pwd':'123456'}
d2 = {'ip':'127.0.0.1', 'port': '8000'}
d3 = dict(d1, **d2)
print(d3)


#方法二:
d1 = {'usr':'zhangxin', 'pwd':'123456'}
d2 = {'ip':'127.0.0.1', 'port': '8000'}
d3 = {}
d3.update(d1)
d3.update(d2)


#方法三:
d1 = {'usr':'zhangxin', 'pwd':'123456'}
d2 = {'ip':'127.0.0.1', 'port': '8000'}
d3 = {}
for k, v in d1.items():
   d3[k] = v
for k, v in d2.items():
   d3[k] = v

print(d3)
print(d3)

 

 

7.Python实现列表去重的方法?

li = [1, 2, 3, 4, 1, 2]
s = set(li)
li = list(s)
print(li)

 

 

8.实现一个单例模式

#方法一:__new__
class Borg(object):
   def __new__(cls, *args, **kwargs):
       if not hasattr(cls, '_instance'):
           ob = super(Borg, cls)
           cls._instance = ob.__new__(cls, *args, **kwargs)
       return cls._instance

class MyClass(Borg):
   def __init__(self):
       self.a = 1

if __name__ == '__main__':
   a1 = MyClass()
   a2 = MyClass()

   a1.a = 10
   print(a1.a)
   print(a2.a)
   print(a1.__dict__)
   
   
   
   
#方法二:共享模式
class Borg2(object):
   _state = {}

   def __new__(cls, *args, **kwargs):
       ob = super(Borg2, cls).__new__(cls, *args, **kwargs)
       ob.__dict__ = cls._state
       return ob

class MyClass(Borg2):
   def __init__(self):
       self.a = 1


if __name__ == '__main__':
   a1 = MyClass()
   a2 = MyClass()

   a1.a = 10
   print(a1.a)
   print(a2.a)
   print(a1.__dict__)

 

 

9.写一段自定义异常代码

 

class FError(Exception):
   pass

try:
   raise FError("自定义异常")
   except FError as e:
   print(e)

 

 

10.简述多线程, 多进程

进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。或者说进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。 线程则是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。

 

进程和线程的关系:

(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。

(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。

(3)CPU分给线程,即真正在CPU上运行的是线程。

 

11.谈一下python的GIL

GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定。每个CPU在同一时间只能执行一个线程(在单核CPU下的多线程其实都只是并发,不是并行,并发和并行从宏观上来讲都是同时处理多路请求的概念。但并发和并行又有区别,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。) 在Python多线程下,每个线程的执行方式: 1.获取GIL 2.执行代码直到sleep或者是python虚拟机将其挂起。 3.释放GIL 可见,某个线程想要执行,必须先拿到GIL,我们可以把GIL看作是“通行证”,并且在一个python进程中,GIL只有一个。拿不到通行证的线程,就不允许进入CPU执行。

 

12.写一个函数, 输入一个字符串, 返回倒序排列的结果: 如: string_reverse('abcdef'), 返回: 'fedcba'(请采用多种方法实现, 并对实现方法进行比较)

 

#1.使用字符串本身的翻转
def string_reverse1(text='abcdef'):
   return text[::-1]
#2.把字符串变为列表,用列表的reverse函数
def string_reverse2(text='abcdef'):
   new_text=list(text)
   new_text.reverse()
   return ''.join(new_text)

print string_reverse2('abcdef')
fedcba
#3.新建一个列表,从后往前取
def string_reverse3(text='abcdef'):
   new_text=[]
   for i in range(1,len(text)+1):
       new_text.append(text[-i])
   return ''.join(new_text)

print string_reverse3('abcdef')
fedcba
#4.利用双向列表deque中的extendleft函数
from collections import deque
def string_reverse4(text='abcdef'):
   d = deque()
   d.extendleft(text)
   return ''.join(d)

print string_reverse4('abcdef')
fedcba
#5.递归
def string_reverse5(text='abcdef'):
   if len(text)<=1:
        return text
   else:
       return string_reverse5(text[1:]+text[0])

 

12.一个台阶总共有n级, 如果一次可以跳1级, 也可以跳2级, 求总共有多少种跳法.

 

F(1) = 1;
F(2)= 2;
F(n) = F(n-1)+F(n-2);  n>2

 

13.进程和线程的区别是什么?

进程是一个程序执行的实体. 进程包含的资源有:代码, 公有数据, 进程控制块(pid, 软硬件资源) 进程的提点是占用内存空间较大, 上下文切换速度慢

线程是一个程序的执行路径(一个函数) 线程包含的资源有:函数代码, 私有数据, 线程控制块, 线程特点是占用内存空间小, 上下文切换速度快

 

 

1.地址空间和其他资源(如打开文件):进程间相互独立,同一进程的各线程间共享。某进程内的线程在其他进程内不可见。 2.通信:进程间通信IPC(管道,信号量,共享内存,消息队列),线程间可以直接独写进程数据段(如全局变量)来进程通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。 3.调度和切换:线程上下文切换比进程上下文切换快得多。 4.在多线程OS中,进程不是一个可执行的实体。

 

 

 

14.进程间的通信机制有哪些?

1.python提供了多种进程通信方式, 主要Queue和Pipe这两种方式, Queue用于多个进程间实现通信, Pipe是两个进程的通信 1.1 Queue有两个方法: Put方法:以插入数据到队列中,他还有两个可选参数:blocked和timeout。详情自行百度 Get方法:从队列读取并且删除一个元素。同样,他还有两个可选参数:blocked和timeout。详情自行百度 1.2 Pipe通信机制,

  • Pipe常用于两个进程,两个进程分别位于管道的两端

  • Pipe方法返回(conn1,conn2)代表一个管道的两个端,Pipe方法有duplex参数,默认为True,即全双工模式,若为FALSE,conn1只负责接收信息,conn2负责发送,

  • send和recv方法分别为发送和接收信息

 

15.请描述TCP和UDP的区别

TCP与UDP区别总结: 1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接;

  1. TCP提供可靠的服务, 也就是说, 通过TCP连接传送的数据, 无差错, 不丢失, 不重复, 且按序到达; UDP尽最大努力交付, 既不保证可靠交付;

  2. TCP面向字节流, 实际上是TCP把数据堪称一连串无结构的字节流;UDP是面向报文的;UDP没有拥塞控制, 因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用, 如IP电话, 实时视频会议等);

  3. 每一条TCP连接只能是点到点的;UDP支持一对一, 一对多, 多对一和多对多的交互通信;

  4. TCP首部开销20字节;UDP的首部开销小, 只有8个字节;

  5. TCP的逻辑通信信道是全双工的可靠信道, UDP则是不可靠信道

 

 

 

posted @ 2019-08-22 11:28  陈文鑫  阅读(293)  评论(0编辑  收藏  举报