程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2023-05(1)

2023-06(2)

python面试题练习

发布于2019-08-03 09:09     阅读(4975)     评论(0)     点赞(11)     收藏(10)


1、一行代码实现 1--100 之和

In [10]: sum(range(101))
Out[10]: 5050

sum() 方法对系列进行求和计算。sum函数的参数必须是可迭代的对象

range() 函数可创建一个整数列表,一般用在 for 循环中。

2、如何在一个函数内部修改全局变量

利用 global 修改全局变量

3、列出 5 个 python 标准库

os:提供了不少与操作系统相关联的函数
sys: 通常用于命令行参数

time:时间模块
re: 正则匹配
math: 数学运算
datetime:处理日期时间

4、字典如何删除键和合并两个字典

字典删除键的方法有pop和del两个

 

pop和del方法删除字典的键,如果键不存在都会报错

 

update方法用来合并字典

 4、谈下 python 的 GIL

GIL 是 python 的全局解释器锁,同一进程中假如有多个线程运行,一个线程在运行 python 程序的时候会霸占 python 解释器(加了一把锁即 GIL),使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时操作,则解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。多进程中因为每个进程都能被系统分配资源,相当于每个进程有了一个 python 解释器,所以多进程可以实现多个进程的同时运行,缺点是进程系统资源开销大。

5、说明一下 os.path 和 sys.path 分别代表什么?

os.path 主要是用于对系统路径文件的操作。

sys.path 主要是对 Python 解释器的系统环境参数的操作(动态的改变 Python 解释器搜索路径)。

6、模块和包是什么?

在 Python 中,模块是搭建程序的一种方式。每一个 Python 代码文件都是一个模块,并可以引用其他的模块,比如对象和属性。

一个包含许多 Python 代码的文件夹是一个包。一个包可以包含模块和子文件夹。

7、谈一下什么是解释性语言,什么是编译性语言?

计算机不能直接理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序。

解释性语言在运行程序的时候才会进行翻译。

编译型语言写的程序在执行之前,需要一个专门的编译过程,把程序编译成机器语言(可执行文件)。编译型语言写的程序在执行之前,需要一个专门的编译过程,把程序编译成机器语言(可执行文件)。

8、关于 Python 程序的运行方面,有什么手段能提升性能?

1、使用多进程,充分利用机器的多核性能

2、对于性能影响较大的部分代码,可以使用 C 或 C++编写

3、对于 IO 阻塞造成的性能影响,可以使用 IO 多路复用来解决

4、尽量使用 Python 的内建函数

5、尽量使用局部变量

9、说一下字典和 json 的区别?

 字典是一种数据结构,json 是一种数据的表现形式,字典的 key 值只要是能 hash 的就行,json 的必须是字符串。json的key必须是双引号,python的字典不需要,单引号也可以

10、什么是可变、不可变类型?

可变不可变指的是内存中的值是否可以被改变,不可变类型指的是对象所在内存块里面的值不可以改变,有数值、字符串、元组;可变类型则是可以改变,主要有列表、字典。

11、请反转字符串"hello world!"

print("hello world!"[::-1])

12、将字符串"k:1|k1:2|k2:3|k3:4",处理成 Python 字典:{k:1, k1:2, ... } # 字典里的 K 作为字符串处理

t_str = "k:1|k1:2|k2:3|k3:4"
t_dict = {i.split(":")[0]:int(i.split(":")[1]) for i in t_str.split("|")}
print(t_dict)
# 输出结果  {'k1': 2, 'k': 1, 'k2': 3, 'k3': 4}

13、写一个列表生成式,产生一个公差为 11 的等差数列

print([i*10 for i in range(10)])
# 输出结果  [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

 14、Python 里面如何生成随机数?

答:random 模块

随机整数:random.randint(a,b):返回随机整数 x,a<=x<=b

random.randrange(start,stop,[,step]):返回一个范围在(start,stop,step)之间的随机整数,不包括结束值。

随机实数:random.random( ):返回 0 到 1 之间的浮点数

random.uniform(a,b):返回指定范围内的浮点数。

15、单引号,双引号,三引号的区别

单引号和双引号是等效的,如果要换行,需要符号(\),三引号则可以直接换行,并且可以包含注释

16、有如下数组 t_list = range(10)我想取以下几个数组,应该如何切片?

1. [1,2,3,4,5,6,7,8,9]
2. [1,2,3,4,5,6]
3. [3,4,5,6]
4. [9]
5. [1,3,5,7,9]

解决方法

print([i for i in t_list[1:]])
# 输出结果 [1, 2, 3, 4, 5, 6, 7, 8, 9]

print([i for i in t_list[1:7]])
# 输出结果 [1, 2, 3, 4, 5, 6]

print([i for i in t_list[3:7]])
# 输出结果 [3, 4, 5, 6]

print([i for i in t_list[9:]])
# 输出结果 [9]

print([i for i in t_list[1::2]])
# 输出结果 [1, 3, 5, 7, 9]

Python 高级

1、Python 中类方法、类实例方法、静态方法有何区别?

类方法:是类对象的方法,在定义时需要在上方使用@classmethod进行装饰,形参为 cls,表示类对象,类对象和实例对象都可调用;

类实例方法:是类实例化对象的方法,只有实例对象可以调用,形参为self,指代对象本身;

静态方法:是一个任意函数,在其上方使用@staticmethod进行装饰,可以用对象直接调用,静态方法实际上跟该类没有太大关系。 

2. Python 的内存管理机制及调优手段?

可以到这里查看具体内容https://www.cnblogs.com/geaozhang/p/7111961.html

内存管理机制:引用计数、垃圾回收、内存池。 

引用计数:

引用计数是一种非常高效的内存管理手段,当一个python对象被引用时,它的引用计数增加1,当它不再被一个变量引用时则引用计数减1,当它的引用计数等于0时对象被删除

垃圾回收:

  当Python的某个对象的引用计数降为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾。比如某个新建对象,被分配给某个引用,对象的引用计数变为1。如果引用被删除,对象的引用计数为0,那么该对象就可以被垃圾回收。

  内存池:

  1. Python 的内存机制呈现金字塔形状,-1,-2 层主要有操作系统进行操作;
  2. 第 0 层是 C 中的 malloc,free 等内存分配和释放函数进行操作;
  3. 第 1 层和第 2 层是内存池,有 Python 的接口函数 PyMem_Malloc 函数实现,当对象小于256K 时有该层直接分配内存;
  4. 第 3 层是最上层,也就是我们对 Python 对象的直接操作;

  Python 在运行期间会大量地执行 malloc 和 free 的操作,频繁地在用户态和核心态之间进行切换,这将严重影响 Python 的执行效率。为了加速 Python 的执行效率,Python 引入了一个内存池机制,用于管理对小块内存的申请和释放。

  Python 内部默认的小块内存与大块内存的分界点定在 256 个字节,当申请的内存小于 256 字节时,PyObject_Malloc 会在内存池中申请内存;当申请的内存大于 256 字节时,PyObject_Malloc 的行为将蜕化为 malloc 的行为。当然,通过修改 Python 源代码,我们可以改变这个默认值,从而改变 Python 的默认内存管理行为。

调优手段:

1.手动垃圾回收

2.调高垃圾回收阈值

3.避免循环引用(手动解循环引用和使用弱引用)

3、内存泄露是什么?如何避免?

  指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。导致程序运行速度减慢甚至系统崩溃等严重后果。

  有__del__() 函数的对象间的循环引用是导致内存泄漏的主凶。

  不使用一个对象时使用:del object 来删除一个对象的引用计数就可以有效防止内存泄漏问题。通过 Python 扩展模块 gc 来查看不能回收的对象的详细信息。

  可以通过 sys.getrefcount(obj) 来获取对象的引用计数,并根据返回值是否为 0 来判断是否内存泄漏。

 4、Python 函数调用的时候参数的传递方式是值传递还是引用传递?

  Python 的参数传递有:位置参数、默认参数、可变参数、关键字参数

 

  函数的传值到底是值传递还是引用传递,要分情况:

  不可变参数用值传递

    像整数和字符串这样的不可变对象,是通过拷贝进行传递的,因为你无论如何都不可能在原处改变不可变对象

 

  可变参数是引用传递的

 

    比如像列表,字典这样的对象是通过引用传递、和 C 语言里面的用指针传递数组很相似,可变对象能在函数内部改变。

5、对缺省参数的理解

  缺省参数指在调用函数的时候没有传入参数的情况下,调用默认的参数,在调用函数的同时赋值时, 所传入的参数会替代默认参数。

  *args 是不定长参数,他可以表示输入参数是不确定的,可以是任意多个。

  **kwargs 是关键字参数,赋值的时候是以键 = 值的方式,参数是可以任意多对在定义函数的时候不确定会有多少参数会传入时,就可以使用两个参数。

6、递归函数停止的条件?

递归的终止条件一般定义在递归函数内部,在递归调用前要做一个条件判断,根据判断的结果选择是继续调用自身,还是 return;返回终止递归。

终止的条件:

判断递归的次数是否达到某一限定值

判断运算的结果是否达到某个范围等,根据设计的目的来选择

一个简单的递归函数的例子

def p_num(num):
    if num > 0:
        print(num)
        p_num(num - 1)

p_num(4)

# 输出结果
4
3
2
1

7、Python 主要的内置数据类型都有哪些? print(dir("a"))的输出?

python的数据类型有

int 整型、bool 布尔、str 字符串、list 列表、tuple 元组、dict 字典、float 浮点型小数

print(dir("a"))的输出是

['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

输出字符串‘a’的内建方法;

8、hasattr() getattr() setattr() 函数使用详解?

class Person():

    def __init__(self):
        self.name = "hahah"
        self.age = 24

    def eat(self):
        print("正在吃饭")

p1 = Person()

hasattr(object, name)函数:

判断一个对象里面是否有name 属性或者name 方法,返回bool 值,有name 属性(方法)返回True, 否则返回 False。

注意:name 要使用引号括起来

print(hasattr(p1, "eat"))  # 输出结果 True
print(hasattr(p1, "name"))  # 输出结果 True
print(hasattr(p1, "age"))  # 输出结果 True

# 输入一个不存在的属性名或者方法名,就会返回False
print(hasattr(p1, "aname"))  # 输出结果 False
print(hasattr(p1, "aage"))  # 输出结果 False
print(hasattr(p1, "aeat"))  # 输出结果 False

getattr(object, name[,default]) 函数:

获取对象 object 的属性或者方法,如果存在则打印出来,如果不存在,打印默认值,默认值可选。注意:如果返回的是对象的方法,则打印结果是:方法的内存地址,如果需要运行这个方法,可以在后面添加括号()。

print(getattr(p1,"name"))  # 输出name属性的值"hahah"
print(getattr(p1,"age"))  # 输出age属性的值24

# 如果获取的是方法,返回的就是这个方法的内存地址
print(getattr(p1,"eat"))
# <bound method Person.eat of <__main__.Person object at 0x7fd87e2d29e8>>

# 如果获取的方法或者属性不存在,会报错
print(getattr(p1,"nameasdasd"))

# Traceback (most recent call last):
#   File "/home/fengwr/Desktop/code/spider/lx.py", line 40, in <module>
#     print(getattr(p1,"nameasdasd"))
# AttributeError: 'Person' object has no attribute 'nameasdasd'

# 如果属性或方法不存在,设置默认值
print(getattr(p1,"nameasdasd", "默认内容"))
# 输出"默认内容"

setattr(object,name,values)函数:
给对象的属性赋值,若属性不存在,先创建再赋值

setattr(p1, "height", 178.56)
print(p1.height)
# 输出结果 178.56

 9、解释一下什么是闭包?

 在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包。

10.Python 中 is 和==的区别?

is 判断的是 a 对象是否就是 b 对象,是通过 id 来判断的。
==判断的是 a 对象的值是否和 b 对象的值相等,是通过 来判断的。

11、python中的私有属性和私有方法

以两个下划线开头的属性和方法称为私有属性和私有方法,但是也可通过特定的方法来访问,所以python中是伪私有属性和伪私有方法

访问私有属性和私有方法

_类名__属性名

_类名__方法名()

12、面向对象中怎么实现只读属性?

class Demo1():
    __name = "小明"

    @property
    def name(self):
        return self.__name

if __name__ == '__main__':
    d1 = Demo1()
    print(d1.name)  # 输出小明
    d1.name = "小红"  #报错
    print(d1.name)

会报如下错误

Traceback (most recent call last):
  File "C:/Users/fengwr/Desktop/demo/lx01.py", line 11, in <module>
    d1.name = "小红"
AttributeError: can't set attribute

不能设置属性。

就是用property装饰器把方法变成了类的属性

这样就实现了只读属性

13、谈谈你对面向对象的理解?

面向对象是相对于面向过程而言的。面向过程语言是一种基于功能分析的、以算法为中心的程序设计方法;而面向对象是一种基于结构分析的、以数据为中心的程序设计思想。在面向对象语言中有一个有很重要东西,叫做类。

面向对象有三大特性:封装、继承、多态

14、Python 里 match 与 search 的区别?

match()函数只检测 RE 是不是在 string 的开始位置匹配,search()会扫描整个 string 查找匹配;

也就是说 match()只有在 0 位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回 none。

import re

a = "hello world"
print(re.match("hell", a))  # 输出<_sre.SRE_Match object; span=(0, 4), match='hell'>
print(re.match("ell", a))  # 输出 None
print(re.search("ell", a))  # 输出<_sre.SRE_Match object; span=(1, 4), match='ell'>

15、Python 字符串查找和替换?

import re

a = "hello world"
# re.findall(r'目的字符串', 原有字符串),返回一个列表
print(re.findall(r'llo', a))   # 输出['llo']
# re.sub(r'要替换的原字符', '要替换的新字符', '原始字符串'),返回字符串
print(re.sub(r'hello', 'goodnight', a))  # 输出goodnight world

16、用 Python 匹配 HTML标签的时候,<.*> 和 <.*?> 有什么区别?

<.*>是贪婪匹配,会从第一个“ <”开始匹配,直到最后一个“ >”中间所有的字符都会匹配到,中间可能会包含“ <>”。

<.*?>是非贪婪匹配,从第一个“ <”开始往后,遇到第一个“ >”结束匹配,这中间的字符串都会匹配到,但是不会有“ <>”。 

17、谈谈你对多进程,多线程,以及协程的理解,项目是否用? 

进程:一个运行的程序(代码)就是一个进程,没有运行的代码叫程序,进程是系统资源分配的最小单位,进程拥有自己独立的内存空间,所以进程间数据不共享,开销大。

线程: 调度执行的最小单位,也叫执行路径,不能独立存在,依赖进程存在一个进程至少有一个线程,叫主线程,而多个线程共享内存(数据共享,共享全局变量),从而极大地提高了程序的运行效率。

协程:是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。 协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。 

18、什么是多线程竞争?

线程是非独立的,同一个进程里线程是数据共享的,当各个线程访问数据资源时会出现竞争状态即:数据几乎同步会被多个线程占用,造成数据混乱 ,即所谓的线程不安全
那么怎么解决多线程竞争问题?--
锁的好处:
确保了某段关键代码(共享数据资源)只能由一个线程从头到尾完整地执行能解决多线程资源竞争下的原子操作问题。
锁的坏处:
阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了锁的致命问题:死锁。

19、什么是死锁?

若干子线程在系统资源竞争时,都在等待对方对某部分资源解除占用状态,结果是谁也不愿先解锁,互相干等着,程序无法执行下去,这就是死锁。

20、GIL 锁 全局解释器锁(只在 cpython 里才有)

作用:限制多线程同时执行,保证同一时间只有一个线程执行,所以 cpython 里的多线程其实是伪多线程!
所以 Python 里常常使用协程技术来代替多线程,协程是一种更轻量级的线程,
进程和线程的切换时由系统决定,而协程由我们程序员自己决定,而模块 gevent 下切换是遇到了耗时操作才会切换。
三者的关系:进程里有线程,线程里有协程

21、什么是线程安全,什么是互斥锁?

每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
同一个进程中的多线程之间是共享系统资源的,多个线程同时对一个对象进行操作,一个线程操作尚未结束,另一个线程已经对其进行操作,导致最终结果出现错误,此时需要对被操作对象添加互斥锁,保证每个线程对该对象的操作都得到正确的结果。

22、说说下面几个概念:同步,异步,阻塞,非阻塞?

同步:多个任务之间有先后顺序执行,一个执行完下个才能执行。
异步:多个任务之间没有先后顺序,可以同时执行有时候一个任务可能要在必要的时候获取另一个
同时执行的任务的结果,这个就叫回调!
阻塞:如果卡住了调用者,调用者不能继续往下执行,就是说调用者阻塞了。
非阻塞:如果不会卡住,可以继续执行,就是说非阻塞的。
同步异步相对于多任务而言,阻塞非阻塞相对于代码执行而言。

23、什么是僵尸进程和孤儿进程?怎么避免僵尸进程?

孤儿进程:父进程退出,子进程还在运行的这些子进程都是孤儿进程,孤儿进程将被 init 进程(进程号为 1)所收养,并由 init 进程对它们完成状态收集工作。
僵尸进程:进程使用 fork 创建子进程,如果子进程退出,而父进程并没有调用 wait 或 waitpid 获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中的这些进程是僵尸进程。
避免僵尸进程的方法:
1.fork 两次用孙子进程去完成子进程的任务;
2.用 wait()函数使父进程阻塞;
3.使用信号量,在 signal handler 中调用 waitpid,这样父进程不用阻塞。

24、Python 中的进程与线程的使用场景? 

多进程适合在 CPU 密集型操作(cpu 操作指令比较多,如位数多的浮点运算)。
多线程适合在 IO 密集型操作(读写数据操作较多的,比如爬虫)。

25、线程是并发还是并行,进程是并发还是并行?

线程是并发,进程是并行;
进程之间相互独立,是系统分配资源的最小单位,同一个线程中的所有线程共享资源。

26、并行(parallel)和并发(concurrency)?

并行:同一时刻多个任务同时在运行。
并发:在同一时间间隔内多个任务都在运行,但是并不会在同一时刻同时运行,存在交替执行的情况。
实现并行的库有:multiprocessing
实现并发的库有:threading
程序需要执行较多的读写、请求和回复任务的需要大量的 IO 操作,IO 密集型操作使用并发更好。
CPU 运算量大的程序程序,使用并行会更好。

27、IO 密集型和 CPU 密集型区别?

IO 密集型:系统运作,大部分的状况是 CPU 在等 I/O (硬盘/内存)的读/写。
CPU 密集型:大部份时间用来做计算、逻辑判断等 CPU 动作的程序称之 CPU 密集型。

28、简述 TCP 和 UDP 的区别以及优缺点?

UDP 是面向无连接的通讯协议,UDP 数据包括目的端口号和源端口号信息。
优点:UDP 速度快、操作简单、要求系统资源较少,由于通讯不需要连接,可以实现广播发送
缺点:UDP 传送数据前并不与对方建立连接,对接收到的数据也不发送确认信号,发送端不知道数据是否会正确接收,也不重复发送,不可靠。
TCP 是面向连接的通讯协议,通过三次握手建立连接,通讯完成时四次挥手
优点:TCP 在数据传递时,有确认、窗口、重传、阻塞等控制机制,能保证数据正确性,较为可靠。
缺点:TCP 相对于 UDP 速度慢一点,要求系统资源较多。

29、描述用浏览器访问 www.baidu.com 的过程

先要解析出 baidu.com 对应的 ip 地址

  • 要先使用 arp 获取默认网关的 mac 地址
  • 组织数据发送给默认网关(ip 还是 dns 服务器的 ip,但是 mac 地址是默认网关的 mac 地址)
  • 默认网关拥有转发数据的能力,把数据转发给路由器
  • 路由器根据自己的路由协议,来选择一个合适的较快的路径转发数据给目的网关
  • 目的网关(dns 服务器所在的网关),把数据转发给 dns 服务器
  • dns 服务器查询解析出 baidu.com 对应的 ip 地址,并原路返回请求这个域名的 client 得到了 baidu.com 对应的 ip 地址之后,会发送 tcp 次握手,进行连接
  • 使用 http 协议发送请求数据给 web 服务器
  • web 服务器收到数据请求之后,通过查询自己的服务器得到相应的结果,原路返回给浏览器。
  • 浏览器接收到数据之后通过浏览器自己的渲染功能来显示这个网页。
  • 浏览器关闭 tcp 连接,即次挥手结束,完成整个访问过程

30、Post Get 请求的区别

GET 请求,请求的数据会附加在 URL 之后,以?分割 URL 和传输数据,多个参数用&连接。URL 编码格式采用的是 ASCII 编码,而不是 uniclde,即是说所有的非 ASCII 字符都要编码之后再传输。

POST 请求:POST 请求会把请求的数据放置在 HTTP 请求包的包体中。上面的 item=bandsaw 就是实际的传输数据。

因此,GET 请求的数据会暴露在地址栏中,而 POST 请求则不会。传输数据的大小:

  • HTTP 规范中,没有对 URL 的长度和传输的数据大小进行限制。但是在实际开发过程中,对 GET,特定的浏览器和服务器对 URL 的长度有限制。因此,在使用 GET 请求时,传输数据会受到 URL 长度的限制。
  • 对于 POST,由于不是 URL 传值,理论上是不会受限制的,但是实际上各个服务器会规定对 POST 提交数据大小进行限制,Apache、IIS 都有各自的配置。

安全性:

  • POST 的安全性比 GET 的高。这里的安全是指真正的安全,而不同于上面 GET 提到的安全方法中的安全,上面提到的安全仅仅是不修改服务器的数据。比如,在进行登录操作,通过 GET 请求, 用户名和密码都会暴露再 URL 上,因为登录页面有可能被浏览器缓存以及其他人查看浏览器的

历史记录的原因,此时的用户名和密码就很容易被他人拿到了。除此之外,GET 请求提交的数据还可能会造成 Cross-site request frogery 攻击。

效率:GET 比 POST 效率高。

POST 请求的过程:

  1. 浏览器请求 tcp 连接(第一次握手)
  2. 服务器答应进行 tcp 连接(第二次握手)
  3. 浏览器确认,并发送 post 请求头第三次握手,这个报文比较小,所以 http 会在此时进行第一次数据发送)
    1. 服务器返回 100 continue 响应
    2. 浏览器开始发送数据
    3. 服务器返回 200 ok 响应

GET 请求的过程:

  1. 浏览器请求 tcp 连接(第一次握手)
  2. 服务器答应进行 tcp 连接(第二次握手)
  3. 浏览器确认,并发送 get 请求头和数据第三次握手,这个报文比较小,所以 http 会在此时进行第一次数据发送)

服务器返回 200 OK 响应

31、cookie session 的区别?

1、cookie 数据存放在客户的浏览器上,session 数据放在服务器上。

2、cookie 不是很安全,别人可以分析存放在本地的 cookie 并进行 cookie 欺骗考虑到安全应当使 session。

 

3、session 会在一定时间内保存在服务器上。当访问增多,会比较占用服务器的性能考虑到减轻服务器性能方面,应当使用 cookie。

4、单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie。

5、建议: 将登陆信息等重要信息存放为 SESSION 其他信息如果需要保留,可以放在 cookie 中

32、请简单说一下三次握手和四次挥手?

三次握手过程:

首先客户端向服务端发送一个带有 SYN 标志,以及随机生成的序号 100(0 字节)的报文

服务端收到报文后返回一个报文(SYN200(0 字节),ACk1001(字节+1))给客户端

客户端再次发送带有 ACk 标志 201(字节+)序号的报文给服务端至此三次握手过程结束,客户端开始向服务端发送数据。

 

1 客户端向服务端发起请求:我想给你通信,你准备好了么?

服务端收到请求后回应客户端:I'ok,你准备好了么

3 客户端礼貌的再次回一下客户端:准备就绪,咱们开始通信吧!

整个过程跟打电话的过程一模一样:1 喂,你在吗在,我说的你听得到不恩,听得到(接下来请开始你的表演)

补充:SYN:请求询问,ACk:回复,回应。

四次挥手过程:

由于 TCP 连接是可以双向通信的(全双工),因此每个方向都必须单独进行关闭(这句话才是精辟,后面四个挥手过程都是其具体实现的语言描述)

四次挥手过程,客户端和服务端都可以先开始断开连接

客户端发送带有 fin 标识的报文给服务端,请求通信关闭

服务端收到信息后,回复 ACK 答应关闭客户端通信(连接)请求

服务端发送带有 fin 标识的报文给客户端,也请求关闭通信

客户端回应 ack 给服务端,答应关闭服务端的通信(连接)请求

33、说说 HTTP 和HTTPS 区别?

HTTP 协议传输的数据都是未加密的,也就是明文的,因此使用 HTTP 协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了 SSL(Secure Sockets Layer)协议用于 HTTP 协议传输的数据进行加密,从而就诞生了 HTTPS。简单来说,HTTPS 协议是由 SSL+HTTP 议构建的可进行加密传输、身份认证的网络协议,要比 http 协议安全。

HTTPS 和 HTTP 的区别主要如下:

1、https 协议需要到 ca 申请证书,一般免费证书较少,因而需要一定费用。

2、http 是超文本传输协议,信息是明文传输,https 则是具有安全性的 ssl 加密传输协议。

3、http  https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。

4、http 的连接很简单,是无状态的;HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全。

34、HTTP 常见请求头

 

Host (主机和端口号)

Connection (链接类型)

Upgrade-Insecure-Requests (升级为 HTTPS 请求)

User-Agent (浏览器名称)

Accept (传输文件类型)

Referer (页面跳转处)

Accept-Encoding(文件编解码格式)

Cookie (Cookie)

x-requested-with :XMLHttpRequest ( Ajax 异步请求)

35、七层模型? IP ,TCP/UDP ,HTTP ,RTSP ,FTP 分别在哪层?

应用层,表示层,会话层,传输层,网络层,数据链路层,物理层

IP 网络层

TCP/UDP 传输层

HTTP、RTSP、FTP 应用层协议

36、Python2和Python3的区别

1. Python3 对 Unicode 字符的原生支持。 

Python2 中使用 ASCII 码作为默认编码方式导致 string 有两种类型 str 和 unicode,Python3 只支持 unicode 的 string。 

2. Python3 采用的是绝对路径的方式进行 import
3. Python2 中存在老式类和新式类的区别, Python3 统一采用新式类。新式类声明要求继承 object,必须用新式类应用多重继承。

4. Python3 使用更加严格的缩进。

Python2 的缩进机制中,1 个 tab 和 8 个 space 是等价的,所以在缩进中可以同时允许 tab 和 space 在代码中共存。这种等价机制会导致部分 IDE 使用存在问题。Python3 中 1 个 tab 只能找另外一个 tab 替代,因此 tab 和 space 共存会导致报错:TabError:inconsistent use of tabs and spaces in indentation.

1. print 语句被 Python3 废弃,统一使用 print 函数
2. exec 语句被 python3 废弃,统一使用 exec 函数
3. execfile 语句被 Python3 废弃,推荐使用 exec(open("./filename").read())
4. 不相等操作符"<>"被 Python3 废弃,统一使用"!="
5. long 整数类型被 Python3 废弃,统一使用 int
6. xrange 函数被 Python3 废弃,统一使用 range,Python3 中 range 的机制也进行修改并提高了大数据集生成效率



所属网站分类: 技术文章 > 博客

作者:heer

链接:https://www.pythonheidong.com/blog/article/3834/52528d1424b3743a04e4/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

11 0
收藏该文
已收藏

评论内容:(最多支持255个字符)