Python后端面試題


Python后端面試題

1.語言

Python面試,基礎相關問題少不了.

  • 提示:
    我希望聽到twisted->tornado->gevent

  • 答案:
    gevent
    代碼看起來好看一些,但是維護比較差,patch沒有規律,而且里面封裝了C,對python3的支持最差.
    twisted
    穩定性是最好的,但是需要較長時間的學習.對python3的支持較差.
    tornado
    兼容性最好.但是過於簡單了,功能不強,另外沒有python數據庫適配器能和tornado無縫對接,因此調用數據庫很麻煩,而且只支持web.

  • 提示:
    這幾個概念很容易混淆,建議通過邊畫圖,邊介紹的方式來表達.

  • 答案:
    迭代器
    (Iterator)迭代器是帶狀態的對象,它會記錄當前迭代所在的位置,以方便下次迭代的時候獲取正確的元素.
    生成器
    (generator)生成器和裝飾器是python中最吸引人的兩個黑科技,生成器雖沒有裝飾器那么常用,但在某些針對的情境下十分有效.
    裝飾器
    (Decorator)裝飾器是python中最吸引人的特性,裝飾器本質上還是一個函數,它可以讓已有的函數不做任何改動的情況下增加功能.

  • 提示:
    混淆視聽,其實Python隊列都是線程安全的,該問題主要考察你對隊列的了解和線程安全的概念.

  • 答案:
    線程
    線程安全和非線程安全這些概念在其他的編程語言也同樣使用.
    所謂線程安全:就是對於多線程同時操作是是安全的而不會發生寫沖突,比如python的Queue
    相反非線程安全:就是多線成同時操作時會發生寫沖突,比如python的其他list,set,dict
    隊列
    Python的Queue模塊中提供了同步的.線程安全的隊列類,包括FIFO(先入先出)隊列Queue,LIFO(后入先出)隊列LifoQueue,和優先級隊列PriorityQueue.這些隊列都實現了鎖原語,能夠在多線程中直接使用.可以使用隊列來實現線程間的同步.
    三種隊列
    Python queue模塊有三種隊列:
    1.FIFO隊列先進先出.(線程安全)
    2.LifoQueue類似於堆,即先進后出(線程安全)
    3.PriorityQueue優先級隊列,級別越低,越先出來(線程安全)
    隊列構造函數
    針對這三種隊列分別有三個構造函數:
    1.class Queue.Queue(maxsize) FIFO
    2.class Queue.LifoQueue(maxsize) LIFO
    3.class Queue.PriorityQueue(maxsize) 優先級隊列
    logging
    logging是Python標准庫里的日志模塊(線程安全)

2.操作系統

可以直接認為是linux,畢竟搞后端的多數是和linux打交道.

  • 提示:
    我希望聽到TCP粘包與分包,為什么會有這種情況,應該如何解決.能講到UDP是否會有同樣情況發生更好.

  • 答案:
    tcp/udp的區別
    TCP與UDP區別總結:
    1.TCP面向連接(如打電話要先撥號建立連接);UDP是無連接的,即發送數據之前不需要建立連接
    2.TCP提供可靠的服務.也就是說,通過TCP連接傳送的數據,無差錯,不丟失,不重復,且按序到達;UDP盡最大努力交付,即不保 證可靠交付
    3.TCP面向字節流,實際上是TCP把數據看成一連串無結構的字節流;UDP是面向報文的
    UDP沒有擁塞控制,因此網絡出現擁塞不會使源主機的發送速率降低(對實時應用很有用,如IP電話,實時視頻會議等)
    4.每一條TCP連接只能是點到點的;UDP支持一對一,一對多,多對一和多對多的交互通信
    5.TCP首部開銷20字節;UDP的首部開銷小,只有8個字節
    6.TCP的邏輯通信信道是全雙工的可靠信道,UDP則是不可靠信道
    關於分包和粘包
    粘包:發送方發送兩個字符串”hello”+”world”,接收方卻一次性接收到了”helloworld”.
    分包:發送方發送字符串”helloworld”,接收方卻接收到了兩個字符串”hello”和”world”.
    TCP為什么會分包
    TCP是以段(Segment)為單位發送數據的,建立TCP鏈接后,有一個最大消息長度(MSS).如果應用層數據包超過MSS,就會把應用層數據包拆分,分成兩個段來發送.這個時候接收端的應用層就要拼接這兩個TCP包,才能正確處理數據.
    TCP為什么會粘包
    有時候,TCP為了提高網絡的利用率,會使用一個叫做Nagle的算法.該算法是指,發送端即使有要發送的數據,如果很少的話,會延遲發送.如果應用層給TCP傳送數據很快的話,就會把兩個應用層數據包“粘”在一起,TCP最后只發一個TCP數據包給接收端.
    如何處理
    在進行TCP Socket開發時,都需要處理數據包粘包和分包的情況.使用的語言是Python.實際上解決該問題很簡單,在應用層下,定義一個協議:消息頭部+消息長度+消息正文即可.

  • 提示:
    考驗你對實際開發中遇到的常見問題,處理方式

  • 答案:
    使用netstat和awk命令來統計網絡連接數
    netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
    TIME_WAIT:表示主動關閉,通過優化系統內核參數可容易解決.
    CLOSE_WAIT:表示被動關閉,需要從程序本身出發.
    ESTABLISHED:表示正在通信過多CLOSE_WAIT原因
    出現大量close_wait的現象,主要原因是某種情況下對方關閉了socket鏈接,但是我方忙與讀或者寫,沒有關閉連接.代碼需要判斷socket,一旦讀到0,斷開連接,read返回負,檢查一下errno,如果不是AGAIN,就斷開連接.

  • 提示:
    考驗在linux開發中,服務器端處理請求的選擇問題

  • 答案:
    select和epoll這兩個機制都I/O復用的解決方案,select為POSIX標准中的,而epoll為Linux所特有.
    更多查看

3.存儲

存儲可能包含rdbms,nosql以及緩存等,我以mysql,redis舉例

3.1mysql相關

  • 提示:
    在服務器建表時字符集(Character Set)和排序規則(Collation)是必不可少的,對他了解多少,如何選擇.

  • 答案:
    字符集
    所謂字符集,就是用來定義字符在數據庫中的編碼的集合.常見的字符集有:utf8(支持中文)和ascii(不支持中文)
    排序規則
    數據庫中的排序規則,就是用來定義字符在進行排序和比較時的一種規則.常見的如下: 1.utf8_general_ci 不區分大小寫,utf8_general_cs 區分大小寫.2.utf8_bin 規定每個字符串用二進制編碼存儲,區分大小寫,可以直接存儲二進制的內容
    說明:所為排序規則,就是指字符比較時是否區分大小寫,以及是按照字符編碼進行比較還是直接用二進制數據比較.

總結:這邊用gbk_chinese_ci來做例子.
字符集名字語言后綴,其中各個典型后綴的含義如下:
1._ci:不區分大小寫的排序方式
2._cs:區分大小寫的排序方式
3._bin:二進制排序方式,大小比較將根據字符編碼,不涉及人類語言,因此_bin的排序方式不包含人類語言
因此gbk_chinese_ci排序方式就表示:字符集為gbk,人類語言使用中文來比較大小,比較時區分大小寫.

  • 提示:
    char與varchar這兩個字符類型在mysql中經常遇見,正確的使用,可以提高效率與避免空間上的浪費.

  • 答案:
    存數據時的區別
    char定義的是固定長度,長度范圍為0-255,存儲時,如果字符數沒有達到定義的位數,會在后面用空格補全存入數據庫中,在上例中,name實際存儲在數據中的數據為'zejin '
    varchar是變長長度,長度范圍為0-65535,存儲時,如果字符沒有達到定義的位數,也不會在后面補空格,在上例subject字段中,實際存儲在數據中的數據為'zejin ',當然還有一或兩個字節來描述該字節長度
    取數據時的區別
    數據庫取char的數據時,會把后面的空格全部丟棄掉,也就是說,在char中的尾部存入空格時,最后取出來都會被丟棄.而數據庫在取varchar數據時,尾部空格會保留.

  • 提示:
    primary key = unique + not null

  • 答案:
    Primary key與Unique Key都是唯一性約束.但二者有很大的區別:
    unique Key
    1.唯一鍵,一個表只能有一個PRIMARY KEY.
    2.Primary key的1個或多個列 必須為NOT NULL,如果列為NULL,在增加PRIMARY KEY時,列自動更改為NOT NULL.
    Primary key
    1.主鍵,一個表可以有多個UNIQUE KEY
    2.UNIQUE KEY 對列沒有NOT NULL或NULL的特殊要求.

  • 提示:
    主要考你對表的設計與優化.可以通過使用外鍵的優缺點來分析該問題.

  • 答案:
    外鍵是什么
    程序很難100%保證數據的完整性,而用外鍵即使在數據庫服務器down機或者出現其他問題的時候,也能夠最大限度的保證數據的一致性和完整性.
    是否該用外鍵
    因需而定,在大型系統中(性能要求不高,安全要求高),使用外鍵;在大型系統中(性能要求高,安全自己控制),不用外鍵;小系統隨便,最好用外鍵.
    外鍵是否需要索引
    加入外鍵的主要問題就是影響性能,因此加入索引能加快關聯查詢的速度.

  • 提示:
    希望看到你通過對兩者區別和針對公司的業務類型來選擇合適的表類型,這樣才能發揮mysql的性能優勢.

  • 答案:
    myisam與innodb是mysql的儲引擎.
    區別
    1.InnoDB支持事務,MyISAM不支持,對於InnoDB每一條SQL語言都默認封裝成事務,自動提交,這樣會影響速度,所以最好把多條SQL語言放在begin和commit之間,組成一個事務;
    2.InnoDB支持外鍵,而MyISAM不支持.對一個包含外鍵的InnoDB表轉為MYISAM會失敗;
    3.InnoDB是聚集索引,數據文件是和索引綁在一起的,必須要有主鍵,通過主鍵索引效率很高.但是輔助索引需要兩次查詢,先查詢到主鍵,然后再通過主鍵查詢到數據.因此,主鍵不應該過大,因為主鍵太大,其他索引也都會很大.而MyISAM是非聚集索引,數據文件是分離的,索引保存的是數據文件的指針.主鍵索引和輔助索引是獨立的.
    4.InnoDB不保存表的具體行數,執行select count() from table時需要全表掃描.MyISAM用一個變量保存了整個表的行數,執行上述語句時只需要讀出該變量即可,速度很快; *
    5.Innodb不支持全文索引,MyISAM支持全文索引,查詢效率上MyISAM要高;* *
    選擇
    1.是否要支持事務,如果要請選擇innodb,如果不需要可以考慮MyISAM
    2.如果表中絕大多數都只是讀查詢,可以考慮MyISAM,如果既有讀寫也挺頻繁,請使用InnoDB.
    3.系統奔潰后,MyISAM恢復起來更困難,能否接受;
    4.MySQL5.5版本開始Innodb已經成為Mysql的默認引擎*(之前是MyISAM),說明其優勢是有目共睹的,如果你不知道用什么,那就用InnoDB,至少不會差.

總結
讀操作多用MyISAM
寫操作多用InnoDB

  • 提示:
    鑒於創建索引需要額外的磁盤空間(,以及太多的索引會導致文件系統大小限制所產生的問題,所以對哪些字段建立索引,什么情況下使用索引,需要審慎考慮.

  • 答案:
    *索引作用
    MySQL索引在MySQL數據庫中,可以有效提高查詢的效率,尤其是查詢數據量非常大時,效果更為明顯,往往能使查詢速度加快成千上萬倍.
    索引原理
    MySQL索引主要有一下幾種索引類型:FULLTEXT,HASH,BTREE,RTREE,對不通類型有着不通的存儲引擎,如上面提到的MyISAM,InnoDB.
    使用注意
    並非所有的數據庫都以相同的方式使用索引.作為通用規則,只有當經常查詢索引列中的數據時,才需要在表上創建索引.索引占用磁盤空間,並且降低添加.刪除和更新行的速度.在多數情況下,索引用於數據檢索的速度優勢大大超過它的不足之處.但是,如果應用程序非常頻繁地更新數據或磁盤空間有限,則可能需要限制索引的數量.

3.2redis相關

  • 提示:
    不同需求不同場景有着不同選擇,一般可以redis+mysql聯用,如果可以涉及memcache,mongoDB這些no sql系列加分.

  • 答案:
    redis場景
    1.會話緩存(Session Cache)
    用Redis緩存會話比其他存儲(如Memcached)的優勢在於:Redis提供持久化.
    2.全頁緩存(FPC)
    即使重啟了Redis實例,因為有磁盤的持久化
    3.隊列
    Redis作為隊列使用的操作,就類似於本地程序語言(如Python)對 list 的 push/pop 操作.
    4.排行榜/計數器
    集合(Set)和有序集合(Sorted Set)也使得我們在執行這些操作的時候變的非常簡單
    5.發布/訂閱
    在社交網絡連接中使用,還可作為基於發布/訂閱的腳本觸發器,甚至用Redis的發布/訂閱功能來建立聊天系統
    redis與mysql
    這兩者是內存和硬盤的關系,硬盤放置主體數據用於持久化存儲,而內存則是當前運行的那部分數據,CPU訪問內存而不是磁盤,這大大提升了運行的速度,當然這是基於程序的局部化訪問原理.
    推理到redis+mysql,它是內存+磁盤關系的一個映射,mysql放在磁盤,redis放在內存,這樣的話,web應用每次只訪問redis,如果沒有找到的數據,才去訪問Mysql.

  • 提示:
    redis本身不處理分布式事物或者說它的事物非常弱,因為redis本身是單線程的.

  • 答案:
    通過Redis+Lua方案,Redis的事務對處理較復雜的業務需求非常有用.
    其次,Redis中實現事務有2種方式:
    1.使用MULIT,EXEC,DISCARD和WATCH等命令;
    2.使用Lua腳本封裝多個redis基本命令,來實現一個復雜的事務操作.
    3.DISCARD指令就是用來回滾的.

  • 提示:
    需要你描述解決該問題的過程(起因-分析-排查-解決)

  • 答案:
    當內存滿了,不允許再存數據,會出現錯誤OOM command not allowed when used memory > ‘maxmemory’

4.安全

Web安全與我們平時開發處處關聯,那么web開發需要在工作中注意哪些安全方面的問題?

<h4 id="4.1">4.1安全</h4>

  • 提示:
    對於一個有經驗的開發人員,代碼的書寫規范是門必修課,這里考的就是程序員對書寫sql語句中是否注意書寫規范.

  • 答案:
    sql不禁是Python中需要防范的問題,在其他語言也是個必不可少的問題,這里引用PHP的防注入方案.
    1.過濾掉一些常見的數據庫操作關鍵字:select,insert,update,delete,and,*等.或者通過系統函數:addslashes(需要被過濾的內容)來進行過濾.
    2.SQL語句書寫的時候盡量不要省略小引號(tab鍵上面那個)和單引號.
    3.提高數據庫命名技巧,對於一些重要的字段根據程序的特點命名,取不易被猜到的.
    4.對於常用的方法加以封裝,避免直接暴漏SQL語句.
    5.控制錯誤信息.
    關閉錯誤提示信息,將錯誤信息寫到系統日志.
    6.使用Mysqli和PDO連接mysql數據預處理.

  • 答案:
    什么是XSS攻擊
    XSS即跨站腳本攻擊,XSS是一種經常出現在web應用中的計算機安全漏洞,它允許惡意web用戶將代碼植入到提供給其它用戶使用的頁面中.簡單的說就是HTML注入問題.
    防止XSS攻擊的兩種方式
    1.對單一變量進行轉義過濾.可以使用escape過濾器,無需轉義時使用safe過濾器
    2.利用django的HTML自動轉義,無需autoescape 標簽,django中的HTML文檔會自動轉義.
  • 提示:
    用 django 有多久,跟 csrf 這個概念打交道就有久.
  • 答案:
    csrf是什么
    CSRF,跨站點偽造請求.顧名思義,就是是偽造請求,冒充用戶在站內的正常操作.
    通過Django來防范CSRF
    1.首先,最基本的原則是:GET 請求不要用有副作用.也就是說任何處理 GET 請求的代碼對資源的訪問都一定要是“只讀“的.
    2.啟用 django.middleware.csrf.CsrfViewMiddleware 這個中間件.
    3.再次,在所有的 POST 表單元素時,需要加上一個csrf_token的tag.
    4.在渲染模塊時,使用 render.它會處理 csrf_token 這個 tag,從而自動為表單添加一個名為csrfmiddlewaretoken 的 input.
    更多XSS與CSRF詳情見

4.2密碼技術

  • 簡單說說https的工作原理與http的區別?
  • 提示:
    希望可以講到里面使用了哪些加密算法

  • 答案:
    Https是一種基於SSL/TLS的Http協議,所有的http數據都是在SSL/TLS協議封裝之上傳輸的.
    Https協議在Http協議的基礎上,添加了SSL/TLS握手以及數據加密傳輸,也屬於應用層協議.
    1.HTTP協議運行在TCP之上,所有傳輸的內容都是明文,客戶端和服務器端都無法驗證對方的身份.
    2.HTTPS是運行在SSL/TLS之上的HTTP協議,SSL/TLS運行在TCP之上.所有傳輸的內容都經過加密,加密采用對稱加密,但對稱加密的密鑰用服務器方的證書進行了非對稱加密.

  • 說說https有什么優缺點?
  • 提示:
    從安全與性能方向回答.

  • 答案:
    優點
    1.使用 HTTPS 協議可認證用戶和服務器,確保數據發送到正確的客戶機和服務器;
    2.HTTPS 協議是由 SSL+HTTP 協議構建的可進行加密傳輸.身份認證的網絡協議, 要比 http 協議安全,可防止數據在傳輸過程中不被竊取.改變,確保數據的完整性.
    3.HTTPS 是現行架構下最安全的解決方案,雖然不是絕對安全,但它大幅增加了中間人攻擊的成本.
    缺點
    1.HTTPS 協議的加密范圍也比較有限,在黑客攻擊.拒絕服務攻擊.服務器劫持等方 面幾乎起不到什么作用
    2.HTTPS 協議還會影響緩存,增加數據開銷和功耗,甚至已有安全措施也會受到影響.
    3.SSL 證書需要錢.功能越強大的證書費用越高.個人網站.小網站沒有必要一般不會用.
    4.HTTPS 連接服務器端資源占用高很多,握手階段比較費時對網站的相應速度有負面 影響.
    5.HTTPS 連接緩存不如 HTTP 高效.

  • 提示:
    對稱加密高效不安全,非對稱加密安全不高效.

  • 答案:
    對稱加密
    對稱加密是指加密和解密使用的密鑰是同一個密鑰,或者可以相互推算.對稱加密的優點是算法簡單,加解密效率高,系統開銷小,適合對大數據量加密.缺點是解密加密使用同一個密鑰,需要考慮遠程通信的情況下如何安全的交換密鑰,如果密鑰丟失,所謂的加密解密就失效了.
    非對稱加密
    非對稱加密和解密使用的密鑰不是同一密鑰,其中一個對外界公開,被稱為公鑰,另一個只有所有者知道,
    稱作私鑰.
    用公鑰加密的信息必須用私鑰才能解開,反之,用私鑰加密的信息只有用公鑰才能解開.

5.總結

5.1新手需掌握技能點

  • 談談裝飾器,迭代器,yield,內存管理等
  • 計算密集型,IO密集型任務怎么辦
  • Tcp/Udp協議,Http協議
  • sql,cache, nosql
  • web安全相關,sql注入,xss等

5.2老鳥需掌握技能點

  • WSGI 和 FastCGI 的關系
  • Gevent 和 threading / multiprocessing 的關系
  • cookie 和 session 的關系,以及 xsrf 的攻擊和防范方法
  • Django 和 Tornado 的關系.差別
  • 考考數據庫知識,SQL 語法和調優,SQLAlchemy ,redis的用法
  • restfull 風格的api怎么寫


作者:林銳波
鏈接:https://www.jianshu.com/p/79f37b79c8e1
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM