python基础面试题
1.为什么学习Python?
Python是目前市面上,我个人认为是最简洁、最优雅、最有前途、最全能的编程语言,没有之一。
2.通过什么途径学习的Python?
3.Python和Java、PHP、C、C#、C++等其他语言的对比?
Python:轻量级、易学、自由/开放源码软件、可移植性、支持面向对象、丰富的库、规范的代码。
Java:优点:开源性,功能强大,库多
缺点:编译速度 比较慢,不完全
PHP:优点:性能很强,配合简单,稳定,容易部署。
缺点:函数命名不规范,驼峰法和下划线,传参位置不一。
C: 优点:能操纵底层,能细粒度优化性能。
缺点:1、是面向过程的,2、运行时类型检查不可用,3、不提供命名空间功能,4、构
造函数和析构函数不可用。
C#: 优点: 强大的.NET Framework托管代码集合类,较简单的语言特性。WEB应用程序
开发速度快。
缺点:底层和高性能不合适,Windows平台以外支持有限。
C++: 优点:性能比较高,可进化型。
缺点: 难学,门槛高
4.简述解释型和编译型编程语言?
解释型 在运行时才翻译 每个语句执行时候才翻译 效率比较低 跨平台性好 (python)
编译型 程序执行之前有一个专门的编译过程 把程序编译成机器语言的文件 程序执行效率高 跨平台性差 (c c++)
5.Python解释器种类以及特点?
CPython
c语言开发的 使用最广的解释器
IPython
基于cpython之上的一个交互式计时器 交互方式增强 功能和cpython一样
PyPy
目标是执行效率 采用JIT技术 对python代码进行动态编译,提高执行效率
JPython
运行在Java上的解释器 直接把python代码编译成Java字节码执行
IronPython
运行在微软 .NET 平台上的解释器,把python编译成. NET 的字节码
6.位和字节的关系?
8位(bit)=1字节(Byte),1024字节=1KB;
7.b、B、KB、MB、GB 的关系?
1TB = 1024GB
1GB = 1024MB
1MB = 1024B(字节)
1字节 = 1个英文字母或1个数字或一个字符
2字节 = 1个中文汉字
8.请至少列举5个 PEP8 规范(越多越好)
1、缩进,4个空格的缩进(编译器都可以完成此功能),不适用Tab,更不能混合使用Tab和空格
2、每行最大长度为79,换行可以使用反斜杠。最好使用圆括号,换行点再操作符的后边敲回车。
3、不要再一句import中多个库。比如import os,sys(不推荐)
4、模块命名尽量短小,使用全部小写的方式,可以使用下划线。
5、包命名尽量短小,使用全部小写的方式。不可以使用下划线
6、类的命名使用CapWords的方式,模块内部使用的类采用--CapWords的方式。
7、函数命名使用全部小写的方式,可以使用下划线。
8、异常命名使用CapWords+Error后缀的方式。
9、常量命名使用全部大写的方式,可以使用下划线。
10、类的属性(方法和变量)命名使用全部小写的方式,可以使用下划线。
11、类方法第一个参数必须是self,而静态方法第一个参数必须是cls。
9.通过代码实现如下转换:
二进制转换成十进制:v = “0b1111011”
先将V变成字符串,然后print(int("0b1111011",2)),结果是123
十进制转换成二进制:v = 18
Print(bin(v)):0b10010
八进制转换成十进制:v = “011”
Print(int(v,8)) 结果是:9
十进制转换成八进制:v = 30
Print(oct(v))结果是:0o36
十六进制转换成十进制:v = “0x12”
v = "0x12"
s = str(v)
print(int(s,16))
#18
十进制转换成十六进制:v = 87
v = 87
print(hex(v))
#0x57
10.通过代码实现如下转换:
如 10.3.9.12 转换规则为:
10 00001010
3 00000011
9 00001001
12 00001100
再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ?
def bian(number):
a = str(bin(number))[2:]
if len(a) % 8:
b = ['0' for _ in range(8 - len(a) % 8)]
b.append(a)
return ''.join(b)
a = bian(10)
b = bian(10)
c = bian(10)
d = bian(10)
d = int(a + b + c + d, 2)
print(d)
#168430090
11.python递归的最大层数?
def fun(n):
print(n)
n += 1
fun(n)
print(fun(1))
998层,之后就报错了,允许最大数字在3925 - 3929之间浮动 ,和计算机的性能有关系。
12.求结果
求结果:
v1 = 1 or 3
v2 = 1 and 3
v3 = 0 and 2 and 1
v4 = 0 and 2 or 1
v5 = 0 and 2 or 1 or 4
v6 = 0 or Flase and 1
v1 = 1 or 3 1
v2 = 1 and 3 3
v3 = 0 and 2 and 1 0
v4 = 0 and 2 or 1 1
v5 = 0 and 2 or 1 or 4 1
v6 = 0 or False and 1 False
13.ascii、unicode、utf-8、gbk 区别?
ascii、unicode、utf-8、gbk 区别?
Ascii:早期编码,只支持英文字母和一些符号
Unicode:万国码,能表示多种符号,在PY2中可以指定4字节或2字节表示一个字符,PY3中默认4字节
UTF-8: 用最短的方式表示unicode,一个英文字符占一字节
Gbk:中文编码。
14.字节码和机器码的区别?
机器码:是电脑CPU直接读取运行的机器指令,运行速度最快,但是非常难懂,比较难编写, 一般人接触不到。
字节码:是一种中间状态(中间码)的二进制代码(文件)。需要直译器转译后才能成为机器码
15.三元运算规则以及应用场景?
一行书中写,代码非常精炼,执行效率更高,可以代替if...else这样的流行语句
16.列举 Python2和Python3的区别?
print:
在PY2中,被视为一个语句,而不是一个函数
在PY3中,被显示为一个函数。
整数的除法:
PY2中,整数是强类型的。比如5/2 结果是2
PY3中,5/2 结果是2.5
Unicode:
PY2中前缀加u代表Unicode。
PY3中默认使用Unicode,如果想让3兼容2,可以通过字符串的前面保留‘u’来实现。
后续发展:
PY3和PY2之间最大的区别不是在语法上,而是事实上PY2在2020年后将失去支持,PY3将继续开发更多的功能,和修复更多的错误。
17.用一行代码实现数值交换:
a = 1
b = 2
a = 1
b = 2
a,b = b,a
18.Python3和Python2中 int 和 long的区别?
long整数类型,被PY3废弃,统一使用int。
19.xrange和range的区别?
PY2中的range返回的是列表,xrange返回的是生成器
PY3中的range返回的是迭代器(测试是class)
20.文件操作时:xreadlines和readlines的区别?
返回类型不同。xreadlines返回的是生成器,readlines返回的是列表
21.列举布尔值为False的常见值?
"" , 0, false, [], (), {}
22.字符串、列表、元组、字典每个常用的5个方法?
字符串:
.upper() #首字母大写
.lower() #所有字母大写
.strip() #去除首尾空格
.replace() #替换
.split() #分割
列表:
.append() #在列表尾部追加一个值
.inset() # 指定位置插入数据
.reverse() #反转
.remove() #删除制定元素
.pop() #删除指定元素
元祖:
.index() #查看元素下标是多少
.len() #计算元祖元素个数
.min() #返回元祖中元素最小值
.max() #返回元祖元素最大值
.tuple() #将列表转换为元祖
字典:
.clear() #删除字典所有项
.get() #获取字典中指定键的值
.keys() #以列表的形式返回字典中所有键
.values() #以列表的形式返回字典中所有值
.items() #以列表的形式返回字典中的键值
23.lambda表达式格式以及应用场景?
lambda x:x + 2
应用场景:函数式编程,闭包
24.pass的作用?
1、空格局。2、保证格式完整性。3、语义完整
25.*arg和**kwarg作用
*arg:接受额外的位置参数
**kwarg接受额外的关键字参数
26.is和==的区别
is判断的是ID的地址
==判断的是数值
27.简述Python的深浅拷贝以及应用场景?
浅拷贝:拷贝最外层容器
深拷贝:拷贝的最外层容器,还拷贝容器中的元素
对于不可变元素,使用浅拷贝
28.Python垃圾回收机制?
1、回收计数引用为0的对象,释放其占用空间
2、循环垃圾回收器。释放循环引用对象
29.Python的可变类型和不可变类型?
可变类型:list、dict、set、可变集合
不可变类型:string、int、float、tuple、不可变集合
30.求结果
v = dict.fromkeys(['k1','k2'],[])
v[‘k1’].append(666)
print(v)
v[‘k1’] = 777
print(v)
1 、{'k1': [666], 'k2': [666]}
2、{'k1': 777, 'k2': [666]}
3、因为value是可变对象,并且使用append来添加元素,所有value的对象引用不变
31.求结果
def num():
return[lambda x:i*x for i in range(4)]
print([m(2) for m in num()])
#[6,6,6,6]
#将return返回生成器表达式就返回[0,2,4,6]
32.列举常见的内置函数?
len、bin、hex、oct、dir、max、min、type
33.filter、map、reduce的作用?
filter:清晰函数
map:对函数里的每个内容,执行方法
reduce:累加函数
配合lambda函数来进行使用
34.一行代码实现9*9乘法表
print('
'.join([' '.join([f'{y} * {x} = {x * y}' for y in range(1, x+1)]) for x in range(1,10)]))
35.如何安装第三方模块?以及用过哪些第三方模块?
使用官方推荐的setuptools的包管理工具,easy -- install和pip。
requests模块
36.至少列举8个常用模块都有那些?
1、sys:用于提供对解释器相关的访问以及维护,并有很强的交互功能
2、time: 时间模块
3、os:用于提供操作系统模块
4、ashlib:用于加密相关的操作
5、random:生成随机变量
6、pickle:用于python特有的类和pthon的数据类型间进行转换
7、datetime:date和time的结合体
8、re:正则表达式模块
37.re的match和search区别?
match与search函数功能一样,match匹配字符串开始的第一个位置,search是在字符串全局匹配第一个符合规则的。
38.什么是正则的贪婪匹配
尽可能的去匹配符合规则的字符,非贪婪模式后面加?(尽可能少的匹配)
39.求结果:a=[i % 2 for i in range(10)] b=(i % 2 for i in range(10))
1、a = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
2、b = 是生成器表达式(generator)
40.a=1 or 2 ,b= 1 and 2,c=1 < (2==2), d=1 < 2 == 2
a = 1 、 b = 2 、c = false 、d = True
41.def func(a,b=[])这种写法有什么坑?
因为b是可变类型,每次调用这个方法b不会每次都初始化[].而是调用相同的[].
42.如何实现 “1,2,3” 变成 [‘1’,’2’,’3’] ?
a = "1 , 2 ,3"
a. split(",")
43.如何实现[‘1’,’2’,’3’]变成[1,2,3] ?
a = ["1", "2", "3"]
方式1:b = [int(x) for x in a]
方式2:print(list(map(lambda x: int(x), a)))
44.比较: a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b2 = [(1,),(2,),(3,) ] 的区别?
1、a和b相同,因为只有一个元素的元祖需要加,来表示(1,)
2、b表示的列表元素为整数,b2表示的是列表元素是元祖
45.如何用一行代码生成[1,4,9,16,25,36,49,64,81,100] ?
print([x ** 2 for x in range(1, 11)])
46.一行代码实现删除列表中重复的值 ?
使用set(可迭代对象)
47.如何在函数中设置一个全局变量 ?
Global变量名
48.logging模块的作用?以及应用场景?
提供了通用的日志系统。
应用场景,做项目的时候打印日志,或者是异常
49.请用代码简答实现stack 。
# Stack():创建一个新的空栈
class Stack():
def __init__(self):
self.items = []
# 判断栈是否为空
def is_empty(self):
return self.items == []
# 添加一个新的元素,item到栈顶
def push(self, item):
self.items.append(item)
# 弹出栈顶元素
def pop(self):
return self.items.pop()
# 返回栈顶元素
def peek(self):
return self.items[len(self.items) - 1]
# 返回栈的元素个数
def size(self):
return len(self.items)
50.常用字符串格式化哪几种?
%、format、f
51.简述 生成器、迭代器、可迭代对象 以及应用场景?
1、生成器是迭代器的一种,需要时yiled关键字
2、迭代器实现了__next__方法
3、可迭代对象实现了__iter__,__next__方法
4、可迭代对象调用__iter__方法后,返回一个迭代器。
52.用Python实现一个二分查找的函数。
def search(datset, find_num):
if len(datset) > 1:
mid = int(len(datset) / 2)
if datset[mid] == find_num:
print(datset[mid])
elif datset[mid] > find_num:
return search(datset[0: mid], find_num)
else:
return search(datset[mid + 1:], find_num)
else:
if datset[0] == find_num:
print(datset[0])
else:
print("不好意思,没有这个数字:", find_num)
search(data, 20)
53.谈谈你对闭包的理解?
内层函数引用了外层函数的变量,然后返回内层函数的情况,成为闭包。
54.os和sys模块的作用?
os:系统有关。
sys:解释器有关。
55.如何生成一个随机数?
使用random模块里的random.random
56.如何使用python删除一个文件?
os.remove(path),删除文件path。如果path是一个目录,抛出osError错误。如果要删除目录,请使用rmdir()方法。
57.谈谈你对面向对象的理解?
体现在三个方面: 封装、继承、多态
继承有两种方式:
1、将同一类的方法封装到类中
2、将数据封装到对象中
继承:子类拥有父类的所有方法和属性,
好处:抽取重复代码,减少代码冗余。
坏处:耦合性太强。
多态:对于不同的类可以有同名的方法,同名的方法应用到不同的类可以有不同行为。
58.Python面向对象中的继承有什么特点?
1、在继承中基类的构造(__init__()方法)不会被调用,它需要在其派生类的构造亲自调用,有别于C#.
2、在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量,区别于在类中调用普通函数不需要带上self参数。
3、Python总是首先查找对应类型的方法,如果它不能再派生类中找到对应的方法,它才开始到基类中逐个查找。
4、Python里边可以继承多个类,C#、 Java不可以多继承(如果继承多个类,继承顺序为从左到右)
59.面向对象深度优先和广度优先是什么?
深度优先:不全部保留节点,占用空间小,有回溯操作(即有入栈/出栈操作),运行速度慢。
广度优先:保留全部节点,占用空间大;无回溯操作(既无入栈、出栈操作)、运行速度快。
60.面向对象中super的作用?
super()函数是用于调用父类的一个方法。用来解决多重继承问题的。
61.是否使用过functools中的函数?其作用是什么?
用过。
作用:把一个函数的某些参数给固定住,返回一个新的函数,调用这个新函数会更简单。
62.列举面向对象中带爽下划线的特殊方法,如:new、init
__new__:可以调用其它类的构造方法或者直接返回别的对象来作为本类的实例。
__init__: 负责类的实例化
__call__:对象后边加括号,出发执行
__str__:print打印一个对象时。
__doc__:类的注释,该属性是无法继承的。
__getattr__:在使用调用属性(方式、属性)不存在的时候触发
__setattr__:添加/修改属性会触发它的执行
__dellattr__:删除属性的时候会触发
__delete__:采用del删除属性时,触发
63.如何判断是函数还是方法?
函数:是封装了一些独立的功能。可以直接调用,python内置了许多函数,同时可以自建函数来使用。
方法:和函数类似,同样封装了独立的功能,但是方法是需要通过对象来调用的,表示针对这个对象要做的操作。
64.静态方法和类方法区别?
1、静态方法:相当于普通函数
2、类方法:通过类调用,第一个参数默认是类本身。
65.列举面向对象中的特殊成员以及应用场景
__new__ : 可以调用其他类的构造方法或者直接返回别的对象来作为本类的实例。
__init__ : 负责类的实例化
__call__对象后边加括号,触发执行
__str__ : print打印一个对象时。
__doc__ : 类的注释,该属性是无法继承的。
__getattr__ : 在使用调用属性(方式,属性)不存在的时候触发
__setattr__ : 添加/修改属性会触发它的执行
__dellattr__ : 删除属性的时候会触发
__delete__ : 采用del删除属性时,触发
66.1、2、3、4、5 能组成多少个互不相同且无重复的三位数
5*4*3
67.什么是反射?以及应用场景?
利用字符串获取对象的属性或方法。
web框架的CBV配置文件获取类
68.metaclass作用?以及应用场景?
metaclass是类的产生类,而并非继承类,
通过它来控制类的产生,以及类实例化的操作。Wtform中实例化自定义form类是执行了其元类的__call__方法。
69.用尽量多的方法实现单例模式。
一:基于classmethod
class Mysql(object):
_instance = None
def __init__(self, ip, port):
self.ip = ip
self.port = port
@classmethod
def singleton(cls):
if not cls._instance:
cls._instance = Mysql('127.0.0.1', 3306)
return cls._instance
obj1 = Mysql.singleton()
obj2 = Mysql.singleton()
print(obj1)
print(obj2)
二:基于装饰器
def singleton(cls):
# 该对象在类Mysql被装饰上singleton的时候就已经实例化完毕
_instance = cls('127.0.0.1',3306)
def inner(*args,**kwargs):
# 判断是否传入参数,传入参数表示要实例化新的,不传表示用默认的
if args or kwargs:
obj = cls(*args,**kwargs)
return obj
return _instance
return inner
@singleton
class Mysql:
def __init__(self,ip,port):
self.ip = ip
self.port = port
obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
print(obj1,obj2,obj3)
三:基于元类
class MymetaClass(type):
def __call__(self, *args, **kwargs):
if not hasattr(self,'instance'):
self.instance = super().__call__(*args,**kwargs)
return self.instance
class Mysql(metaclass=MymetaClass):
def __init__(self,host,port):
self.host = host
self.port = port
obj = Mysql('ajdak',213)
obj1 = Mysql('asdasdas',134234)
print(obj,obj1)
四:基于__new__
class Singleton(object):
_instance = None
def __new__(cls, *args, **kw):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kw)
return cls._instance
class MyClass(Singleton):
a = 1
五:基于模块
# 单独在一个py文件中定义一个类,并实例化一个对象,之后在其他文件导入这一对象,实现单例
class Singleton(object):
def __init__(self,host,port):
self.host = host
self.port = port
singleton = Singleton('127.0.0.1',3306)
70.装饰器的写法以及应用场景。
from functools import wraps
def outer(func):
@wraps(func)
def inner(*args, **kwargs):
"""我就是装饰器里的函数"""
func(*args, **kwargs)
return inner
#应用场景:Django的csrf,缓存,Falsk中的许多装饰器
71.异常处理写法以及如何主动抛出异常(应用场景)
try:
"""执行语句"""
except: #异常类型
"""触发异常后执行的语句"""
finally:
"""有没有异常都执行的语句"""
# 主动抛出异常
raise #异常类实例
72.什么是面向对象的mro
方法查找的顺序
73.isinstance作用以及应用场景?
判断一个对象是不是某个类的实例
74.写代码实现
Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would
have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1]
给定一个整数数组,返回两个数的索引,使它们加起来成为一个特定的目标。可以假定每个输入只有一个解,并且不能使用同一个元素两次。示例:给定nums=[2,7,11,15],目标=9,因为nums[0]+nums[1]=2+7=9,返回[0,1],
nums = [2, 7, 11, 15]
class Solution(object):
def twoSum(self, nums, target):
"""
:param nums: list[int]
:param target: int
:return: List[int]
"""
if len(nums) <= 1:
return False
buff_dict = {}
for i in range(len(nums)):
if nums[i] in buff_dict:
return [buff_dict[nums[i]], i]
else:
buff_dict[target - nums[i]] = i
75.json序列化时,可以处理的数据类型有哪些?如何定制支持datetime类型?
#字符串、字典、列表、数字、布尔值、None、、自定义class类
import json
from datetime import datetime, date
class MyJson(json.JSONEncoder):
def default(self, o):
if isinstance(o, datetime):
return o.strftime('%Y-%m-%d %X')
elif isinstance(o, date):
return o.strftime('%Y-%m-%d')
else:
super().default(self, o)
date_time = {'day1': datetime.today(), 'day2': date.today()}
print(json.dumps(date_time, cls=MyJson))
76.json序列化时,默认遇到中文会转换成unicode,如果想要保留中文怎么办?
import json
a=json.dumps({"ddf":"你好"},ensure_ascii=False)
print(a) #{"ddf": "你好"}
77.什么是断言?应用场景?
断言条件为真时,代码继续执行,负责抛出异常,这个异常通常不会去捕获他,我们设置一个断言目的就是要求必须实现某个条件。
78.有用过with statement吗?它的好处是什么?
文件操作时使用过,with语句下代码完成后调用求值语句返回对象的__exit__方法,可以实现一些操作,比如关闭文件。
79.使用代码实现查看列举目录下的所有文件。
def print_directory_contents(sPath):
import os
for sChild in os.listdir(sPath):
sChildPath = os.path.join(sPath,sChild)
if os.path.isdir(sChildPath):
print_directory_contents(sChildPath)
else:
print(sChildPath)
80.简述 yield和yield from关键字。
yield:生成器函数关键字
yield from:相当于 for i in obj : yield i
网络编程和并发
1.简述 OSI 七层协议
1、物理层
为数据链路层提供物理连接,实现比特流的透明传输,所传输数据的单位是比特,该层定义了通信设备与传输线接口硬件的电气、机械以及功能和过程的特性。
2、数据链路层
在通信的实体之间建立数据链路连接,传送以帧为单位的数据,通过检查发生在连接通信系统间传送路上的比特错误并进行恢复,确保比特序列组成为数据流准确无误地传送给对方的系统。数据链路层在相邻的节点之间实现透明的高可靠性传输。
3、网络层
解决多节点传送时的路由选择、拥挤控制及网络互连等,控制分组传送系统的操作,它的特性对高层是透明的,同时,根据传输层的要求选择服务质量,并向传输层报告未恢复的差错。
4、传输层
为两个端系统(源站和目标站)的会话层之间建立一条传输连接,可靠、透明地传送报文,执行端一端差错控制、顺序和流量控制、管理多路复用等。本层提供建立、维护和拆除传送连接的功能,并保证网络连接的质量。它向高层屏蔽了下层数据通信的细节,因而是OSI网络参考模型中最需要的一层。
5、会话层
不参与具体的数据传输,但对数据传输的同步进行管理。它主要负责提供两个进程之间建立、维护和结束会话连接功能,同时要对进程中必要的信息传送方式、进程间的同步以及重新同步进行管理。
6、表示层
解决在两个通信系统中交换信息时不同数据格式的编码之间的转换,语法选择,数据加密与解密及文本压缩等。
7、应用层
负责向用户提供各种网络应用服务,如文件传输、电子邮件、远程访问等。把进程中于对方进程通信的部分放入应用实体中,同时,对各种业务内容的通信功能进行管理。
2.什么是C/S和B/S架构?
C/S架构软件:
(即客户机/服务器模式)分为客户机和服务器两层:第一层是在客户机系统上结合了表示与业务逻辑,第二层是通过网络结合了数据库服务器。简单的说就是第一层是用户表示层,第二层是数据库层。客户端和服务器直接相连,这两个组成部分都承担着重要的角色。
B/S型模式:
即浏览器/服务器结构。它是C/S架构的一种改进,可以说属于三层C/S架构。主要是利用了不断成熟的WWW浏览器技术,用通用浏览器就实现了原来需要复杂专用软件才能实现的强大功能,并节约了开发成本,是一种全新的软件系统构造技术。
3.简述 三次握手、四次挥手的流程。
所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发。
第一次握手:
Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
第二次握手:
Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
第三次握手:
Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发
第一次挥手:
Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
第二次挥手:
Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
第三次挥手:
Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
第四次挥手:
Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
4.什么是arp协议?
地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。
5.TCP和UDP的区别?
1.基于连接与无连接
2.TCP要求系统资源较多,UDP较少;
3.UDP程序结构较简单
4.流模式(TCP)与数据报模式(UDP);
5.TCP保证数据正确性,UDP可能丢包
6.TCP保证数据顺序,UDP不保证
6.什么是局域网和广域网?
局域网和广域网是按规模大小而划分的两种计算机网络。范围在几千米以内的计算机网络统称为局域网;而连接的范围超过10千米的,则称为广域网,因特网(Intenet)就是目前最大的广域网。
7.为何基于tcp协议的通信比基于udp协议的通信更可靠?
TCP的可靠保证,是它的三次握手双向机制,这一机制保证校验了数据,保证了他的可靠性。而UDP就没有了,udp信息发出后,不验证是否到达对方,所以不可靠。
8.什么是socket?简述基于tcp协议的套接字通信流程。
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
9.什么是粘包? socket 中造成粘包的原因是什么? 哪些情况会发生粘包现象?
粘包:
指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。出现粘包现象的原因是多方面的,它既可能由发送方造成,也可能由接收方造成。
socket 中造成粘包的原因:
发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。
哪些情况会发生粘包现象:
接收方引起的粘包是由于接收方用户进程不及时接收数据,从而导致粘包现象。这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据。分包是指在出现粘包的时候我们的接收方要进行分包处理。
10.IO多路复用的作用?
I/O多路复用是通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。
11.什么是防火墙以及作用?
简单的来说,防火墙就是一种,避免你的电脑被黑客入侵的一种防护工具,一种确保网络安全的方法!
允许网络管理员定义一个中心点来防止非法用户进入内部网络。2.可以很方便地监视网络的安全性,并报警。3.可以作为部署NAT(Network Address Translation,网络地址变换)的地点,利用NAT技术,将有限的IP地址动态或静态地与内部的IP地址对应起来,用来缓解地址空间短缺的问题等
12.select、poll、epoll 模型的区别?
(1)select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用 epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在 epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的 时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。
(2)select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要 一次拷贝,而且把current往等待队列上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内 部定义的等待队列)。这也能节省不少的开销。
13.简述 进程、线程、协程的区别 以及应用场景?
进程拥有自己的堆和栈,既不共享堆也不共享栈 进程由操作系统调度
线程拥有自己的堆和共享的栈 共享栈 但不共享堆 线程也是由操作系统调度
协程和线程一样有自己的堆和共享的栈 共享栈但不共享堆 协程由开发人员在适当情况调用
14.GIL锁是什么鬼?
GIL:全局解释器锁。当我们用多线程的时候,每一个进程中只有一个GIL锁,那么这多个线程中谁拿到GIL锁,谁即可以用cpu(ps:多个进程有多个Gil锁,但每个进程中只有一个GIL)
15.Python中如何使用线程池和进程池?
进程池:使用multiprocessing.Pool
线程池:使用ThreadPool模块
16.threading.local的作用?
threadLocal解决了参数在一个线程中各个函数之间相互传递的问题
一个threadLocal变量虽然是全局变量,但每个线程都只能读写自己线程的独立副本 互不干扰
17.进程之间如何进行通信?
创建一个queue队列,或使用 from multiprocessing import Manage管理要进行通信的数据
18.什么是并发和并行?
字面理解
并行:好比百米赛跑 枪声一响 运动员都一起向前冲运动员就好比程序 这个过程是并行
并发:是指两个或多个事件在同一时间间隔发生。
19.进程锁和线程锁的作用?
当多进程或多线程是不用进程访问相同一个变量是会造成同一时间执行相同的事 而得不到正确的结果 所以需要用锁锁上这个全局变量,当某一个进程或线程访问时其他进程或线程均无法访问
20.解释什么是异步非阻塞?
异步双方不需要共同的时钟,也就是接收方不知道发送方什么时候发送,所以在发送的信息中就要有提示接收方开始接收的信息,如开始位,同时在结束时有停止位。
非阻塞模式是指利用socket事件的消息机制,Server端与Client端之间的通信处于异步状态。
21.路由器和交换机的区别?
路由器是将信息通过ip转发 交换机是将数据传给下一个
22.什么是域名解析?
域名解析是把域名指向网站空间IP,让人们通过注册的域名可以方便地访问到网站的一种服务
23.如何修改本地hosts文件?
记事本打开C:WindowsSystem32driversetc下的hosts文件进行修改
24.生产者消费者模型应用场景及优势?
应用于一个生产数据一个处理数据的场景
优势生产者和消费者之间不直接进行通信 而是通过一个队列相当于一个缓冲区,平衡了生产者和消费者的处理能力
25.什么是cdn?
尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。
26.LVS是什么及作用?
27.Nginx是什么及作用?
我们可以了解到Nginx是一个http服务器。同效果的http服务器还有Apache、tomcat等
作用:
1、 http服务器。Nginx是一个http服务可以独立提供http服务。可以做网页静态服务器。
2、 虚拟主机。可以实现在一台服务器虚拟出多个网站。例如个人网站使用的虚拟主机。基于端口的,不同的端口基于域名的,不同域名
3、 反向代理,负载均衡。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。
28.keepalived是什么及作用?
29.haproxy是什么以及作用?
30.什么是负载均衡?
负载均衡是高可用网络基础架构的的一个关键组成部分,有了负载均衡,我们通常可以将我们的应用服务器部署多台,然后通过负载均衡将用户的请求分发到不同的服务器用来提高网站、应用、数据库或其他服务的性能以及可靠性。
31.什么是rpc及应用场景?
32.简述 asynio模块的作用和应用场景。
asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。
asyncio的编程模型就是一个消息循环。我们从asyncio模块中直接获取一个EventLoop的引用,然后把需要执行的协程扔到EventLoop中执行,就实现了异步IO。
33.简述 gevent模块的作用和应用场景。
当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。
由于切换是在IO操作时自动完成,所以gevent需要修改Python自带的一些标准库,这一过程在启动时通过monkey patch完成:
34.twisted框架的使用和应用?
Twisted是用Python实现的基于事件驱动的网络引擎框架,Twisted支持许多常见的传输及应用层协议,包括TCP、UDP、SSL/TLS、HTTP、IMAP、SSH、IRC以及FTP。就像Python一样,Twisted也具有“内置电池”(batteries-included)的特点。Twisted对于其支持的所有协议都带有客户端和服务器实现,同时附带有基于命令行的工具,使得配置和部署产品级的Twisted应用变得非常方便。
数据库和缓存
1.列举常见的关系型数据库和非关系型都有那些?
关系型数据库:mysql,oracle,sqlserver,sqlite关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织优点:(1)易于维护:都是使用表结构,格式一致;(2)使用方便:SQL语言通用,可用于复杂查询;(3)复杂操作:支持SQL,可用于一个表以及多个表之间非常复杂的查询。缺点:(1)读写性能比较差,尤其是海量数据的高效率读写;(2)固定的表结构,灵活度稍欠;(3)高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。
非关系型数据库:mongoDB,redis非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合,可以是文档或者键值对等。优点:(1)格式灵活:存储数据的格式可以是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型。(2)速度快:nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘;(3)高扩展性;(4)成本低:nosql数据库部署简单,基本都是开源软件。缺点:(1)不提供sql支持,学习和使用成本较高;(2)无事务处理;(3)数据结构相对复杂,复杂查询方面稍欠。非关系型数据库的分类和比较:(1)文档型,如mongoDB(2)key-value型,如redis(3)列式数据库(4)图形数据库
2.MySQL常见数据库引擎及比较?
InnoDB:支持事务处理,支持外键,支持崩溃修复能力和并发控制。如果需要对事务的完整性要求比较高(比如银行),要求实现并发控制(比如售票),那选择InnoDB有很大的优势。如果需要频繁的更新、删除操作的数据库,也可以选择InnoDB,因为支持事务的提交(commit)和回滚(rollback)。
MyISAM:插入数据快,空间和内存使用比较低。如果表主要是用于插入新记录和读出记录,那么选择MyISAM能实现处理高效率。如果应用的完整性、并发性要求比较低,也可以使用。
MEMORY:所有的数据都在内存中,数据的处理速度快,但是安全性不高。如果需要很快的读写速度,对数据的安全性要求较低,可以选择MEMOEY。它对表的大小有要求,不能建立太大的表。所以,这类数据库只使用在相对较小的数据库表。
注意,同一个数据库也可以使用多种存储引擎的表。如果一个表要求比较高的事务处理,可以选择InnoDB。这个数据库中可以将查询要求比较高的表选择MyISAM存储。如果该数据库需要一个用于查询的临时表,可以选择MEMORY存储引擎。
3.简述数据三大范式?
第一范式:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的关系模式中实现不了。
第二范式:如果关系模式R满足第一范式,并且R得所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。
第三范式:设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF.
# 关系实质上是一张二维表,其中每一行是一个元组,每一列是一个属性
4.什么是事务?MySQL如何支持事务?
原子性、一致性、隔离性、持久性
在mysql中用的最多的存储引擎有:innodb,bdb,myisam ,memory 等。其中innodb和bdb支持事务而myisam等不支持事务。
5.简述数据库设计中一对多和多对多的应用场景?
一对多关系示例:一个学生只属于一个班,但是一个班级有多名学生。
多对多关系示例:一个学生可以选择多门课,一门课也有多名学生。
6.如何基于数据库实现商城商品计数器?
如果是在非常高的并发之下,还是建议用内存数据库redis去实现计数的功能。如果不是那么高的并发,用表实现就可以。
7.常见SQL(必备)
https://www.cnblogs.com/wupeiqi/articles/5729934.html
8.简述触发器、函数、视图、存储过程?
触发器:做数据库操作的时候,还希望相关的数据同步操作就用触发器,比如想要向A表插入数据的时候,同时向B表插入,这样写过触发器每次向A表插入数据之后就会自动向B表插入。
函数:|过程不必返回值|函数必须返回值|过程可以有OUT和IN OUT参数|函数只能有IN参数|过程不可以在SQL语句中调用|某些函数可以在SQL语句中调用
视图:就是一个表或者多个表的一个映射,一般只做查询使用。比如你想要的数据存在两个表里,但你查询时不想每次都写关联,那么你创建一个视图,以后只查询这个视图就可以(查询时视图与查询表语法一样)。
存储过程:这个一般是沉淀数据使用的,当你需要查询的数据不能用一个sql语句查出或者sql语句查询速度特别慢,想要提高效率,就会用到存储过程,先把需要的数据沉淀到结果表里然后直接查询结果表就能提高效率。
9.MySQL索引种类
1.普通索引2.唯一索引3.主键索引4.组合索引5.全文索引
10.索引在什么情况下遵循最左前缀的规则?
最左前缀原理的一部分,索引index1:(a,b,c),只会走a、a,b、a,b,c 三种类型的查询,其实这里说的有一点问题,a,c也走,但是只走a字段索引,不会走c字段。
索引是有序的,index1索引在索引文件中的排列是有序的,首先根据a来排序,然后才是根据b来排序,最后是根据c来排序,
11.主键和外键的区别?
主键:唯一标识一条记录,不能有重复的,不允许为空
外键:表的外键是另一表的主键, 外键可以有重复的, 可以是空值
12.MySQL常见的函数?
sum,abs,floor
13.列举 创建索引但是无法命中索引的8种情况。
一:索引本身出现问题
1.索引本身失效
2.没有查询条件,或者查询条件没有建立索引
3.在查询条件上没有使用引导列
4.对小表查询
5.查询的数量是大表中的大部分数据。
二:受查询条件的影响
1.对列使用函数,该列的索引将不起作用。
2.对列进行运算(加减乘除号)该列的索引将不起作用。
3.某些情况下的LIKE操作,该列的索引将不起作用。
4.某些情况使用反向操作,该列的索引将不起作用。
5.在WHERE中使用OR时,有一个列没有索引,那么其它列的索引将不起作用
6.隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误
7.使用not in ,not exist等语句时
8.当变量采用的是times变量,而表的字段采用的是date变量时.或相反情况。
9.当B-tree索引 is null不会失效,使用is not null时,会失效,位图索引 is null,is not null 都会失效
10.联合索引 is not null 只要在建立的索引列(不分先后)都会失效,in null时 必须要和建立索引第一列一起使用,当建立索引第一位置条件是is null 时,其他建立索引的列可以是is null(但必须在所有列 都满足is null的时候),或者 = 一个值;当建立索引的第一位置是 = 一个值时,其他索引列可以是任何情况(包括is null = 一个值),以上两种情况索引都会失效,其他情况不会失效。
14.如何开启慢日志查询?
slow_query_log =1
slow_query_log_file=/application/mysql/data/localhost-slow.log
long_query_time = 1
15.数据库导入导出命令(结构+数据)?
https://www.cnblogs.com/doudouxiaoye/p/5819607.html
16.数据库优化方案?
https://blog.csdn.net/q602075961/article/details/71076390
17.char和varchar的区别?
char不可变字段,varchar是可变字段
18.简述MySQL的执行计划?
MySql提供了EXPLAIN语法用来进行查询分析,在SQL语句前加一个"EXPLAIN"即可
19在对name做了唯一索引前提下,简述以下区别:
select * from tb where name = ‘Oldboy-Wupeiqi’
select * from tb where name = ‘Oldboy-Wupeiqi’ limit 1
过滤出数据的同时,进行计数
20.1000w条数据,使用limit offset 分页时,为什么越往后翻越慢?如何解决?
先查主键,在分页。 select * from tb where id in(select id from tb where limit 10 offset 20)
21.什么是索引合并?
索引合并,让一条sql可以使用多个索引。对这些索引取交集,并集,或者先取交集再取并集。从而减少从数据表中取数据的次数,提高查询效率。
22.什么是覆盖索引?
如果一个索引包含(或覆盖)所有需要查询的字段的值,称为‘覆盖索引’
23.简述数据库读写分离?
主服务器master记录数据库操作日志到Binary log,从服务器开启i/o线程将二进制日志记录的操作同步到relay log(存在从服务器的缓存中),另外sql线程将relay log日志记录的操作在从服务器执行。
24.简述数据库分库分表?(水平、垂直)
1.数据库分表
把一张表按照一定的规则分解成不同的实体表。比如垂直划分和水平划分 垂直切分:把不同功能,不同模块的数据分别放到不同的表中,但是如果同一个模块的数据量太大就会存在性能瓶颈水平切分:垂直切分解决不了大表的瓶颈,如果同一个功能中表的数据量过大,就要对该表进行切分,为水平切分通俗理解:垂直切分---分不同的模块表;水平切分---分同一个模块下的多个表
2.分库
将一堆数据放到不同的数据库中保存,上面说的都是在同一个数据库上,分库是分到不同的数据库上
25.redis和memcached比较?
(1) Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。
(2)Redis支持数据的备份,即master-slave模式的数据备份。
(3)Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
26.redis中数据库默认是多少个db 及作用?
当redis 服务器初始化时,会预先分配 16 个数据库(该数量可以通过配置文件配置),所有数据库保存到结构 redisServer 的一个成员 redisServer.db 数组中。当我们选择数据库 select number 时,程序直接通过 redisServer.db[number] 来切换数据库。有时候当程序需要知道自己是在哪个数据库时,直接读取 redisDb.id 即可。
27.python操作redis的模块?
28.如果redis中的某个列表中的数据量非常大,如果实现循环显示每一个值?
可以尝试将对象分拆成几个key-value, 使用multiGet获取值,这样分拆的意义在于分拆单次操作的压力,将操作压力平摊到多个redis实例中,降低对单个redis的IO影响。
29.redis如何实现主从复制?以及数据同步机制?
Redis的主从同步机制可以确保redis的master和slave之间的数据同步
全备份过程中,在slave启动时,会向其master发送一条SYNC消息,master收到slave的这条消息之后,将可能启动后台进程进行备份,备份完成之后就将备份的数据发送给slave
30.redis中的sentinel的作用?
用于监控redis集群中Master状态的工具
31.如何实现redis集群?
Redis集群设计包括2部分:哈希Slot和节点主从
主从模式的设计:
优点:读写分离,通过增加Slaver可以提高并发读的能力。缺点:Master写能力是瓶颈。
虽然理论上对Slaver没有限制但是维护Slaver开销总将会变成瓶颈。
Master的Disk大小也将会成为整个Redis集群存储容量的瓶颈。
哈希Slot的优缺点:
缺点:每个Node承担着互相监听、高并发数据写入、高并发数据读出,工作任务繁重
优点:将Redis的写操作分摊到了多个节点上,提高写的并发能力,扩容简单。
32.redis中默认有多少个哈希槽?
16384 个哈希槽
33.简述redis的有哪几种持久化策略及比较?
rdb:快照形式是直接把内存中的数据保存到一个dump文件中,定时保存,保存策略
aof:把所有的对redis的服务器进行修改的命令都存到一个文件里,命令的集合
34列举redis支持的过期策略。
volatile-lru:只对设置了过期时间的key进行LRU(默认值)
allkeys-lru : 删除lru算法的key
volatile-random:随机删除即将过期key
allkeys-random:随机删除
volatile-ttl : 删除即将过期的
noeviction : 永不过期,返回错误
35.MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 中都是热点数据?
redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:
(1)volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
(2)volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
(3)volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
(4)allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
(5)allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
(6)no-enviction(驱逐):禁止驱逐数据
36.写代码,基于redis的列表实现 先进先出、后进先出队列、优先级队列。
请求的优先级。我们先假设一个最简单的场景,有三个优先级:高中低三级。可以设置3个list结构,比如叫queue_h,queue_m,queue_l,分别对应三个优先级。
37.如何基于redis实现消息队列?
使用lpush向list的左端推送数据(发送消息),使用rpop从右端接收数据(消费消息)
38.如何基于redis实现发布和订阅?以及发布订阅和消息队列的区别?
“发布/订阅”模式包含两种角色,分别是发布者和订阅者。订阅者可以订阅一个或若干个频道(channel),而发布者可以向指定的频道发送消息,所有订阅此频道的订阅者都会收到此消息。
39.什么是codis及作用?
Codis是一个分布式的Redis解决方案,对于上层的应用来说,连接Codis Proxy和连接原生的Redis Server没有明显的区别,上层应用可以像使用单机的Redis一样使用,Codis底层会处理请求的转发,不停机的数据迁移等工作,所有后边的一切事情,对于前面客户端来说是透明的,可以简单的认为后边连接是一个内存无限大的Redis服务。
业务需要,数据可能需要迁移,机器横向扩容
经过线上测试,Codis的升级版Reborn在pipline操作的性能比Codis慢了几十倍
40.什么是twemproxy及作用?
twemproxy是 Twtter 开源的一个 Redis 和 Memcache 代理服务器,主要用于管理 Redis 和 Memcached 集群,减少与Cache 服务器直接连接的数量。
41.写代码实现redis事务操作。
Redis会将一个事务中的所有命令序列化,然后按顺序执行
42.redis中的watch的命令的作用?
当某个事务需要按条件执行时,就要使用这个命令将给定的键设置为受监控的