python面試題練習

一、一行代碼實現 1--100 之和

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

sum() 方法對系列進行求和計算。sum函數的參數必須是可迭代的對象html

range() 函數可建立一個整數列表,通常用在 for 循環中。python

二、如何在一個函數內部修改全局變量

利用 global 修改全局變量git

三、列出 5 個 python 標準庫

os:提供了很多與操做系統相關聯的函數
sys: 一般用於命令行參數程序員

time:時間模塊
re: 正則匹配
math: 數學運算
datetime:處理日期時間web

四、字典如何刪除鍵和合並兩個字典

字典刪除鍵的方法有pop和del兩個算法

 

pop和del方法刪除字典的鍵,若是鍵不存在都會報錯json

 

update方法用來合併字典api

 四、談下 python 的 GIL

GIL 是 python 的全局解釋器鎖,同一進程中假若有多個線程運行,一個線程在運行 python 程序的時候會霸佔 python 解釋器(加了一把鎖即 GIL),使該進程內的其餘線程沒法運行,等該線程運行完後其餘線程才能運行。若是線程運行過程當中遇到耗時操做,則解釋器鎖解開,使其餘線程運行。因此在多線程中,線程的運行還是有前後順序的,並非同時進行。多進程中由於每一個進程都能被系統分配資源,至關於每一個進程有了一個 python 解釋器,因此多進程能夠實現多個進程的同時運行,缺點是進程系統資源開銷大。數組

五、說明一下 os.path 和 sys.path 分別表明什麼?

os.path 主要是用於對系統路徑文件的操做。瀏覽器

sys.path 主要是對 Python 解釋器的系統環境參數的操做(動態的改變 Python 解釋器搜索路徑)。

六、模塊和包是什麼?

在 Python 中,模塊是搭建程序的一種方式。每個 Python 代碼文件都是一個模塊,並能夠引用其餘的模塊,好比對象和屬性。

一個包含許多 Python 代碼的文件夾是一個包。一個包能夠包含模塊和子文件夾。

七、談一下什麼是解釋性語言,什麼是編譯性語言?

計算機不能直接理解高級語言,只能直接理解機器語言,因此必需要把高級語言翻譯成機器語言,計算機才能執行高級語言編寫的程序。

解釋性語言在運行程序的時候纔會進行翻譯。

編譯型語言寫的程序在執行以前,須要一個專門的編譯過程,把程序編譯成機器語言(可執行文件)。編譯型語言寫的程序在執行以前,須要一個專門的編譯過程,把程序編譯成機器語言(可執行文件)。

八、關於 Python 程序的運行方面,有什麼手段能提高性能?

一、使用多進程,充分利用機器的多核性能

二、對於性能影響較大的部分代碼,可使用 C 或 C++編寫

三、對於 IO 阻塞形成的性能影響,可使用 IO 多路複用來解決

四、儘可能使用 Python 的內建函數

五、儘可能使用局部變量

九、說一下字典和 json 的區別?

 字典是一種數據結構,json 是一種數據的表現形式,字典的 key 值只要是能 hash 的就行,json 的必須是字符串。json的key必須是雙引號,python的字典不須要,單引號也能夠

十、什麼是可變、不可變類型?

可變不可變指的是內存中的值是否能夠被改變,不可變類型指的是對象所在內存塊裏面的值不能夠改變,有數值、字符串、元組;可變類型則是能夠改變,主要有列表、字典。

十一、請反轉字符串"hello world!"

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

十二、將字符串"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}

1三、寫一個列表生成式,產生一個公差爲 11 的等差數列

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

 1四、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):返回指定範圍內的浮點數。

1五、單引號,雙引號,三引號的區別

單引號和雙引號是等效的,若是要換行,須要符號(\),三引號則能夠直接換行,而且能夠包含註釋

1六、有以下數組 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 高級

一、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.避免循環引用(手動解循環引用和使用弱引用)

三、內存泄露是什麼?如何避免?

  指因爲疏忽或錯誤形成程序未能釋放已經再也不使用的內存的狀況。內存泄漏並不是指內存在物理上的消失,而是應用程序分配某段內存後,因爲設計錯誤,失去了對該段內存的控制,於是形成了內存的浪費。致使程序運行速度減慢甚至系統崩潰等嚴重後果。

  有__del__() 函數的對象間的循環引用是致使內存泄漏的主兇。

  不使用一個對象時使用:del object 來刪除一個對象的引用計數就能夠有效防止內存泄漏問題。經過 Python 擴展模塊 gc 來查看不能回收的對象的詳細信息。

  能夠經過 sys.getrefcount(obj) 來獲取對象的引用計數,並根據返回值是否爲 0 來判斷是否內存泄漏。

 四、Python 函數調用的時候參數的傳遞方式是值傳遞仍是引用傳遞?

  Python 的參數傳遞有:位置參數、默認參數、可變參數、關鍵字參數

 

  函數的傳值究竟是值傳遞仍是引用傳遞,要分狀況:

  不可變參數用值傳遞

    像整數和字符串這樣的不可變對象,是經過拷貝進行傳遞的,由於你不管如何都不可能在原處改變不可變對象

 

  可變參數是引用傳遞的

 

    好比像列表,字典這樣的對象是經過引用傳遞、和 C 語言裏面的用指針傳遞數組很類似,可變對象能在函數內部改變。

五、對缺省參數的理解

  缺省參數指在調用函數的時候沒有傳入參數的狀況下,調用默認的參數,在調用函數的同時賦值時, 所傳入的參數會替代默認參數。

  *args 是不定長參數,他能夠表示輸入參數是不肯定的,能夠是任意多個。

  **kwargs 是關鍵字參數,賦值的時候是以鍵 = 值的方式,參數是能夠任意多對在定義函數的時候不肯定會有多少參數會傳入時,就可使用兩個參數。

六、遞歸函數中止的條件?

遞歸的終止條件通常定義在遞歸函數內部,在遞歸調用前要作一個條件判斷,根據判斷的結果選擇是繼續調用自身,仍是 return;返回終止遞歸。

終止的條件:

判斷遞歸的次數是否達到某一限定值

判斷運算的結果是否達到某個範圍等,根據設計的目的來選擇

一個簡單的遞歸函數的例子

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

p_num(4)

# 輸出結果
4
3
2
1

七、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’的內建方法;

八、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

 九、解釋一下什麼是閉包?

 在函數內部再定義一個函數,而且這個函數用到了外邊函數的變量,那麼將這個函數以及用到的一些變量稱之爲閉包。

10.Python 中 is 和==的區別?

is 判斷的是 a 對象是否就是 b 對象,是經過 id 來判斷的。
==判斷的是 a 對象的值是否和 b 對象的值相等,是經過 來判斷的。

十一、python中的私有屬性和私有方法

以兩個下劃線開頭的屬性和方法稱爲私有屬性和私有方法,可是也可經過特定的方法來訪問,因此python中是僞私有屬性和僞私有方法

訪問私有屬性和私有方法

_類名__屬性名

_類名__方法名()

十二、面向對象中怎麼實現只讀屬性?

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裝飾器把方法變成了類的屬性

這樣就實現了只讀屬性

1三、談談你對面向對象的理解?

面向對象是相對於面向過程而言的。面向過程語言是一種基於功能分析的、以算法爲中心的程序設計方法;而面向對象是一種基於結構分析的、以數據爲中心的程序設計思想。在面嚮對象語言中有一個有很重要東西,叫作類。

面向對象有三大特性:封裝、繼承、多態

1四、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'>

1五、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

1六、用 Python 匹配 HTML標籤的時候,<.*> 和 <.*?> 有什麼區別?

<.*>是貪婪匹配,會從第一個「 <」開始匹配,直到最後一個「 >」中間全部的字符都會匹配到,中間可能會包含「 <>」。

<.*?>是非貪婪匹配,從第一個「 <」開始日後,遇到第一個「 >」結束匹配,這中間的字符串都會匹配到,可是不會有「 <>」。 

1七、談談你對多進程,多線程,以及協程的理解,項目是否用? 

進程:一個運行的程序(代碼)就是一個進程,沒有運行的代碼叫程序,進程是系統資源分配的最小單位,進程擁有本身獨立的內存空間,因此進程間數據不共享,開銷大。

線程: 調度執行的最小單位,也叫執行路徑,不能獨立存在,依賴進程存在一個進程至少有一個線程,叫主線程,而多個線程共享內存(數據共享,共享全局變量),從而極大地提升了程序的運行效率。

協程:是一種用戶態的輕量級線程,協程的調度徹底由用戶控制。協程擁有本身的寄存器上下文和棧。 協程調度切換時,將寄存器上下文和棧保存到其餘地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操做棧則基本沒有內核切換的開銷,能夠不加鎖的訪問全局變量,因此上下文的切換很是快。 

1八、什麼是多線程競爭?

線程是非獨立的,同一個進程裏線程是數據共享的,當各個線程訪問數據資源時會出現競爭狀態即:數據幾乎同步會被多個線程佔用,形成數據混亂 ,即所謂的線程不安全
那麼怎麼解決多線程競爭問題?--
鎖的好處:
確保了某段關鍵代碼(共享數據資源)只能由一個線程從頭至尾完整地執行能解決多線程資源競爭下的原子操做問題。
鎖的壞處:
阻止了多線程併發執行,包含鎖的某段代碼實際上只能以單線程模式執行,效率就大大地降低了鎖的致命問題:死鎖。

1九、什麼是死鎖?

若干子線程在系統資源競爭時,都在等待對方對某部分資源解除佔用狀態,結果是誰也不肯先解鎖,互相干等着,程序沒法執行下去,這就是死鎖。

20、GIL 鎖 全局解釋器鎖(只在 cpython 裏纔有)

做用:限制多線程同時執行,保證同一時間只有一個線程執行,因此 cpython 裏的多線程實際上是僞多線程!
因此 Python 裏經常使用協程技術來代替多線程,協程是一種更輕量級的線程,
進程和線程的切換時由系統決定,而協程由咱們程序員本身決定,而模塊 gevent 下切換是遇到了耗時操做纔會切換。
三者的關係:進程裏有線程,線程裏有協程

2一、什麼是線程安全,什麼是互斥鎖?

每一個對象都對應於一個可稱爲" 互斥鎖" 的標記,這個標記用來保證在任一時刻,只能有一個線程訪問該對象。
同一個進程中的多線程之間是共享系統資源的,多個線程同時對一個對象進行操做,一個線程操做還沒有結束,另外一個線程已經對其進行操做,致使最終結果出現錯誤,此時須要對被操做對象添加互斥鎖,保證每一個線程對該對象的操做都獲得正確的結果。

2二、說說下面幾個概念:同步,異步,阻塞,非阻塞?

同步:多個任務之間有前後順序執行,一個執行完下個才能執行。
異步:多個任務之間沒有前後順序,能夠同時執行有時候一個任務可能要在必要的時候獲取另外一個
同時執行的任務的結果,這個就叫回調!
阻塞:若是卡住了調用者,調用者不能繼續往下執行,就是說調用者阻塞了。
非阻塞:若是不會卡住,能夠繼續執行,就是說非阻塞的。
同步異步相對於多任務而言,阻塞非阻塞相對於代碼執行而言。

2三、什麼是殭屍進程和孤兒進程?怎麼避免殭屍進程?

孤兒進程:父進程退出,子進程還在運行的這些子進程都是孤兒進程,孤兒進程將被 init 進程(進程號爲 1)所收養,並由 init 進程對它們完成狀態收集工做。
殭屍進程:進程使用 fork 建立子進程,若是子進程退出,而父進程並無調用 wait 或 waitpid 獲取子進程的狀態信息,那麼子進程的進程描述符仍然保存在系統中的這些進程是殭屍進程。
避免殭屍進程的方法:
1.fork 兩次用孫子進程去完成子進程的任務;
2.用 wait()函數使父進程阻塞;
3.使用信號量,在 signal handler 中調用 waitpid,這樣父進程不用阻塞。

2四、Python 中的進程與線程的使用場景? 

多進程適合在 CPU 密集型操做(cpu 操做指令比較多,如位數多的浮點運算)。
多線程適合在 IO 密集型操做(讀寫數據操做較多的,好比爬蟲)。

2五、線程是併發仍是並行,進程是併發仍是並行?

線程是併發,進程是並行;
進程之間相互獨立,是系統分配資源的最小單位,同一個線程中的全部線程共享資源。

2六、並行(parallel)和併發(concurrency)?

並行:同一時刻多個任務同時在運行。
併發:在同一時間間隔內多個任務都在運行,可是並不會在同一時刻同時運行,存在交替執行的狀況。
實現並行的庫有:multiprocessing
實現併發的庫有:threading
程序須要執行較多的讀寫、請求和回覆任務的須要大量的 IO 操做,IO 密集型操做使用併發更好。
CPU 運算量大的程序程序,使用並行會更好。

2七、IO 密集型和 CPU 密集型區別?

IO 密集型:系統運做,大部分的情況是 CPU 在等 I/O (硬盤/內存)的讀/寫。
CPU 密集型:大部份時間用來作計算、邏輯判斷等 CPU 動做的程序稱之 CPU 密集型。

2八、簡述 TCP 和 UDP 的區別以及優缺點?

UDP 是面向無鏈接的通信協議,UDP 數據包括目的端口號和源端口號信息。
優勢:UDP 速度快、操做簡單、要求系統資源較少,因爲通信不須要鏈接,能夠實現廣播發送
缺點:UDP 傳送數據前並不與對方創建鏈接,對接收到的數據也不發送確認信號,發送端不知道數據是否會正確接收,也不重複發送,不可靠。
TCP 是面向鏈接的通信協議,經過三次握手創建鏈接,通信完成時四次揮手
優勢:TCP 在數據傳遞時,有確認、窗口、重傳、阻塞等控制機制,能保證數據正確性,較爲可靠。
缺點:TCP 相對於 UDP 速度慢一點,要求系統資源較多。

2九、描述用瀏覽器訪問 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 響應

3一、cookie session 的區別?

一、cookie 數據存放在客戶的瀏覽器上,session 數據放在服務器上。

二、cookie 不是很安全,別人能夠分析存放在本地的 cookie 並進行 cookie 欺騙考慮到安全應當使 session。

 

三、session 會在必定時間內保存在服務器上。當訪問增多,會比較佔用服務器的性能考慮到減輕服務器性能方面,應當使用 cookie。

四、單個 cookie 保存的數據不能超過 4K,不少瀏覽器都限制一個站點最多保存 20 個 cookie。

五、建議: 將登錄信息等重要信息存放爲 SESSION 其餘信息若是須要保留,能夠放在 cookie 中

3二、請簡單說一下三次握手和四次揮手?

三次握手過程:

首先客戶端向服務端發送一個帶有 SYN 標誌,以及隨機生成的序號 100(0 字節)的報文

服務端收到報文後返回一個報文(SYN200(0 字節),ACk1001(字節+1))給客戶端

客戶端再次發送帶有 ACk 標誌 201(字節+)序號的報文給服務端至此三次握手過程結束,客戶端開始向服務端發送數據。

 

1 客戶端向服務端發起請求:我想給你通訊,你準備好了麼?

服務端收到請求後迴應客戶端:I'ok,你準備好了麼

3 客戶端禮貌的再次回一下客戶端:準備就緒,我們開始通訊吧!

整個過程跟打電話的過程如出一轍:1 喂,你在嗎在,我說的你聽獲得不恩,聽獲得(接下來請開始你的表演)

補充:SYN:請求詢問,ACk:回覆,迴應。

四次揮手過程:

因爲 TCP 鏈接是能夠雙向通訊的(全雙工),所以每一個方向都必須單獨進行關閉(這句話纔是精闢,後面四個揮手過程都是其具體實現的語言描述)

四次揮手過程,客戶端和服務端均可以先開始斷開鏈接

客戶端發送帶有 fin 標識的報文給服務端,請求通訊關閉

服務端收到信息後,回覆 ACK 答應關閉客戶端通訊(鏈接)請求

服務端發送帶有 fin 標識的報文給客戶端,也請求關閉通訊

客戶端迴應 ack 給服務端,答應關閉服務端的通訊(鏈接)請求

3三、說說 HTTP 和HTTPS 區別?

HTTP 協議傳輸的數據都是未加密的,也就是明文的,所以使用 HTTP 協議傳輸隱私信息很是不安全,爲了保證這些隱私數據能加密傳輸,因而網景公司設計了 SSL(Secure Sockets Layer)協議用於 HTTP 協議傳輸的數據進行加密,從而就誕生了 HTTPS。簡單來講,HTTPS 協議是由 SSL+HTTP 議構建的可進行加密傳輸、身份認證的網絡協議,要比 http 協議安全。

HTTPS 和 HTTP 的區別主要以下:

一、https 協議須要到 ca 申請證書,通常免費證書較少,於是須要必定費用。

二、http 是超文本傳輸協議,信息是明文傳輸,https 則是具備安全性的 ssl 加密傳輸協議。

三、http  https 使用的是徹底不一樣的鏈接方式,用的端口也不同,前者是 80,後者是 443。

四、http 的鏈接很簡單,是無狀態的;HTTPS 協議是由 SSL+HTTP 協議構建的可進行加密傳輸、身份認證的網絡協議,比 http 協議安全。

3四、HTTP 常見請求頭

 

Host (主機和端口號)

Connection (連接類型)

Upgrade-Insecure-Requests (升級爲 HTTPS 請求)

User-Agent (瀏覽器名稱)

Accept (傳輸文件類型)

Referer (頁面跳轉處)

Accept-Encoding(文件編解碼格式)

Cookie (Cookie)

x-requested-with :XMLHttpRequest ( Ajax 異步請求)

3五、七層模型? IP ,TCP/UDP ,HTTP ,RTSP ,FTP 分別在哪層?

應用層,表示層,會話層,傳輸層,網絡層,數據鏈路層,物理層

IP 網絡層

TCP/UDP 傳輸層

HTTP、RTSP、FTP 應用層協議

3六、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 廢棄,統一使用 int6. xrange 函數被 Python3 廢棄,統一使用 range,Python3 中 range 的機制也進行修改並提升了大數據集生成效率

相關文章
相關標籤/搜索