校招面試問答準(zhǔn)備

多有參考
全棧修煉手冊
Python常見的170道面試題
關(guān)于python的面試題

python語言特性

  1. python2 和 python3 的區(qū)別?

    • print在python3中是函數(shù)必須加括號唧龄,在python2中為class祠够。
    • python2只能夠默認(rèn)的字符串類型是ASCII冗尤,python3中默認(rèn)字符串類型是Unicode旋炒。
    • python2中/的結(jié)果是整型python3中的是浮點(diǎn)型
    • python2中使用xrange掌测,python3中使用range乖阵。
      xrange生成一個(gè)list對象旅择,range生成一個(gè)range對象(可迭代惭笑,但不是迭代器)
  2. python3中的基本數(shù)據(jù)類型
    字符串(string)、數(shù)字(digit)生真、列表(list)沉噩、元組(tuple)、集合(sets)柱蟀、字典(dictionary)川蒙。

  3. python3常用方法函數(shù)

    1. python內(nèi)置結(jié)構(gòu)時(shí)間復(fù)雜度
    2. 字符串內(nèi)建函數(shù)
    3. python內(nèi)置函數(shù)
    4. python中的拷貝(引用和copy()、deepcopy()的區(qū)別)
      • 對于不可變對象沒有意義
      • 淺拷貝構(gòu)造一個(gè)新的復(fù)合對象长已,然后(盡可能)將對它的引用插入到原始對象中畜眨。
      • 深拷貝構(gòu)造一個(gè)新的復(fù)合對象,然后遞歸地將復(fù)制對象插入到原始對象中找到的對象中术瓮。
    5. 了解enumerate嘛康聂?
      enumerate可以在迭代一個(gè)對象的時(shí)候同時(shí)獲取當(dāng)前對象的索引和值。for index, value in enumerate([a,b,c,d])
    6. isinstance 作用以及應(yīng)用場景胞四?
      判斷一個(gè)對象是否是另一個(gè)對象的子類
      print(isinstance(True,int))
    7. lambda表達(dá)式格式以及應(yīng)用場景恬汁?
      匿名函數(shù)lambda x: x表達(dá)式
      按照字典的值排序
      d = {'a':2,'b':1,'c':3}
      print(dict(sorted(d.items(), key=lambda x:x[1]))) # {'b':1,'a':2,'c':3}
      
    8. map()函數(shù)接收兩個(gè)參數(shù),一個(gè)是函數(shù)撬讽,一個(gè)是Iterable蕊连,map將傳入的函數(shù)依次作用到序列的每個(gè)元素,并把結(jié)果作為新的Iterator返回游昼。
      推薦使用列表推導(dǎo)式
       def f(x):
          return x * x
       r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
       list(r) #[1, 4, 9, 16, 25, 36, 49, 64, 81]
       列表推導(dǎo)式
       [i*i for i in range(1,10)]
      
    9. reduce()把一個(gè)函數(shù)作用在一個(gè)序列[x1, x2, x3, ...]上甘苍,這個(gè)函數(shù)必須接收兩個(gè)參數(shù),reduce把結(jié)果繼續(xù)和序列的下一個(gè)元素做累積計(jì)算烘豌,其效果就是:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
      把序列[1, 3, 5, 7, 9]變換成整數(shù)13579载庭,reduce就可以派上用場:
      from functools import reduce
          def fn(x, y):
              return x * 10 + y
       reduce(fn, [1, 3, 5, 7, 9]) #13579
      
    10. filter()也接收一個(gè)函數(shù)和一個(gè)序列。和map()不同的是廊佩,filter()把傳入的函數(shù)依次作用于每個(gè)元素囚聚,然后根據(jù)返回值是True還是False決定保留還是丟棄該元素。
      同樣推薦使用列表推導(dǎo)式
      def is_odd(n):
         return n % 2 == 1
      
      list(filter(is_odd, [1,  4,  9, 16, 25]))
      # 結(jié)果: [1, 9, 25]
      [i for i in [j*j for j in range(1,6)] if i%2 == 1]
      
    11. zip()函數(shù)用于將可迭代的對象作為參數(shù)标锄,將對象中對應(yīng)的元素打包成一個(gè)個(gè)元組顽铸,然后返回由這些元組組成的對象,這樣做的好處是節(jié)約了不少的內(nèi)存料皇。
      我們可以使用 list() 轉(zhuǎn)換來輸出列表谓松。
      如果各個(gè)迭代器的元素個(gè)數(shù)不一致,則返回列表長度與最短的對象相同践剂,利用 * 號操作符鬼譬,可以將元組解壓為列表。
      #把元組 ("a","b") 和元組 (1,2)逊脯,變?yōu)樽值?{"a":1,"b":2}
      a = ("a", "b")
      b = (1, 2)
      print(dict(zip(a, b)))
      
      #交換字典的鍵和值
      s =  {"A":1,"B":2}
      #方法一:
      dict_new = {value:key for key优质,value in 
      s.items()}
      # 方法二:
      new_s= dict(zip(s.values(),s.keys()))
      
  4. 什么是閉包军洼?
    當(dāng)一個(gè)內(nèi)嵌函數(shù)引用其外部作作用域的變量,我們就會(huì)得到一個(gè)閉包. 總結(jié)一下,創(chuàng)建一個(gè)閉包必須滿足以下幾點(diǎn):
    必須有一個(gè)內(nèi)嵌函數(shù)
    內(nèi)嵌函數(shù)必須引用外部函數(shù)中的變量
    外部函數(shù)的返回值必須是內(nèi)嵌函數(shù)
    裝飾器本質(zhì)就是一個(gè)閉包

  5. 什么是裝飾器巩螃?
    裝飾器就是一個(gè)函數(shù),它可以在不需要做任何代碼變動(dòng)的前提下給一個(gè)函數(shù)增加額外功能匕争,啟動(dòng)裝飾的效果牺六。比如插入日志

    def log(func):
     def wrapper(*args, **kw):
         print('call %s():' % func.__name__)
         return func(*args, **kw)
     return wrapper
    
     @log
     def now():
         print("2019.8.20")
     >>> now()
     call now(): 
     2019.8.20
    
    但是now.__name__變成了'wrapper',因?yàn)槲覀兎祷氐木褪莣rapper汗捡,不過python早都考慮到了淑际,完整實(shí)現(xiàn)如下:
    import functools
    
    def log(func):
      @functools.wraps(func)
      def wrapper(*args, **kw):
          print('call %s():' % func.__name__)
          return func(*args, **kw)
      return wrapper
    
  6. python解包?
    解包在英文里叫做 Unpacking扇住,就是將容器里面的元素逐個(gè)取出來a,b,c = [1,2,3]這個(gè)過程就是解包春缕,python中解包是自動(dòng)完成的.

    • 代碼中經(jīng)常遇到的*args, **kwargs 含義及用法。

      在函數(shù)定義中使用 args 和*kwargs 傳遞可變長參數(shù)艘蹋。 *args 用來將參數(shù)打包成 tuple 給函數(shù)體調(diào)用锄贼。 **kwargs 打包關(guān)鍵字參數(shù)成 dict 給函數(shù)體調(diào)用。

    • 合并兩個(gè)字典
      a = {"A":1,"B":2}
      b = {"C":3,"D":4}
      # a.update(b) 
      print({**a,**b})
      
    • n = [1,2,3,4]
      a,*b,c = n
      a,b,c #1,[2,3],[3]
      
    1. 自動(dòng)解包支持一切可迭代對象
    2. 可以用星號操作使等號左邊的變量個(gè)數(shù)少于右邊的元素個(gè)數(shù)
      1.函數(shù)調(diào)用時(shí)女阀,可以使用* 或**解包可迭代對象
  7. python函數(shù)傳參宅荤?
    python中傳的是對象的引用屑迂。
    默認(rèn)參數(shù)只初始化一次且必須指向不變對象

    from datetime import datetime
    
    def test(t=datetime.today()):
       print t
      
    if __name__ == "__main__":
       test()
       test()
    兩次調(diào)用輸出為同一個(gè)值 
    建議常用下面一種方式
    
    from datetime import datetime
    
    def test2(t = None):
       if t is None:
          t = datetime.today()
       print t
    
    if __name__ == "__main__":
     test()
     test()
    
     def func(item, item_list=[]):
       item_lsit.append(item)
       print(item_lsit)
    
    func('xiaomi') #[xiaomi]
    func('iphone',item_list=['xiaomi','huawei'])#[xiaomi,huawei,iphone]
    func('vivo')#[xiaomi,vivo]
    第一次初始化def時(shí)會(huì)生成可變對象的內(nèi)存地址,然后將這個(gè)默認(rèn)參數(shù)item_list與內(nèi)存地址綁定冯键。
    在后面的調(diào)用中惹盼,如果指定了新的默認(rèn)值,就會(huì)將原來的默認(rèn)值覆蓋掉惫确,如果沒有指認(rèn)的話手报,就會(huì)用原來的默認(rèn)值。
    
  8. 什么是列表推導(dǎo)式改化?字典推導(dǎo)式呢掩蛤?集合推導(dǎo)式?

    • [x for x in range(10)]
    • #[[1,2],[3,4],[5,6]] 一行代碼展開該列表陈肛,得出 [1,2,3,4,5,6]
      l = [[1,2],[3,4],[5,6]]
      x=[j for i in l for j in i]  
      print(x)
      
    • d = {key: value for (key, value) in iterable}
    •  # 把字典的key和value調(diào)換
       d = {'a':'1', 'b':'2'}
       print({v:k for k,v in d.items()})
      
    • #如何把元組 ("a","b") 和元組 (1,2)揍鸟,變?yōu)樽值?{"a":1,"b":2}
      a = ("a", "b")
      b = (1, 2)
      print(dict(zip(a, b)))
      
    • squared = {x**2 for x in [1, 1, 2]}與列表推導(dǎo)式類似,唯一區(qū)別在于它使用大括號
  9. 什么是迭代器句旱?
    迭代器對象從集合的第一個(gè)元素開始訪問蜈亩,直到所有的元素被訪問完結(jié)束。迭代器只能往前不會(huì)后退前翎。
    迭代器有兩個(gè)基本的方法:iter(可迭代對象) 和 next(迭代器)

  10. 如何創(chuàng)建一個(gè)迭代器稚配?
    把一個(gè)類作為迭代器使用需要在類中實(shí)現(xiàn)__iter__()__next__()
    __iter__() 方法返回一個(gè)特殊的迭代器對象, 這個(gè)迭代器對象實(shí)現(xiàn)了 next() 方法并通過 StopIteration 異常標(biāo)識(shí)迭代的完成港华。
    __next__() 方法會(huì)返回下一個(gè)迭代器對象道川。

       class MyNumbers:
         def __iter__(self):
            self.a = 1
            return self
     
         def __next__(self):
            if self.a <= 20:
               x = self.a
               self.a += 1
               return x
             else:
               raise StopIteration
    
       myclass = MyNumbers()
       myiter = iter(myclass)
    
       for x in myiter:
           print(x)#1-20
    
  11. 什么是生成器?

    • 在 Python 中立宜,使用了 yield 的函數(shù)被稱為生成器(generator)冒萄。
    • 跟普通函數(shù)不同的是,生成器是一個(gè)返回迭代器的函數(shù)橙数,只能用于迭代操作尊流,更簡單點(diǎn)理解生成器就是一個(gè)迭代器。
    • 在調(diào)用生成器運(yùn)行的過程中灯帮,每次遇到 yield 時(shí)函數(shù)會(huì)暫停并保存當(dāng)前所有的運(yùn)行信息崖技,返回 yield 的值, 并在下一次執(zhí)行 next() 方法時(shí)從當(dāng)前位置繼續(xù)運(yùn)行。
    • 調(diào)用一個(gè)生成器函數(shù)钟哥,返回的是一個(gè)迭代器對象迎献。
    • #請將 [i for i in range(3)] 改成生成器
      (i for i in range(3))
      不同的是生成式不必創(chuàng)建完整的list,從而節(jié)省大量的空間
      
  12. 單下劃線和雙下劃線腻贰?
    __foo__: 一種約定,Python內(nèi)部的名字,用來區(qū)別其他用戶自定義的命名,以防沖突吁恍,就是例如__init__(),__call__()這些特殊方法
    _foo:一種約定,用來指定變量私有.程序員用來指定私有變量的一種方式.不能用from module import * 導(dǎo)入,其他方面和公有一樣訪問;
    __foo:這個(gè)有真正的意義:解析器用classname__foo來代替這個(gè)名字,以區(qū)別和其他類相同的命名,它無法直接像公有成員一樣隨便訪問,通過對象名.類名__xxx這樣的方式可以訪問.

  13. hasattr()冀瓦、getattr()伴奥、setattr() 、delattr()的用法(python中的反射)翼闽?
    配合dir()獲取一個(gè)對象的所有屬性和方法
    hasattr(obj,'attr')可以判斷一個(gè)對象是否含有某個(gè)屬性拾徙,getattr(obj,'attr',default) 可以充當(dāng) get 獲取對象屬性的作用相當(dāng)于obj.attr。 setattr(obj,'attr','abc') 可以充當(dāng) obj.attr = "abc"的賦值操作,delattr(obj,'attr')相當(dāng)于del obj.attr

  14. 魔法方法以及用途肄程。
    init類的初始化方法
    new對象實(shí)例化時(shí)第一個(gè)調(diào)用的方法
    slots動(dòng)態(tài)的給類添加屬性和方法
    str友好打印
    repr程序友好打印
    call對實(shí)例進(jìn)行調(diào)用實(shí)例名()
    property使實(shí)例方法可以像實(shí)例屬性一樣訪問
    使用時(shí)只需要在對應(yīng)的方法上加@property同時(shí)會(huì)生成@方法名.setter@方法名.deleter修飾的方法可用來升級取代 getattrsetattr

  15. python中的元類
    這個(gè)不常用选浑,但是像ORM中還是需要的蓝厌,比如在ORM中想定義一個(gè)父類而不是生成一張表就要用元類。

  16. @staticmethod和@classmethod

    • 相同之處:@staticmethod和@classmethod都可以直接類名.方法名()來調(diào)用古徒,不用實(shí)例化一個(gè)類拓提。
    • @staticmethod 經(jīng)常有一些和類相關(guān)的功能但是運(yùn)行時(shí)又不需要實(shí)例和類參數(shù)的參與。
      @classmethod 需要在類中運(yùn)行而不再實(shí)例中運(yùn)行的方法
  17. 類變量和實(shí)例變量

    • 類變量:是可在類的所有實(shí)例之間共享的值(也就是說隧膘,它們不是單獨(dú)分配給每個(gè)實(shí)例的)代态。例如下例中,num_of_instance 就是類變量疹吃,用于跟蹤存在著多少個(gè)Test 的實(shí)例蹦疑。
    • 實(shí)例變量:實(shí)例化之后,每個(gè)實(shí)例單獨(dú)擁有的變量萨驶。
  18. with的作用歉摧?
    with 提供了一種機(jī)制,可以在進(jìn)入和退出(無論正常退出腔呜,還是異常退出)某個(gè)語句塊時(shí)叁温,自動(dòng)執(zhí)行自定義的代碼。
    對這個(gè)機(jī)制的封裝核畴,叫做上下文管理器膝但。with 是對上下文管理器的調(diào)用。

    一般訪問文件時(shí)的操作
    f = open(
     'test.txt', 'r')
    try : 
       data = f.read()
    finally:
       f.close()
    
    同樣的語句我們可以用with來實(shí)現(xiàn)
    with open('test.txt', 'r') as f:
    data = f.read()
    
  19. 如何實(shí)現(xiàn)上下文管理器谤草?
    在python中實(shí)現(xiàn)了__enter__()__exit__()方法對象就可以稱為上下文管理器

    class File(object):
       def __init__(self, file_name, file_model):
            self.file_name = file_name
            self.file_model = file_model
       def __enter__(self):
            self.f =  open(self.file_name, self.model) 
            return self.f
       def __exit__(self):
            self.f.close()
    
    with File('test.txt', 'r') as f:
          data = f.read()
    
  20. w跟束、a+、wb文件寫入模式的區(qū)別

    • w打開一個(gè)文件用與寫入,如果該文件存在則會(huì)將原有的文件覆蓋,如果該文件不存在,則會(huì)創(chuàng)建一個(gè)新文件
    • wb以二進(jìn)制的格式去寫入數(shù)據(jù),如果該文件已經(jīng)存在則會(huì)將原有的文件覆蓋,如果該文件件不存在,則會(huì)創(chuàng)建一個(gè)新文件
    • a+ 打開一個(gè)文件,用于讀寫,如果該文件已經(jīng)存在,文件的指針將會(huì)放在文件的結(jié)尾位置,新的內(nèi)容會(huì)被寫入到已有內(nèi)容的后面丑孩。如果該文件不存在,則會(huì)創(chuàng)建新文件用于讀寫
  21. read泳炉、readline、readlines的區(qū)別嚎杨?

    • read 讀取整個(gè)文件
    • readline 讀取下一行,使用生成器方法
    • readlines 讀取整個(gè)文件到一個(gè)迭代器以供我們遍歷
  22. 鴨子類型
    “當(dāng)看到一只鳥走起來像鴨子花鹅、游泳起來像鴨子、叫起來也像鴨子枫浙,那么這只鳥就可以被稱為鴨子刨肃」潘”
    我們并不關(guān)心對象是什么類型,到底是不是鴨子真友,只關(guān)心行為黄痪。
    比如在python中,有很多file-like的東西盔然,比如StringIO,GzipFile,socket桅打。它們有很多相同的方法,我們把它們當(dāng)作文件使用愈案。
    又比如list.extend()方法中,我們并不關(guān)心它的參數(shù)是不是list,只要它是可迭代的,所以它的參數(shù)可以是list/tuple/dict/字符串/生成器等.

  23. 單例模式

    單例模式是一種常用的軟件設(shè)計(jì)模式挺尾。在它的核心結(jié)構(gòu)中只包含一個(gè)被稱為單例類的特殊類。通過單例模式可以保證系統(tǒng)中一個(gè)類只有一個(gè)實(shí)例而且該實(shí)例易于外界訪問站绪,從而方便對實(shí)例個(gè)數(shù)的控制并節(jié)約系統(tǒng)資源遭铺。如果希望在系統(tǒng)中某個(gè)類的對象只能存在一個(gè),單例模式是最好的解決方案恢准。
    __new__()__init__()之前被調(diào)用魂挂,用于生成實(shí)例對象。利用這個(gè)方法和類的屬性的特點(diǎn)可以實(shí)現(xiàn)設(shè)計(jì)模式的單例模式馁筐。單例模式是指創(chuàng)建唯一對象涂召,單例模式設(shè)計(jì)的類只能實(shí)例

    使用__new__方法實(shí)現(xiàn)
    class Singleton(object):
     def __new__(cls, *args, **kw):
         if not hasattr(cls, '_instance'):
             orig = super(Singleton, cls)
             cls._instance = orig.__new__(cls, *args, **kw)
         return cls._instance
    
    class MyClass(Singleton):
        a = 1
    
    
    
    import方法
    作為python的模塊是天然的單例模式
    # mysingleton.py
    class My_Singleton(object):
        def foo(self):
            pass
    
    my_singleton = My_Singleton()
    
    # to use
    from mysingleton import my_singleton
    
    my_singleton.foo()
    
    
    
    裝飾器版本
    def singleton(cls):
     instances = {}
     def getinstance(*args, **kw):
         if cls not in instances:
             instances[cls] = cls(*args, **kw)
         return instances[cls]
     return getinstance
    
    @singleton
    class MyClass:
      ...
    
    
    共享屬性實(shí)現(xiàn)
    創(chuàng)建實(shí)例時(shí)把所有實(shí)例的__dict__指向同一個(gè)字典,這樣它們具有相同的屬性和方法.
    class Borg(object):
     _state = {}
     def __new__(cls, *args, **kw):
         ob = super(Borg, cls).__new__(cls, *args, **kw)
         ob.__dict__ = cls._state
         return ob
    
    class MyClass2(Borg):
        a = 1
    
  24. 字符串格式化方式有哪些?
    %s(不推薦了),format敏沉,fstring(推薦)

  25. 序列化(pickle和JSON)
    通過dumpsloads進(jìn)行序列化和反序列化
    json序列化保存中文`json.dumps({"name":"小明"},ensure)ascii=False)

  26. python字符串編碼芹扭?

    "S".encode("gbk").decode("utf-8")
    將編碼為GBK的字符“S”解碼成Unicode再編碼成utf-8
    
  27. python常用模塊
    常用內(nèi)建模塊
    常用第三方模塊

操作系統(tǒng)

  1. 多進(jìn)程、多線程和協(xié)程的區(qū)別赦抖?

    1. 地址空間:線程是進(jìn)程內(nèi)的一個(gè)執(zhí)行單元舱卡,進(jìn)程內(nèi)至少有一個(gè)線程,它們共享進(jìn)程的地址空間队萤,
      而進(jìn)程有自己獨(dú)立的地址空間
    2. 資源擁有:進(jìn)程是資源分配和擁有的單位,同一個(gè)進(jìn)程內(nèi)的線程共享進(jìn)程的資源
    3. 線程是處理器調(diào)度的基本單位,但進(jìn)程不是
    4. 二者均可并發(fā)執(zhí)行
    5. 每個(gè)獨(dú)立的線程有一個(gè)程序運(yùn)行的入口轮锥、順序執(zhí)行序列和程序的出口,
      但是線程不能夠獨(dú)立執(zhí)行要尔,必須依存在應(yīng)用程序中舍杜,由應(yīng)用程序提供多個(gè)線程執(zhí)行控制
    6. 一個(gè)線程可以多個(gè)協(xié)程,一個(gè)進(jìn)程也可以單獨(dú)擁有多個(gè)協(xié)程赵辕。
    7. 線程進(jìn)程都是同步機(jī)制既绩,而協(xié)程則是異步
    8. 協(xié)程能保留上一次調(diào)用時(shí)的狀態(tài),每次過程重入時(shí)还惠,就相當(dāng)于進(jìn)入上一次調(diào)用的狀態(tài)
  2. 線程同步方式饲握?

    1. 互斥鎖:通過互斥機(jī)制防止多個(gè)線程同時(shí)訪問公共資源
      1.信號量:控制同一時(shí)刻多個(gè)線程訪問統(tǒng)一資源的線程數(shù)
    2. 事件:通過通知的方式保持多個(gè)線程同步
  3. 進(jìn)程間通信的方式

    1. 管道:管道是通過調(diào)用 pipe 函數(shù)創(chuàng)建的,fd[0] 用于讀,fd[1] 用于寫救欧。
    2. 消息隊(duì)列: 間接(內(nèi)核)
      相比于 FIFO衰粹,消息隊(duì)列具有以下優(yōu)點(diǎn):
      消息隊(duì)列可以獨(dú)立于讀寫進(jìn)程存在,從而避免了 FIFO 中同步管道的打開和關(guān)閉時(shí)可能產(chǎn)生的困難笆怠;
      避免了 FIFO 的同步阻塞問題铝耻,不需要進(jìn)程自己提供同步方法;
      讀進(jìn)程可以根據(jù)消息類型有選擇地接收消息蹬刷,而不像 FIFO 那樣只能默認(rèn)地接收瓢捉。
    3. 信號量:它是一個(gè)計(jì)數(shù)器,用于為多個(gè)進(jìn)程提供對共享數(shù)據(jù)對象的訪問办成。
    4. 共享內(nèi)存:允許多個(gè)進(jìn)程共享一個(gè)給定的存儲(chǔ)區(qū)泡态。因?yàn)閿?shù)據(jù)不需要在進(jìn)程之間復(fù)制,所以這是最快的一種 IPC诈火。
      需要使用信號量用來同步對共享存儲(chǔ)的訪問兽赁。
      多個(gè)進(jìn)程可以將同一個(gè)文件映射到它們的地址空間從而實(shí)現(xiàn)共享內(nèi)存状答。另外 XSI 共享內(nèi)存不是使用文件冷守,而是使用使用內(nèi)存的匿名段。
    5. 套接字:與其它通信機(jī)制不同的是惊科,它可用于不同機(jī)器間的進(jìn)程通信拍摇。
  4. python中如何使用多線程?
    threading模塊
    threading.Thread類用于創(chuàng)建線程
    start()方法啟動(dòng)線程
    可以用join()等待線程結(jié)束

  5. python中如何使用多進(jìn)程
    multiprocessing模塊
    Multiprocessing.Process類實(shí)現(xiàn)多進(jìn)程

  6. 解釋什么是同步馆截、異步充活、阻塞、非阻塞蜡娶?

    引用知乎回答
    1.同步與異步
    同步和異步關(guān)注的是消息通信機(jī)制 (synchronous communication/ asynchronous communication)
    所謂同步混卵,就是在發(fā)出一個(gè)調(diào)用時(shí),在沒有得到結(jié)果之前窖张,該調(diào)用就不返回幕随。但是一旦調(diào)用返回,就得到返回值了宿接。
    換句話說赘淮,就是由調(diào)用者主動(dòng)等待這個(gè)調(diào)用的結(jié)果。
    而異步則是相反睦霎,調(diào)用在發(fā)出之后梢卸,這個(gè)調(diào)用就直接返回了,所以沒有返回結(jié)果副女。換句話說蛤高,當(dāng)一個(gè)異步過程調(diào)用發(fā)出后,調(diào)用者不會(huì)立刻得到結(jié)果。而是在調(diào)用發(fā)出后襟齿,被調(diào)用者通過狀態(tài)姻锁、通知來通知調(diào)用者,或通過回調(diào)函數(shù)處理這個(gè)調(diào)用猜欺。
    阻塞和非阻塞關(guān)注的是程序在等待調(diào)用結(jié)果(消息位隶,返回值)時(shí)的狀態(tài).
    阻塞調(diào)用是指調(diào)用結(jié)果返回之前,當(dāng)前線程會(huì)被掛起开皿。調(diào)用線程只有在得到結(jié)果之后才會(huì)返回涧黄。
    非阻塞調(diào)用指在不能立刻得到結(jié)果之前,該調(diào)用不會(huì)阻塞當(dāng)前線程赋荆。

  7. 什么是死鎖笋妥?
    原因:

    • 競爭資源
    • 程序推進(jìn)順序不當(dāng)

    必要條件:

    • 互斥條件:每個(gè)資源要么已經(jīng)分配給了一個(gè)進(jìn)程,要么就是可用的窄潭。
    • 請求和保持條件:已經(jīng)得到了某個(gè)資源的進(jìn)程可以再請求新的資源
    • 不剝奪條件:已經(jīng)分配給一個(gè)進(jìn)程的資源不能強(qiáng)制性地被搶占春宣,它只能被占有它的進(jìn)程顯式地釋放。
    • 環(huán)路等待條件:有兩個(gè)或者兩個(gè)以上的進(jìn)程組成一條環(huán)路嫉你,該環(huán)路中的每個(gè)進(jìn)程都在等待下一個(gè)進(jìn)程所占有的資源月帝。

    處理死鎖基本方法:

    • 預(yù)防死鎖(摒棄除1以外的條件)
    • 避免死鎖(銀行家算法)
    • 檢測死鎖(資源分配圖)
    • 解除死鎖
      • 剝奪資源
      • 撤銷進(jìn)程
  8. 什么是分頁機(jī)制
    邏輯地址和物理地址分離的內(nèi)存分配管理方案

    • 程序的邏輯地址劃分為固定大小的頁(page)
    • 物理地址劃分同樣大小的幀
    • 通過頁表對應(yīng)邏輯地址和物理地址
  9. 什么是分段機(jī)制

    • 分段是為了滿足代碼的一些邏輯需求
    • 數(shù)據(jù)共享,數(shù)據(jù)保護(hù)幽污,動(dòng)態(tài)鏈接等
    • 通過段表實(shí)現(xiàn)邏輯地址和物理地址的映射關(guān)系
      每個(gè)段內(nèi)部是連續(xù)內(nèi)存分配嚷辅,段和段之間是離散分配的

    頁是出于內(nèi)存利用率的角度提出的離散分配機(jī)制
    段是出于用戶角度,用戶數(shù)據(jù)保護(hù)距误,數(shù)據(jù)隔離等用途的管理機(jī)制
    頁的大小是固定的簸搞,操作系統(tǒng)決定;段大小不確定准潭,用戶程序決定

  10. 什么是虛擬內(nèi)存
    通過把一部分暫時(shí)不用的內(nèi)存信息放到硬盤上

    • 局部性原理(一塊內(nèi)存被訪問趁俊,時(shí)間上不遠(yuǎn)的將來還可能被訪問,空間上周圍的內(nèi)存也可能被訪問)刑然,程序運(yùn)行時(shí)候只有部分必要的信息裝入內(nèi)存
    • 內(nèi)存中暫時(shí)不用的內(nèi)容放到硬盤上
    • 系統(tǒng)似乎提供了比實(shí)際內(nèi)存大得多的容量寺擂,稱之為虛擬內(nèi)存
  11. 什么是內(nèi)存抖動(dòng)
    本質(zhì)上是頻繁的頁調(diào)動(dòng)行為

    • 頻繁的頁調(diào)度,進(jìn)程不斷產(chǎn)生缺頁中斷
    • 置換一個(gè)頁闰集,又不斷的再次需要這個(gè)頁
    • 運(yùn)行程序太多沽讹,頁面替換策略不好。終止進(jìn)程,或增加物理內(nèi)存
  12. python的垃圾回收機(jī)制
    Python GC主要使用引用計(jì)數(shù)(reference counting)來跟蹤和回收垃圾。在引用計(jì)數(shù)的基礎(chǔ)上嗅回,通過“標(biāo)記-清除”(mark and sweep)解決容器對象可能產(chǎn)生的循環(huán)引用問題,通過“分代回收”(generation collection)以空間換時(shí)間的方法提高垃圾回收效率挚瘟。

    • 引用計(jì)數(shù)
      PyObject是每個(gè)對象必有的內(nèi)容叹谁,其中ob_refcnt就是做為引用計(jì)數(shù)。當(dāng)一個(gè)對象有新的引用時(shí)乘盖,它的ob_refcnt就會(huì)增加焰檩,當(dāng)引用它的對象被刪除,它的ob_refcnt就會(huì)減少.引用計(jì)數(shù)為0時(shí)订框,該對象生命就結(jié)束了析苫。
    • 標(biāo)記-清除機(jī)制
      基本思路是先按需分配,等到?jīng)]有空閑內(nèi)存的時(shí)候從寄存器和程序棧上的引用出發(fā)穿扳,遍歷以對象為節(jié)點(diǎn)衩侥、以引用為邊構(gòu)成的圖,把所有可以訪問到的對象打上標(biāo)記矛物,然后清掃一遍內(nèi)存空間茫死,把所有沒標(biāo)記的對象釋放。
    • 分代技術(shù)
      分代回收的整體思想是:將系統(tǒng)中的所有內(nèi)存塊根據(jù)其存活時(shí)間劃分為不同的集合履羞,每個(gè)集合就成為一個(gè)“代”峦萎,垃圾收集頻率隨著“代”的存活時(shí)間的增大而減小,存活時(shí)間通常利用經(jīng)過幾次垃圾回收來度量忆首。
      Python默認(rèn)定義了三代對象集合爱榔,索引數(shù)越大,對象存活時(shí)間越長雄卷。
      舉例: 當(dāng)某些內(nèi)存塊M經(jīng)過了3次垃圾收集的清洗之后還存活時(shí)搓蚪,我們就將內(nèi)存塊M劃到一個(gè)集合A中去蛤售,而新分配的內(nèi)存都劃分到集合B中去丁鹉。當(dāng)垃圾收集開始工作時(shí),大多數(shù)情況都只對集合B進(jìn)行垃圾回收悴能,而對集合A進(jìn)行垃圾回收要隔相當(dāng)長一段時(shí)間后才進(jìn)行揣钦,這就使得垃圾收集機(jī)制需要處理的內(nèi)存少了,效率自然就提高了漠酿。在這個(gè)過程中冯凹,集合B中的某些內(nèi)存塊由于存活時(shí)間長而會(huì)被轉(zhuǎn)移到集合A中,當(dāng)然炒嘲,集合A中實(shí)際上也存在一些垃圾宇姚,這些垃圾的回收會(huì)因?yàn)檫@種分代的機(jī)制而被延遲。
  13. 當(dāng)退出python時(shí)是否釋放所有內(nèi)存分配夫凸?
    循環(huán)引用其他對象或引用自全局命名空間的對象的模塊浑劳,在 Python 退出時(shí)并非完全釋放。另外夭拌,也不會(huì)釋放 c 庫保留的內(nèi)存部分

  14. GIL全局解釋器鎖
    每個(gè)線程在執(zhí)行的過程都需要先獲取 GIL魔熏,保證同一時(shí)刻只有一個(gè)線程可以執(zhí)行代碼衷咽。
    線程釋放 GIL 鎖的情況:在 IO 操作等可能會(huì)引起阻塞的 systemcall 之前,可以暫時(shí)釋放 GIL,但在執(zhí)行完畢后, 必須重新獲取 GIL蒜绽,Python3.x 使用計(jì)時(shí)器(執(zhí)行時(shí)間達(dá)到閾值后镶骗,當(dāng)前線程釋放 GIL。
    對于io密集型任務(wù)躲雅,python的多線程起到作用鼎姊,但對于cpu密集型任務(wù),python的多線程幾乎占不到任何優(yōu)勢相赁,還有可能因?yàn)闋帄Z資源而變慢此蜈。

計(jì)算機(jī)網(wǎng)絡(luò)

  1. TCP和UDP?
    TCP提供面向連接的噪生、可靠的數(shù)據(jù)流傳輸裆赵,而UDP提供的是非面向連接的、不可靠的數(shù)據(jù)流傳輸跺嗽。
    TCP傳輸單位稱為TCP報(bào)文段战授,UDP傳輸單位稱為用戶數(shù)據(jù)報(bào)。
    TCP注重?cái)?shù)據(jù)安全性桨嫁,UDP數(shù)據(jù)傳輸快植兰,因?yàn)椴恍枰B接等待,少了許多操作璃吧,但是其安全性卻一般楣导。
    TCP對應(yīng)的協(xié)議和UDP對應(yīng)的協(xié)議
    TCP對應(yīng)的協(xié)議:
    (1) FTP:定義了文件傳輸協(xié)議,使用21端口畜挨。
    (2) Telnet:一種用于遠(yuǎn)程登陸的端口筒繁,使用23端口,用戶可以以自己的身份遠(yuǎn)程連接到計(jì)算機(jī)上巴元,可提供基于DOS模式下的通信服務(wù)毡咏。
    (3) SMTP:郵件傳送協(xié)議,用于發(fā)送郵件逮刨。服務(wù)器開放的是25號端口呕缭。
    (4) POP3:它是和SMTP對應(yīng),POP3用于接收郵件修己。POP3協(xié)議所用的是110端口恢总。
    (5)HTTP:是從Web服務(wù)器傳輸超文本到本地瀏覽器的傳送協(xié)議。
    UDP對應(yīng)的協(xié)議:
    (1) DNS:用于域名解析服務(wù)睬愤,將域名地址轉(zhuǎn)換為IP地址片仿。DNS用的是53號端口。
    (2) SNMP:簡單網(wǎng)絡(luò)管理協(xié)議戴涝,使用161號端口滋戳,是用來管理網(wǎng)絡(luò)設(shè)備的钻蔑。由于網(wǎng)絡(luò)設(shè)備很多,無連接的服務(wù)就體現(xiàn)出其優(yōu)勢奸鸯。
    (3) TFTP(Trival File Transfer Protocal)咪笑,簡單文件傳輸協(xié)議,該協(xié)議在熟知端口69上使用UDP服務(wù)娄涩。

  2. 三次握手和四次揮手窗怒?
    三次握手

    1. 客戶端通過向服務(wù)器端發(fā)送一個(gè)SYN來創(chuàng)建一個(gè)主動(dòng)打開,作為三次握手的一部分蓄拣⊙镄椋客戶端把這段連接的序號設(shè)定為隨機(jī)數(shù) A。
    2. 服務(wù)器端應(yīng)當(dāng)為一個(gè)合法的SYN回送一個(gè)SYN/ACK球恤。ACK 的確認(rèn)碼應(yīng)為 A+1辜昵,SYN/ACK 包本身又有一個(gè)隨機(jī)序號 B。
    3. 最后咽斧,客戶端再發(fā)送一個(gè)ACK堪置。當(dāng)服務(wù)端受到這個(gè)ACK的時(shí)候,就完成了三路握手张惹,并進(jìn)入了連接創(chuàng)建狀態(tài)舀锨。此時(shí)包序號被設(shè)定為收到的確認(rèn)號 A+1,而響應(yīng)則為 B+1宛逗。

    四次揮手
    注意: 中斷連接端可以是客戶端坎匿,也可以是服務(wù)器端. 下面僅以客戶端斷開連接舉例, 反之亦然.

    1. 客戶端發(fā)送一個(gè)數(shù)據(jù)分段, 其中的 FIN 標(biāo)記設(shè)置為1. 客戶端進(jìn)入 FIN-WAIT 狀態(tài). 該狀態(tài)下客戶端只接收數(shù)據(jù), 不再發(fā)送數(shù)據(jù).
    2. 服務(wù)器接收到帶有 FIN = 1 的數(shù)據(jù)分段, 發(fā)送帶有 ACK = 1 的剩余數(shù)據(jù)分段, 確認(rèn)收到客戶端發(fā)來的 FIN 信息.
    3. 服務(wù)器等到所有數(shù)據(jù)傳輸結(jié)束, 向客戶端發(fā)送一個(gè)帶有 FIN = 1 的數(shù)據(jù)分段, 并進(jìn)入 CLOSE-WAIT 狀態(tài), 等待客戶端發(fā)來帶有 ACK = 1 的確認(rèn)報(bào)文.
    4. 客戶端收到服務(wù)器發(fā)來帶有 FIN = 1 的報(bào)文, 返回 ACK = 1 的報(bào)文確認(rèn), 為了防止服務(wù)器端未收到需要重發(fā), 進(jìn)入 TIME-WAIT 狀態(tài). 服務(wù)器接收到報(bào)文后關(guān)閉連接. 客戶端等待 2MSL 后未收到回復(fù), 則認(rèn)為服務(wù)器成功關(guān)閉, 客戶端關(guān)閉連接.
  3. TCP連接狀態(tài)?
    CLOSED:初始狀態(tài)雷激。
    LISTEN:服務(wù)器處于監(jiān)聽狀態(tài)替蔬。
    SYN_SEND:客戶端socket執(zhí)行CONNECT連接,發(fā)送SYN包侥锦,進(jìn)入此狀態(tài)进栽。
    SYN_RECV:服務(wù)端收到SYN包并發(fā)送服務(wù)端SYN包德挣,進(jìn)入此狀態(tài)恭垦。
    ESTABLISH:表示連接建立「裥幔客戶端發(fā)送了最后一個(gè)ACK包后進(jìn)入此狀態(tài)番挺,服務(wù)端接收到ACK包后進(jìn)入此狀態(tài)。
    FIN_WAIT_1:終止連接的一方(通常是客戶機(jī))發(fā)送了FIN報(bào)文后進(jìn)入屯掖。等待對方FIN玄柏。
    CLOSE_WAIT:(假設(shè)服務(wù)器)接收到客戶機(jī)FIN包之后等待關(guān)閉的階段。在接收到對方的FIN包之后贴铜,自然是需要立即回復(fù)ACK包的粪摘,表示已經(jīng)知道斷開請求瀑晒。但是本方是否立即斷開連接(發(fā)送FIN包)取決于是否還有數(shù)據(jù)需要發(fā)送給客戶端,若有徘意,則在發(fā)送FIN包之前均為此狀態(tài)苔悦。
    FIN_WAIT_2:此時(shí)是半連接狀態(tài),即有一方要求關(guān)閉連接椎咧,等待另一方關(guān)閉玖详。客戶端接收到服務(wù)器的ACK包勤讽,但并沒有立即接收到服務(wù)端的FIN包蟋座,進(jìn)入FIN_WAIT_2狀態(tài)。
    LAST_ACK:服務(wù)端發(fā)動(dòng)最后的FIN包脚牍,等待最后的客戶端ACK響應(yīng)向臀,進(jìn)入此狀態(tài)。
    TIME_WAIT:客戶端收到服務(wù)端的FIN包诸狭,并立即發(fā)出ACK包做最后的確認(rèn)飒硅,在此之后的2MSL時(shí)間稱為TIME_WAIT狀態(tài)。

  4. 在瀏覽器中輸入網(wǎng)址后執(zhí)行的全部過程
    1.查詢DNS獲取域名對應(yīng)IP 2.瀏覽器與對應(yīng)IP發(fā)起HTTP三次握手 3.TCP/IP連接建立起來之后瀏覽器就可以向服務(wù)器發(fā)送HTTP請求了 4. TLS握手 5. HTTP服務(wù)器請求處理并根據(jù)請求參數(shù)返回一些經(jīng)過后端處理生成的HTML頁面代碼 6.瀏覽器拿到代碼開始解析和渲染作谚,最終把完整的頁面呈現(xiàn)給用戶

  5. HTTP是無狀態(tài)的如何實(shí)現(xiàn)識(shí)別用戶呢三娩?(Cookie和Session)

    • session一般是服務(wù)器生成之后給客戶端(通過url參數(shù)或cookie)
    • cookie是實(shí)現(xiàn)session的一種機(jī)制,通過HTTPcookie字段實(shí)現(xiàn)
    • session通過在服務(wù)器保存sessionid識(shí)別用戶客戶端
  6. HTTP和HTTPS的區(qū)別

    • http是HTTP協(xié)議運(yùn)行在TCP之上妹懒。所有傳輸?shù)膬?nèi)容都是明文雀监,客戶端和服務(wù)器端都無法驗(yàn)證對方的身份。
    • https是HTTP運(yùn)行在SSL/TLS之上眨唬,SSL/TLS運(yùn)行在TCP之上会前。所有傳輸?shù)膬?nèi)容都經(jīng)過加密,加密采用對稱加密匾竿,但對稱加密的密鑰用服務(wù)器方的證書進(jìn)行了非對稱加密瓦宜。此外客戶端可以驗(yàn)證服務(wù)器端的身份,如果配置了客戶端驗(yàn)證岭妖,服務(wù)器方也可以驗(yàn)證客戶端的身份临庇。
    • https協(xié)議需要到ca申請證書,一般免費(fèi)證書很少昵慌,需要交費(fèi)假夺。
    • http是超文本傳輸協(xié)議,信息是明文傳輸斋攀,https 則是具有安全性的ssl加密傳輸協(xié)議
    • http和https使用的是完全不同的連接方式用的端口也不一樣,前者是80,后者是443已卷。
    • http的連接很簡單,是無狀態(tài)的
    • HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議 要比http協(xié)議安全
  7. 請求和響應(yīng)的組成淳蔼?
    請求:狀態(tài)行 (POST / HTTP/1.1)請求頭(常用HTTP請求頭)消息主體(GET為空)
    響應(yīng):狀態(tài)行(HTTP/1.1 200 OK)響應(yīng)頭(常見HTTP響應(yīng)頭)響應(yīng)正文

  8. 常見響應(yīng)狀態(tài)碼侧蘸?

    狀態(tài)碼 類別 原因短語
    1XX Informational(信息性狀態(tài)碼) 接收的請求正在處理
    2XX Success(成功狀態(tài)碼) 請求正常處理完畢
    3XX Redirection(重定向狀態(tài)碼) 需要進(jìn)行附加操作以完成請求
    4XX Client Error(客戶端錯(cuò)誤狀態(tài)碼) 服務(wù)器無法處理請求
    5XX Server Error(服務(wù)器錯(cuò)誤狀態(tài)碼) 服務(wù)器處理請求出錯(cuò)

    100 Continue :表明到目前為止都很正常裁眯,客戶端可以繼續(xù)發(fā)送請求或者忽略這個(gè)響應(yīng)。
    200 OK
    301 Moved Permanently :永久性重定向
    302 Found :臨時(shí)性重定向
    400 Bad Request :請求報(bào)文中存在語法錯(cuò)誤讳癌。
    401 Unauthorized :該狀態(tài)碼表示發(fā)送的請求需要有認(rèn)證信息(BASIC 認(rèn)證未状、DIGEST 認(rèn)證)。如果之前已進(jìn)行過一次請求析桥,則表示用戶認(rèn)證失敗司草。
    403 Forbidden :請求被拒絕,服務(wù)器端沒有必要給出拒絕的詳細(xì)理由泡仗。
    404 Not Found
    500 Internal Server Error :服務(wù)器正在執(zhí)行請求時(shí)發(fā)生錯(cuò)誤埋虹。
    503 Service Unavailable :服務(wù)器暫時(shí)處于超負(fù)載或正在進(jìn)行停機(jī)維護(hù),現(xiàn)在無法處理請求娩怎。

  9. GET和POST的區(qū)別
    GET 被強(qiáng)制服務(wù)器支持
    瀏覽器對URL的長度有限制搔课,所以GET請求不能代替POST請求發(fā)送大量數(shù)據(jù)
    GET請求發(fā)送數(shù)據(jù)更小
    GET請求是不安全的
    GET請求是冪等的
    冪等的意味著對同一URL的多個(gè)請求應(yīng)該返回同樣的結(jié)果
    POST請求不能被緩存
    POST請求相對GET請求是「安全」的
    這里安全的含義僅僅是指是非修改信息
    GET用于信息獲取,而且是安全的和冪等的
    所謂安全的意味著該操作用于獲取信息而非修改信息截亦。換句話說爬泥,GET 請求一般不應(yīng)產(chǎn)生副作用。就是說崩瓤,它僅僅是獲取資源信息袍啡,就像數(shù)據(jù)庫查詢一樣,不會(huì)修改却桶,增加數(shù)據(jù)境输,不會(huì)影響資源的狀態(tài)。
    POST是用于修改服務(wù)器上的資源的請求
    發(fā)送包含未知字符的用戶輸入時(shí)颖系,POST 比 GET 更穩(wěn)定也更可靠
    引申:說完原理性的問題嗅剖,我們從表面上來看看GET和POST的區(qū)別:
    GET是從服務(wù)器上獲取數(shù)據(jù),POST是向服務(wù)器傳送數(shù)據(jù)嘁扼。 GET和 POST只是一種傳遞數(shù)據(jù)的方式信粮,GET也可以把數(shù)據(jù)傳到服務(wù)器,他們的本質(zhì)都是發(fā)送請求和接收結(jié)果趁啸。只是組織格式和數(shù)據(jù)量上面有差別强缘,http協(xié)議里面有介紹
    GET是把參數(shù)數(shù)據(jù)隊(duì)列加到提交表單的ACTION屬性所指的URL中,值和表單內(nèi)各個(gè)字段一一對應(yīng)莲绰,在URL中可以看到欺旧。POST是通過HTTP POST機(jī)制,將表單內(nèi)各個(gè)字段與其內(nèi)容放置在HTML HEADER內(nèi)一起傳送到ACTION屬性所指的URL地址蛤签。用戶看不到這個(gè)過程。 因?yàn)镚ET設(shè)計(jì)成傳輸小數(shù)據(jù)栅哀,而且最好是不修改服務(wù)器的數(shù)據(jù)震肮,所以瀏覽器一般都在地址欄里面可以看到称龙,但POST一般都用來傳遞大數(shù)據(jù),或比較隱私的數(shù)據(jù)戳晌,所以在地址欄看不到鲫尊,能不能看到不是協(xié)議規(guī)定,是瀏覽器規(guī)定的沦偎。
    對于GET方式疫向,服務(wù)器端用Request.QueryString獲取變量的值,對于POST方式豪嚎,服務(wù)器端用Request.Form獲取提交的數(shù)據(jù)搔驼。 沒明白,怎么獲得變量和你的服務(wù)器有關(guān)侈询,和GET或POST無關(guān)舌涨,服務(wù)器都對這些請求做了封裝
    GET傳送的數(shù)據(jù)量較小,不能大于2KB扔字。POST傳送的數(shù)據(jù)量較大囊嘉,一般被默認(rèn)為不受限制。但理論上革为,IIS4中最大量為80KB扭粱,IIS5中為100KB。 POST基本沒有限制震檩,我想大家都上傳過文件焊刹,都是用POST方式的。只不過要修改form里面的那個(gè)type參數(shù)
    GET安全性非常低恳蹲,POST安全性較高虐块。 如果沒有加密,他們安全級別都是一樣的嘉蕾,隨便一個(gè)監(jiān)聽器都可以把所有的數(shù)據(jù)監(jiān)聽到贺奠。

  10. 長/短連接的優(yōu)缺點(diǎn)?
    長連接可以省去較多的TCP建立和關(guān)閉的操作错忱,減少浪費(fèi)儡率,節(jié)約時(shí)間。
    對于頻繁請求資源的客戶來說以清,較適用長連接儿普。
    client與server之間的連接如果一直不關(guān)閉的話,會(huì)存在一個(gè)問題掷倔,
    隨著客戶端連接越來越多眉孩,server早晚有扛不住的時(shí)候,這時(shí)候server端需要采取一些策略,
    如關(guān)閉一些長時(shí)間沒有讀寫事件發(fā)生的連接浪汪,這樣可以避免一些惡意連接導(dǎo)致server端服務(wù)受損巴柿;
    如果條件再允許就可以以客戶端機(jī)器為顆粒度,限制每個(gè)客戶端的最大長連接數(shù)死遭,
    這樣可以完全避免某個(gè)蛋疼的客戶端連累后端服務(wù)广恢。
    短連接對于服務(wù)器來說管理較為簡單,存在的連接都是有用的連接呀潭,不需要額外的控制手段钉迷。
    但如果客戶請求頻繁,將在TCP的建立和關(guān)閉操作上浪費(fèi)時(shí)間和帶寬钠署。

  11. TCP長/短連接的應(yīng)用場景糠聪?
    長連接多用于操作頻繁,點(diǎn)對點(diǎn)的通訊踏幻,而且連接數(shù)不能太多情況枷颊。
    每個(gè)TCP連接都需要三次握手,這需要時(shí)間该面,如果每個(gè)操作都是先連接夭苗,
    再操作的話那么處理速度會(huì)降低很多,所以每個(gè)操作完后都不斷開隔缀,
    再次處理時(shí)直接發(fā)送數(shù)據(jù)包就OK了题造,不用建立TCP連接。
    例如:數(shù)據(jù)庫的連接用長連接猾瘸,如果用短連接頻繁的通信會(huì)造成socket錯(cuò)誤界赔,
    而且頻繁的socket 創(chuàng)建也是對資源的浪費(fèi)。
    而像WEB網(wǎng)站的http服務(wù)一般都用短鏈接牵触,因?yàn)殚L連接對于服務(wù)端來說會(huì)耗費(fèi)一定的資源淮悼,
    而像WEB網(wǎng)站這么頻繁的成千上萬甚至上億客戶端的連接用短連接會(huì)更省一些資源,
    如果用長連接揽思,而且同時(shí)有成千上萬的用戶袜腥,如果每個(gè)用戶都占用一個(gè)連接的話,
    那可想而知吧钉汗。所以并發(fā)量大羹令,但每個(gè)用戶無需頻繁操作情況下需用短連好。

  12. 什么是IO多路復(fù)用损痰?
    操作系統(tǒng)提供的同事監(jiān)聽多個(gè)socket的機(jī)制福侈,一般阻塞 I/O 只能阻塞一個(gè) I/O 操作,而 I/O 復(fù)用模型能夠阻塞多個(gè) I/O 操作卢未,所以才叫做多路復(fù)用肪凛。
    I/O 多路復(fù)用是用于提升效率堰汉,單個(gè)進(jìn)程可以同時(shí)監(jiān)聽多個(gè)網(wǎng)絡(luò)連接 IO。 在 IO 密集型的系統(tǒng)中显拜, 相對于線程切換的開銷問題衡奥,IO 多路復(fù)用可以極大的提升系統(tǒng)效率爹袁。

  13. select远荠、poll、epoll 模型的區(qū)別失息?
    select譬淳,poll,epoll 都是 IO 多路復(fù)用的機(jī)制盹兢。I/O 多路復(fù)用就通過一種機(jī)制邻梆,可以監(jiān)視多個(gè)描述符,一旦某個(gè)描述符就緒(一般是讀就緒或者寫就緒)绎秒,能夠通知程序進(jìn)行相應(yīng)的讀寫操作浦妄。
    select 模型: select 目前幾乎在所有的平臺(tái)上支持,其良好跨平臺(tái)支持也是它的一個(gè)優(yōu)點(diǎn)见芹。select 的一 個(gè)缺點(diǎn)在于單個(gè)進(jìn)程能夠監(jiān)視的文件描述符的數(shù)量存在最大限制剂娄,在 Linux 上一般為 1024,可以通過修改宏定義甚至重新編譯內(nèi)核的方式提升這一限制玄呛,但 是這樣也會(huì)造成效率的降低阅懦。
    poll 模型: poll 和 select 的實(shí)現(xiàn)非常類似,本質(zhì)上的區(qū)別就是存放 fd 集合的數(shù)據(jù)結(jié)構(gòu)不一樣徘铝。select 在一個(gè)進(jìn)程內(nèi)可以維持最多 1024 個(gè)連接耳胎,poll 在此基礎(chǔ)上做了加強(qiáng),可以維持任意數(shù)量的連接惕它。
    但 select 和 poll 方式有一個(gè)很大的問題就是怕午,我們不難看出來 select 是通過輪訓(xùn)的方式來查找是否可讀或者可寫,打個(gè)比方淹魄,如果同時(shí)有 100 萬個(gè)連接都沒有斷開郁惜,而只有一個(gè)客戶端發(fā)送了數(shù)據(jù),所以這里它還是需要循環(huán)這么多次揭北,造成資源浪費(fèi)扳炬。所以后來出現(xiàn)了 epoll 系統(tǒng)調(diào)用。
    epoll 模型: epoll 是 select 和 poll 的增強(qiáng)版搔体,epoll 同 poll 一樣恨樟,文件描述符數(shù)量無限制。但是也并不是所有情況下 epoll 都比 select/poll 好疚俱,比如在如下場景:在大多數(shù)客戶端都很活躍的情況下劝术,系統(tǒng)會(huì)把所有的回調(diào)函數(shù)都喚醒,所以會(huì)導(dǎo)致負(fù)載較高。既然要處理這么多的連接养晋,那倒不如 select 遍歷簡單有效衬吆。

數(shù)據(jù)庫

  1. 什么是事務(wù)?
    數(shù)據(jù)庫事務(wù)(Database Transaction) 绳泉,是指作為單個(gè)邏輯工作單元執(zhí)行的一系列操作逊抡,要么完全地執(zhí)行,要么完全地不執(zhí)行零酪。
    AUTOCOMMIT
    MySQL 默認(rèn) 自動(dòng)提交模式冒嫡。也就是說,如果不顯式使用 START TRANSACTION 語句來開始一個(gè)事務(wù)四苇,那么每個(gè)查詢都會(huì)被當(dāng)做一個(gè)事務(wù)自動(dòng)提交

  2. 數(shù)據(jù)庫ACID孝凌?
    原子性:一個(gè)事務(wù)中所有操作全部成功或失敗
    一致性:事務(wù)開始和結(jié)束之后數(shù)據(jù)完整性沒有被破壞
    隔離性:允許多個(gè)事務(wù)同時(shí)對數(shù)據(jù)庫修改和讀取
    持久性:事務(wù)結(jié)束后,修改是用久不會(huì)丟失的


  3. 三范式月腋?
    1NF:屬性不可分
    2NF:屬性完全依賴于主鍵 [消除部分子函數(shù)依賴]
    3NF:屬性不依賴于其它非主屬性 [消除傳遞依賴]

  4. 并發(fā)一致性問題蟀架?
    丟失修改:并發(fā)的寫入造成其中一些修改丟失
    臟讀:一個(gè)事務(wù)讀取到另一個(gè)事務(wù)沒有提交的修改
    幻讀:在一個(gè)事務(wù)第二次查出現(xiàn)第一次沒有的結(jié)構(gòu)
    非重復(fù)讀:一個(gè)事務(wù)重復(fù)讀兩次得到的結(jié)果不一樣

  5. 事務(wù)隔離級別(為解決并發(fā)異常)
    每種隔離級別解決一個(gè)問題
    讀未提交:的的事務(wù)可以讀取到未提交的改變
    讀已提交:只能讀取已經(jīng)提交的數(shù)據(jù)
    可重復(fù)讀:同一事務(wù)先后查詢結(jié)果一樣(mysql innoDB默認(rèn)實(shí)現(xiàn)可重復(fù)讀級別)
    串行化:事務(wù)玩去串行化的執(zhí)行,隔離級別最高榆骚,執(zhí)行效率最低

  6. 你所知道的鎖片拍?
    樂觀鎖(先修改,更新時(shí)發(fā)現(xiàn)數(shù)據(jù)已經(jīng)變了就回滾)
    用數(shù)據(jù)版本(Version)記錄機(jī)制實(shí)現(xiàn)寨躁,這是樂觀鎖最常用的一種實(shí)現(xiàn)方式穆碎。何謂數(shù)據(jù)版本?即為數(shù)據(jù)增加一個(gè)版本標(biāo)識(shí)职恳,一般是通過為數(shù)據(jù)庫表增加一個(gè)數(shù)字類型的 “version” 字段來實(shí)現(xiàn)所禀。當(dāng)讀取數(shù)據(jù)時(shí),將version字段的值一同讀出放钦,數(shù)據(jù)每更新一次色徘,對此version值加1。當(dāng)我們提交更新的時(shí)候操禀,判斷數(shù)據(jù)庫表對應(yīng)記錄的當(dāng)前版本信息與第一次取出來的version值進(jìn)行比對褂策,如果數(shù)據(jù)庫表當(dāng)前版本號與第一次取出來的version值相等,則予以更新颓屑,否則認(rèn)為是過期數(shù)據(jù)斤寂。



    悲觀鎖(一鎖二查三更新)
    與樂觀鎖相對應(yīng)的就是悲觀鎖了。悲觀鎖就是在操作數(shù)據(jù)時(shí)揪惦,認(rèn)為此操作會(huì)出現(xiàn)數(shù)據(jù)沖突遍搞,所以在進(jìn)行每次操作時(shí)都要通過獲取鎖才能進(jìn)行對相同數(shù)據(jù)的操作,所以悲觀鎖需要耗費(fèi)較多的時(shí)間器腋。另外與樂觀鎖相對應(yīng)的溪猿,悲觀鎖是由數(shù)據(jù)庫自己實(shí)現(xiàn)了的钩杰,要用的時(shí)候,我們直接調(diào)用數(shù)據(jù)庫的相關(guān)語句就可以了诊县。

    • 排它鎖
      排它鎖exclusive lock(也叫 writer lock)又稱寫鎖讲弄。排它鎖是悲觀鎖的一種實(shí)現(xiàn)。
      若事務(wù) 1 對數(shù)據(jù)對象 A 加上 X 鎖依痊,事務(wù) 1 可以讀 A 也可以修改 A避除,其他事務(wù)不能再對 A 加任何鎖,直到事物 1 釋放 A 上的鎖抗悍。這保證了其他事務(wù)在事物 1 釋放 A 上的鎖之前不能再讀取和修改 A驹饺。排它鎖會(huì)阻塞所有的排它鎖和共享鎖
      讀取為什么要加讀鎖呢:防止數(shù)據(jù)在被讀取的時(shí)候被別的線程加上寫鎖

      使用方式:在需要執(zhí)行的語句后面加上 for update 就可以了
    • 共享鎖
      共享鎖又稱讀鎖(read lock)钳枕,是讀取操作創(chuàng)建的鎖缴渊。其他用戶可以并發(fā)讀取數(shù)據(jù),但任何事務(wù)都不能對數(shù)據(jù)進(jìn)行修改(獲取數(shù)據(jù)上的排他鎖)鱼炒,直到已釋放所有共享鎖衔沼。
      如果事務(wù) T 對數(shù)據(jù) A 加上共享鎖后,則其他事務(wù)只能對 A 再加共享鎖昔瞧,不能加排他鎖指蚁。獲得共享鎖的事務(wù)只能讀數(shù)據(jù),不能修改數(shù)據(jù)



      在查詢語句后面增加 lock in share mode自晰,MySQL 會(huì)對查詢結(jié)果中的每行都加共享鎖凝化,當(dāng)沒有其他線程對查詢結(jié)果集中的任何一行使用排他鎖時(shí),可以成功申請共享鎖酬荞,否則會(huì)被阻塞搓劫。其他線程也可以讀取使用了共享鎖的表,而且這些線程讀取的是同一個(gè)版本的數(shù)據(jù)混巧。
      加上共享鎖后枪向,對于 update,insert,delete 語句會(huì)自動(dòng)加排它鎖。

  7. 什么是索引咧党?
    索引是數(shù)據(jù)表中一個(gè)或多個(gè)列進(jìn)行排序的數(shù)據(jù)結(jié)構(gòu)
    索引能大幅度提升檢索速度
    創(chuàng)建秘蛔、更新索引本身也會(huì)消耗時(shí)間和空間

  8. 什么是B-Tree?
    多路平衡查找樹(每個(gè)節(jié)點(diǎn)最多m(m>=2)個(gè)孩子傍衡,稱為m階或者度)
    葉節(jié)點(diǎn)具有相同的深度
    節(jié)點(diǎn)中的數(shù)據(jù)key從左到右是遞增的

  9. 什么是B+Tree深员?
    mysql實(shí)際使用B+Tree作為輸贏的數(shù)據(jù)結(jié)構(gòu)
    只在葉子節(jié)點(diǎn)帶有指向記錄的指針(可以增加樹的度)
    葉子節(jié)點(diǎn)通過指針相連(實(shí)現(xiàn)范圍查找)

  10. mysql索引類型
    普通索引CREATE INDEX
    唯一索引,索引列的值必須唯一CREATE UNIQUE INDEX
    主鍵索引PRIMARY KEY一個(gè)表只能有一個(gè)
    全文索引FULLTEXT INDEX蛙埂,InnoDB不支持

  11. 什么時(shí)候創(chuàng)建索引倦畅?
    經(jīng)常用到查詢條件的字段WHERE條件
    經(jīng)常用作表連接的字段
    經(jīng)常出現(xiàn)在ORDER BY, GROUP BY之后的字段

  12. 知道Redis嗎?
    是一個(gè)完全開源免費(fèi)的key-value內(nèi)存數(shù)據(jù)庫
    通常被認(rèn)為是一個(gè)數(shù)據(jù)結(jié)構(gòu)服務(wù)器箱残,主要是因?yàn)槠溆兄S富的數(shù)據(jù)結(jié)構(gòu)
    string:可以是字符串滔迈、整數(shù)或浮點(diǎn)數(shù)
    list:一個(gè)鏈表止吁,鏈表上的每個(gè)節(jié)點(diǎn)都包含了一個(gè)字符串
    set:包含字符串的無序收集器,并且被包含的每個(gè)字符串都是獨(dú)一無二的燎悍、各不相同
    zset:字符串成員與浮點(diǎn)數(shù)分值之間的有序映射敬惦,元素的排列順序由分值的大小決定
    hash:包含鍵值對的無序散列表

  13. 了解Redis的事務(wù)嗎?
    簡單理解谈山,可以認(rèn)為 redis 事務(wù)是一些列 redis 命令的集合俄删,并且有如下兩個(gè)特點(diǎn): 1.事務(wù)是一個(gè)單獨(dú)的隔離操作:事務(wù)中的所有命令都會(huì)序列化、按順序地執(zhí)行奏路。事務(wù)在執(zhí)行的過程中畴椰,不會(huì)被其他客戶端發(fā)送來的命令請求所打斷。 2.事務(wù)是一個(gè)原子操作:事務(wù)中的命令要么全部被執(zhí)行鸽粉,要么全部都不執(zhí)行斜脂。 一般來說,事務(wù)有四個(gè)性質(zhì)稱為ACID触机,分別是原子性帚戳,一致性,隔離性和持久性儡首。 一個(gè)事務(wù)從開始到執(zhí)行會(huì)經(jīng)歷以下三個(gè)階段:開始事務(wù)片任、命令入隊(duì)、執(zhí)行事務(wù)
    代碼示例:

    import redis
    import sys
    def run():   
        try:
            conn=redis.StrictRedis('192.168.80.41')
           # Python中redis事務(wù)是通過pipeline的封裝實(shí)現(xiàn)的
            pipe=conn.pipeline()
            pipe.sadd('s001','a')
            sys.exit()
            #在事務(wù)還沒有提交前退出蔬胯,所以事務(wù)不會(huì)被執(zhí)行对供。
            pipe.sadd('s001','b')
            pipe.execute()
            pass
        except Exception as err:
            print(err)
            pass
    if __name__=="__main__":
          run()
    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市氛濒,隨后出現(xiàn)的幾起案子产场,更是在濱河造成了極大的恐慌,老刑警劉巖泼橘,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涝动,死亡現(xiàn)場離奇詭異,居然都是意外死亡炬灭,警方通過查閱死者的電腦和手機(jī)醋粟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來重归,“玉大人米愿,你說我怎么就攤上這事”撬保” “怎么了育苟?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵靴姿,是天一觀的道長疗绣。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么逸贾? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任变擒,我火速辦了婚禮随静,結(jié)果婚禮上囚企,老公的妹妹穿的比我還像新娘。我一直安慰自己馍惹,他們只是感情好躺率,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著万矾,像睡著了一般悼吱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上良狈,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天后添,我揣著相機(jī)與錄音,去河邊找鬼们颜。 笑死吕朵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的窥突。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼硫嘶,長吁一口氣:“原來是場噩夢啊……” “哼阻问!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起沦疾,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤称近,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后哮塞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體刨秆,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年忆畅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了衡未。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡家凯,死狀恐怖缓醋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绊诲,我是刑警寧澤送粱,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站掂之,受9級特大地震影響抗俄,放射性物質(zhì)發(fā)生泄漏脆丁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一动雹、第九天 我趴在偏房一處隱蔽的房頂上張望偎快。 院中可真熱鬧,春花似錦洽胶、人聲如沸晒夹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丐怯。三九已至,卻和暖如春翔横,著一層夾襖步出監(jiān)牢的瞬間读跷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工禾唁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留效览,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓荡短,卻偏偏與公主長得像丐枉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子掘托,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,100評論 1 32
  • 一瘦锹、簡歷準(zhǔn)備 1、個(gè)人技能 (1)自定義控件闪盔、UI設(shè)計(jì)弯院、常用動(dòng)畫特效 自定義控件 ①為什么要自定義控件? Andr...
    lucas777閱讀 5,202評論 2 54
  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說明:當(dāng)在唯一索引所對應(yīng)的列上鍵入重復(fù)值時(shí)泪掀,會(huì)觸發(fā)此異常听绳。 O...
    我想起個(gè)好名字閱讀 5,311評論 0 9
  • 不足的地方請大家多多指正,如有其它沒有想到的常問面試題請大家多多評論异赫,一起成長椅挣,感謝!~ String可以被繼承嗎...
    啟示錄是真的閱讀 2,936評論 3 3
  • 總體來說,今天還很開心 不過一直雖然不爽大于開心 但是畢竟時(shí)過境遷 機(jī)會(huì)慢慢少了 加油吧
    莫度茶閱讀 131評論 0 0