1. 程式人生 > >Python常見面試題彙總(根據面試總結)

Python常見面試題彙總(根據面試總結)

Redis:

Redis快取擊穿、快取雪崩、快取重建

回答參考:

快取擊穿:

    當一個連線訪問快取資料庫中不存在的資料時,會直接通過快取資料庫到後端資料庫中查詢資料,但如果有大量連線在查詢一個不存在的資料,就會有大量連線直接訪問到後端資料庫,給後端伺服器造成巨大壓力,可能導致後臺伺服器崩潰的情況。  解決方案:當查詢一個不存在的快取資料時,訪問資料庫,如果發現後端資料庫也不存在這個檔案,將這個查詢的key在快取中儲存為None。下次再有連線請求這個key時直接從快取中返回。

 

快取雪崩:

    快取資料一般會設定過期時間,當所有的快取資料幾乎在同一時間過期時,會有大量資料直接訪問到後端資料庫,導致後端資料庫瞬間承受訪問壓力過大,可能導致後端資料庫崩潰。並且當資料庫重啟後,仍會有大量連線訪問到資料庫,可能導致再次崩潰。  解決方案:採用快取重建或快取預熱。

 

快取重建:

    Redis支援持久化操作,比如快取之類不重要的資料可以使用RDB持久化,可以恢復大部分快取內容到快取資料庫彙總,減少直接訪問後端資料庫的次數。

 

快取預熱:

    系統上線時手動載入一部分資料到快取資料庫,同樣也是為了減少快取資料庫中沒有資料,導致連線直接穿透到後端資料庫的情況。

 

Redis應用場景

回答參考:

    Redis是非關係型記憶體資料庫,要根據自己專案業務方向去思考Redis的應用場景,電商系統可以作為快取資料庫和訂單佇列,爬蟲系統可以作為URL佇列和去重。但畢竟Redis也是資料庫的一種,直接作為資料庫使用也是可以的。

 

Redis訂閱釋出機制

Redis提供了釋出訂閱功能,可以用於訊息的傳輸,Redis的釋出訂閱機制包括三個部分,釋出者,訂閱者和Channel 
釋出者和訂閱者都是Redis客戶端,Channel則為Redis伺服器端,釋出者將訊息傳送到某個的頻道,訂閱了這個頻道的訂閱者就能接收到這條訊息。Redis的這種釋出訂閱機制與基於主題的釋出訂閱類似,Channel相當於主題。

 

詳細介紹:

https://www.cnblogs.com/yitudake/p/6747995.html

https://blog.csdn.net/clh604/article/details/1975493


Redis叢集

回答參考:

    Redis叢集主要有主從叢集和哨兵叢集,主從叢集就是將多臺Redis伺服器配置Master-Slave,以達到分攤訪問壓力的目的,但有時候主伺服器也會有崩潰,斷電或其他導致宕機的情況發生。這時候就可以使用哨兵叢集配置。 也就是當Master伺服器宕機時,其他的Slave伺服器通過投票選出一臺Slave伺服器晉升為Master,替代原Master伺服器的工作,保證整個叢集的高可用性。

 

詳細介紹:Redis哨兵叢集

https://www.cnblogs.com/PatrickLiu/p/8444546.html

 

 

秒殺場景如何解決?

詳細介紹:

https://blog.csdn.net/zhanjianshinian/article/details/53342730

 

使用Redis佇列,設定佇列最大數量,有新的訂單直接加入佇列,當超過最大數量時直接返回產品暫時售空,請稍後嘗試,期間依次處理Redis佇列中的訂單請求,如果訂單均成功,提示剩餘使用者秒殺結束,這樣也可以一定程度的避免超賣情況。具體介紹看連結。


MySQL:

MySQL索引的原理

索引詳細介紹:

https://blog.csdn.net/iefreer/article/details/15815455

 

B+數詳細介紹:

https://www.zhihu.com/question/30527705

 

使用的MySQL版本號是多少?

MySQL常用版本號為5.6 / 5.7 / 5.8

最新的MySQL版本號為8.0

 

拓展: MySQL 4 - 5.6版本區別

http://www.jb51.net/article/121638.htm

拓展: MySQL 8.0 新特性

http://www.jb51.net/article/137123.htm

 

MySQL與Redis的區別

回答參考:

MySQL是關係型資料庫,資料儲存在硬碟上

Redis是非關係型資料庫,資料儲存在記憶體上

但兩種資料庫都支援事物,支援持久化(Redis的AOF和RDB)

Redis速度優於MySQL,常見於快取或作為佇列使用

 

MySQL不用模糊搜尋,建立索引這些方法,如何降低一個數據量非常大的表的查詢壓力?

資料庫是如何進行查詢的,資料量大的時候有沒有什麼優化方案?

回答參考:

初期優化可以嘗試建立索引,讀寫分離,更換硬碟,比如機械更換成固態,PCIE固態更換為更快的NVME固態,如果資料量達到一定級別時,就要考慮優化SQL查詢語句等等;

資料庫優化漏斗原則:

1、 減少磁碟訪問(減少磁碟訪問)

2、 返回更少資料(減少網路傳輸或磁碟訪問)

3、 減少互動次數(減少網路傳輸)

4、 減少伺服器CPU開銷(減少CPU及記憶體開銷)

5、 利用更多資源(增加資源)

 

拓展:SQL優化總結

https://blog.csdn.net/u011277123/article/details/72627011

 

資料庫表增加了新欄位更新問題

回答參考:

MySQL增加了新欄位後,如果設定了欄位預設值,則原先所有資料在該欄位的值更新為預設值。

就像在更新MySQL欄位後,在Django中執行Migrate操作必須要對新欄位設定預設值一樣。

 

 

Django、Nginx:

 

Django中如何連線多個數據庫?

連線多個數據庫是Django1.2版本後新特性

 

詳細配置:

https://code.ziqiangxuetang.com/django/django-multi-database.html

 

RESTful API設計規範

詳細資訊:

https://www.cnblogs.com/EasonJim/p/7770711.html

 

URI規範

不要用大寫

單詞間使用下劃線'_'

不使用動詞,資源要使用名詞複數形式,如:user、rooms、tickets

層級 >= 三層,則使用'?'帶引數

users/1/address/2/citys (bad) /citys?users=1&address=2; (good)

 

Method

GET:查詢資源

POST:建立資源

PUT/PATCH

PUT:全量更新資源(提供改變後的完整資源)

PATCH:區域性更新資源(僅提供改變的屬性)

DELETE:刪除資源

 

nginx的原理是什麼?

Nginx由核心和模組組成,其中,核心的設計非常微小和簡潔,完成的工作也非常簡單,僅僅通過查詢配置檔案將客戶端請求對映到一個location block(location是Nginx配置中的一個指令,用於URL匹配),而在這個location中所配置的每個指令將會啟動不同的模組去完成相應的工作。

 

Nginx的模組從功能上分為如下三類。

Handlers(處理器模組)。此類模組直接處理請求,並進行輸出內容和修改headers資訊等操作。Handlers處理器模組一般只能有一個。

Filters (過濾器模組)。此類模組主要對其他處理器模組輸出的內容進行修改操作,最後由Nginx輸出。

Proxies (代理類模組)。此類模組是Nginx的HTTP Upstream之類的模組,這些模組主要與後端一些服務比如FastCGI等進行互動,實現服務代理和負載均衡等功能。

 

 

Python:

協程是什麼

協程,又稱為微執行緒,看上去像是子程式,但是它和子程式又不太一樣,它在執行的過程中,可以在中斷當前的子程式後去執行別的子程式,再返回來執行之前的子程式,但是它的相關資訊還是之前的。

 

優點:

極高的執行效率,因為子程式切換而不是執行緒切換,沒有了執行緒切換的開銷;

不需要多執行緒的鎖機制,因為只有一個執行緒在執行;

 

py3的生成器和列表有什麼區別

生成器格式最外層是一個(),而列表解析格式最外層是一個[]

生成器是將資料不用一次讀取,而列表解析是一次讀取所有資料(耗記憶體)

生成器返回的是一個生成器物件(不能直接迴圈),而列表解析返回的是一個新列表

 

程序池、執行緒池、連線池

池的概念

 

池可以分為多種,常見的有記憶體池、程序池、執行緒池和連線池。

由於伺服器的硬體資源“充裕”,那麼提高伺服器效能的一個很直接的方法就是以空間換時間,即“浪費”伺服器的硬體資源,以換取其執行效率。這就是池的概念。池是一組資源的集合,這組資源在伺服器啟動之初就完全被建立並初始化,這稱為靜態資源分配。當伺服器進入正是執行階段,即開始處理客戶請求的時候,如果它需要相關的資源,就可以直接從池中獲取,無需動態分配。很顯然,直接從池中取得所需資源比動態分配資源的速度要快得多,因為分配系統資源的系統呼叫都是很耗時的。當伺服器處理完一個客戶連線後,可以把相關的資源放回池中,無需執行系統呼叫來釋放資源。從最終效果來看,池相當於伺服器管理系統資源的應用設施,它避免了伺服器對核心的頻繁訪問。

詳細介紹:

https://blog.csdn.net/walkerkalr/article/details/37729323

https://blog.csdn.net/sjyttkl/article/details/75577178

 

 

全域性變數和單例模式有什麼區別

(1)全域性變數是對一個物件的靜態引用,全域性變數確實可以提供單例模式實現的全域性訪問功能,但是它並不能保證應用程式只有一個例項;編碼規範也明確的指出應該要少使用全域性變數,因為過多的使用全域性變數會造成程式碼難讀;全域性變數並不能實現繼承。

 

(2)、單例模式雖然在繼承上不能很好的處理,但是還是可以實現繼承的;單例模式在類中儲存了它的唯例項這個類,可以保證只能建立一個例項,同時它還提供了一個訪問該唯一例項的全域性訪問點。

 

一個列表a,用一行程式碼求出偶數位置的值加3,再求和

sum([x+3 for y,x in enumerate(a) if not y&1])

 

 

爬蟲:

都使用了什麼爬蟲技術?應用方向是什麼?

都爬了什麼網站

回答參考:

如果是普通公司,尋找跟公司業務有關係的,比如金融公司是金融資料、股票資料或者其他可以促進公司業務發展的比如各地企業資訊,微博輿情輿論等。

如果是小型外包公司,可以說爬了一些房產資料,招聘資料,淘寶、京東等有一些商業價值的資料,但是提前瞭解這些型別的資料都有什麼網站,比如房產的房天下、鏈家、我愛我家,招聘的智聯、拉勾、直聘,電商類的還有蘇寧國美等等。

總而言之,要避免說一些鬥圖網啊、豆瓣TOP250這些商業價值少的,就是反向思考,如果一個數據無法為公司帶來價值,那麼為什麼要去爬取它。

 

每天爬取量多少

回答參考:

爬取量根據網站的不同,爬蟲所在裝置效能的不同以及爬蟲所在網路的出入頻寬以及所爬網站的自身限制均有關係;掛匿名IP代理池,阿里雲1M頻寬2G記憶體爬拉勾,每爬一條更換一次IP,大概一天8萬左右的資料量。

像是淘寶、京東、知乎,在超過一定頻率的訪問後,會出現各種型別的驗證碼,淘寶是滑動解鎖,京東和知乎是字元驗證碼。

 

爬蟲遇到驗證碼怎麼處理

回答參考:

驗證碼基本藉助於第三方打碼平臺解決,常見的有打碼超人,打碼兔等等,字元類的大概0.02元一次。

如果遇到遮蓋變形較少的驗證碼,可以使用tesseract三方庫進行OCR識別解決。

語言驗證碼和簡訊驗證碼也可以使用接碼平臺解決,常見的有星辰碼,易碼,愛碼族等等,語音一般1元一條,簡訊一般0.1元一條。

 

User-Agent如何判斷瀏覽器型別,火狐怎麼顯示,Chrome怎麼顯示

一般為Mozilla開頭 + 裝置識別號 + 瀏覽器核心版本號

切記! 所有User-Agent 均為Mozilla開頭;Mozilla是Netscape的吉祥物,也是Netscape Navigator瀏覽器使用的內部開發代號。由於Netscape早期的影響力,直到今天,所有瀏覽器包括IE,向Web伺服器報告自己的瀏覽器標識的 時候,都以 “Mozilla”開頭,表明自己是Mozilla相容的。

 

chrome

Mozilla/5.0 (Windows NT 5.2) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30

 

Firefox

Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0

 

 

Git:

Git的提交、克隆、合併?

 

 

 

Git分支的實現原理是什麼

https://gitee.com/progit/3-Git-%E5%88%86%E6%94%AF.html

 

Git如何解決分支提交衝突?

 

Linux:

當一個程序出錯,先於執行緒關閉,如何判斷程序內的執行緒是否存活

回答參考:

執行緒依託於程序,當程序出錯關閉後,執行緒也會關閉

但是程序內的程序不會關閉,可能會產生孤兒程序

 

詳細介紹:

https://www.cnblogs.com/Anker/p/3271773.html

 

軟連線與硬連結

ln是linux中又一個非常重要命令,它的功能是為某一個檔案在另外一個位置建立一個同步的連結,分為軟連結、硬連結。軟連結相當於windows的快捷方式

 

軟連結:

1.軟連結,以路徑的形式存在。類似於Windows作業系統中的快捷方式

2.軟連結可以 跨檔案系統 ,硬連結不可以

3.軟連結可以對一個不存在的檔名進行連結

4.軟連結可以對目錄進行連結

 

硬連結:

1.硬連結,以檔案副本的形式存在。但不佔用實際空間。

2.不允許給目錄建立硬連結

3.硬連結只有在同一個檔案系統中才能建立

 

gz/ tar / bz2 三種壓縮包的解壓縮命令

tar命令

  解包:tar zxvf FileName.tar

打包:tar czvf FileName.tar DirName

 

gz命令

    解壓:tar zxvf filename.tar.gz

壓縮:tar zcvf filename.tar.gz dirname

 

bz2命令

解壓:tar jxvf filename.tar.bz2
      
壓縮:tar jcvf filename.tar.bz2 dirname


網路協議:

url的格式是什麼?

Uniform Resource Locator / 統一資源定位符

協議://使用者名稱:密碼@子域名.域名.頂級域名:埠號/目錄/檔名.檔案字尾?引數=值#標誌

 

拓展:

URL又分為絕對URL和相對URL:

絕對URL(absolute URL)顯示檔案的完整路徑,這意味著絕對URL本身所在的位置與被引用的實際檔案的位置無關

相對URL(relative URL)以包含URL本身的資料夾的位置為參考點,描述目標資料夾的位置。

 請求頭裡都可以得到什麼內容

請求頭: 

Accept: text/html,image/*(瀏覽器可以接收的型別) 

Accept-Charset: ISO-8859-1(瀏覽器可以接收的編碼型別) 

Accept-Encoding: gzip,compress(瀏覽器可以接收壓縮編碼型別) 

Accept-Language: en-us,zh-cn(瀏覽器可以接收的語言和國家型別) 

Host: www.it315.org:80(瀏覽器請求的主機和埠) 

If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT(某個頁面快取時間) 

Referer: http://www.it315.org/index.jsp(請求來自於哪個頁面) 

User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)(瀏覽器相關資訊) 

Cookie:(瀏覽器暫存伺服器傳送的資訊) 

Connection: close(1.0)/Keep-Alive(1.1)(HTTP請求的版本的特點) 

Date: Tue, 11 Jul 2000 18:23:51 GMT(請求網站的時間) 

專案題:

專案上線後出現Bug如何除錯?

演算法題:

1、 講一個字串逆序,不要使用反轉函式

2、 一個數組,存放著無序的10個數[8,5,3,0,7,1,2,6,4,9],請程式設計實現這10個數由小到大的排序,找出效率最優的方式

3、 一本書100頁,一次可以看一頁,一次也可以看兩頁,有多少種解法

4、 不使用任何庫函式,將給定字串按單詞反轉,輸入格式是“this is a string”,輸出格式是“string a is this”,不使用額外的空間就地旋轉

5、 找出陣列中出現次數最多的數字,輸入樣例:[ 1,1,2,3,4 ] 輸出樣例: 1 ,如果都出現一次的話,返回其中最大值,數值均為整數型別,如果有多次多個的情況,返回其中最大值

6、 給一個整形陣列,將其中所有的0元素移動到陣列尾部,並保證其中非零元素的順序不變; 輸入樣例: [ 0, 1, 0,3, 12 ]  輸出樣例: [1, 3, 12, 0, 0 ]

7、 有一個人A要去B公司上班,這個人有一個要求就是每7天中必須休息兩天,公司實行排班制,排班表格式如:“1 1 0 1 1 0 0 1 1 1 1 0 1 1 1 1 0 1 1 0 1 1 0 0 1 1”,其中1為工作,0為休息,請編寫一個函式,接收一個排班表,返回這個人最大連續工作天數。(30分鐘思路,15分鐘程式碼)

8、 手寫陣列二分查詢,給一個排序陣列,一個搜尋值K,如果找到返回K,找不到返回-1;不能使用遞迴

 

 

微軟:

1. 完成一個函式:defAdd(num1, num2):其中,兩個輸入都是數字,都是字串(如:“12345678986543210123456789”),要求計算兩個數字的和,返回一個字串,不能使用內建函式,如int,long等。例如,輸入兩個數字是:“1000000000000000”和“-1”,返回“999999999999999”。

2. 給定一個數組nums,然後對其排序,使得排序結果滿足nums[0] < nums[1] > nums[2] < nums[3]…。 例如給定陣列nums=[1,2,3,4,5,6,7,8,9],其中一個滿足條件的結果是1<6>2<7>3<8>4<9>5.給出一個結果即可(可能無解)。最優解法是O(n)時間複雜度和O(1)空間複雜度。

3. 寫一個函式,輸入是兩個int陣列A和B。要求從A和B中分別取出一個數,使他們的和為20。打印出所有的組合。要求數字在陣列中的位置和數字本身。比如輸入為 A = [18, 2, 7, 8, 3], B = [17, 1, 19],輸出為 3 (A4) + 17 (B0) = 20,表示A的第4個元素是3,B的第0個元素是17

4. 寫一個函式,輸入一個隨機的01序列,打印出這個序列中最長的01交替出現的序列的起始位置和結束位置。例如:輸入“0001010101101”,輸出起始位置2, 結束位置10

5. 逆轉一個單鏈表。

6. 實現一個類,用於表示一個大小無限制的整數,要求可以用任何進位制的形式初始化,並提供方法列印成任何進位制的形式,並實現加減法(或四則運算),實現repr

7. 給一個數n,給出可以由多少種方法用正整數來累加成該數。例如給一個數3,那麼一共有三種:1+1+1,1+2,3

8. 將兩個有序整數序列合併為一個大的有序整數序列,輸出,然後反轉,再輸出。自己實現,不能呼叫sort方法和reverse方法

 

 

程式設計題:

1、 定義一個基本圖形Shape類,定義屬性長、寬,頂一個一個計算周長getPerimeter的方法,再分別定義長方形(Rectangle),正方形(Square)兩個類繼承Shape類,實現方法的過載和重寫。

給定一個檔案handler.py 裡面一個handler函式,會接受一個字串,並進行處理,然後返回一個result值,有一個檔案為a.csv,以python test.py a.csv執行,請編寫一個test.py檔案,讀取每一行傳入函式進行處理,並打印出結果,請考慮所有異常情