Python面试常用二十题总结
1.請至少用一種方法下面字符串的反轉?
1).A[::-1]
2).交換前后字母的位置
t = list(A)
l = len(t)
for i, j inzip(range(l - 1, 0, -1), range(l // 2)):
??????? t[i], t[j] = t[j], t[i]
return"".join(t)
3). 遞歸的方式, 每次輸出一個字符
defstring_reverse3(string):?
??? if len(string) <= 1:?
??????? return string?
??? return string_reverse3(string[1:]) +string[0]
2.請手寫一個lambda函數
Sum = Lambda a,b:a+b
3.請手寫一個函數,用來取出1—100(均包含)中9的倍數或者有數字9的所有整數
For I inxrange(1,101):
?????? If i%9 == 0 or “9” in str(I):
???????????? Print i
4.? Python里面如何實現tuple和list的轉換
直接用tuple和list函數
5.? Python里面match()和search()的區別?
re模塊中match(pattern,string[,flags]),檢查string的開頭是否與pattern匹配。
re模塊中research(pattern,string[,flags]),在string搜索pattern的第一個匹配值。
6.請用至少一種方法刪除下面list里面的重復元素
1).A=list(set(A))
2).A =[1,2,3,4,5,1,5]
List = []
for i in A:
??? if I not in List:
??? ?????? List.append(i)
print List
?
7.請簡述python中單例模式的特點,并手寫一個單例模式?
單例模式的要點有三個;一是某個類只能有一個實例;二是它必須自行創建這個實例;三是它必須自行向整個系統提供這個實例。
classSingleton(object):
__instance=None
def__init__(self):
?????? pass
def__new__(cls,*args,**kwd):
?????? if Singleton.__instance is None:
???????????? Singleton.__instance=object.__new__(cls,*args,**kwd)
?????? return Singleton.__instance
8.請簡述值傳遞和引用傳遞的區別?
值傳遞僅僅傳遞的是值
引用傳遞,傳遞的是內存地址,修改后會改變內存地址對應儲存的值。
9.請手寫一個匹配ip的正則表達式?
^(?:(?:1[0-9][0-9]\.)|(?:2[0-4][0-9]\.)|(?:25[0-5]\.)|(?:[1-9][0-9]\.)|(?:[0-9]\.)){3}(?:(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5])|(?:[1-9][0-9])|(?:[0-9]))$
^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$'
10.mysql數據庫的優化?
1. 優化索引、SQL 語句、分析慢查詢;
2. 設計表的時候嚴格根據數據庫的設計范式來設計數據庫;
3. 使用緩存,把經常訪問到的數據而且不需要經常變化的數據放在緩存中,能節約磁盤IO;
4. 優化硬件;采用SSD,使用磁盤隊列技術(RAID0,RAID1,RDID5)等;
5. 采用MySQL 內部自帶的表分區技術,把數據分層不同的文件,能夠提高磁盤的讀取效率;
6. 垂直分表;把一些不經常讀的數據放在一張表里,節約磁盤I/O;
7. 主從分離讀寫;采用主從復制把數據庫的讀操作和寫入操作分離開來;
8. 分庫分表分機器(數據量特別大),主要的的原理就是數據路由;
9. 選擇合適的表引擎,參數上的優化;
10. 進行架構級別的緩存,靜態化和分布式;
11. 不采用全文索引;
12. 采用更快的存儲方式,例如NoSQL存儲經常訪問的數
?
11.進程間通信(IPC)有那些方式?
1.??? 管道(Pipe):管道可用于具有親緣關系進程間的通信,允許一個進程和另一個與它有共同祖先的進程之間進行通信。
2.??? 命名管道(named pipe):命名管道克服了管道沒有名字的限制,因此,除具有管道所具有的功能外,它還允許無親緣關系進程間的通信。命名管道在文件系統中有對應的文件名。命名管道通過命令mkfifo或系統調用mkfifo來創建。
3.??? 信號(Signal):信號是比較復雜的通信方式,用于通知接受進程有某種事件發生,除了用于進程間通信外,進程還可以發送信號給進程本身;linux除了支持Unix早期信號語義函數sigal外,還支持語義符合Posix.1標準的信號函數sigaction(實際上,該函數是基于BSD的,BSD為了實現可靠信號機制,又能夠統一對外接口,用sigaction函數重新實現了signal函數)。
4.??? 消息(Message)隊列:消息隊列是消息的鏈接表,包括Posix消息隊列system V消息隊列。有足夠權限的進程可以向隊列中添加消息,被賦予讀權限的進程則可以讀走隊列中的消息。消息隊列克服了信號承載信息量少,管道只能承載無格式字節流以及緩沖區大小受限等缺
5.??? 共享內存:使得多個進程可以訪問同一塊內存空間,是最快的可用IPC形式。是針對其他通信機制運行效率較低而設計的。往往與其它通信機制,如信號量結合使用,來達到進程間的同步及互斥。
6.??? 內存映射(mapped memory):內存映射允許任何多個進程間通信,每一個使用該機制的進程通過把一個共享的文件映射到自己的進程地址空間來實現它。
7.??? 信號量(semaphore):主要作為進程間以及同一進程不同線程之間的同步手段。
8.??? 套接口(Socket):更為一般的進程間通信機制,可用于不同機器之間的進程間通信。起初是由Unix系統的BSD分支開發出來的,但現在一般可以移植到其它類Unix系統上:Linux和System V的變種都支持套接字
?
12.簡述這兩個參數是什么意思:*args,**kwargs?我們為什么要使用它們?
*args 當我們不知道要有多少個參數傳給函數,或者我們想把一個列表或者tuple存起來以后傳給函數。
**kwargs當我們不知道有多少個關鍵字參數要傳給函數,或者我們想把字典存起來以后傳給函數
13.談談你對python多線程的理解?
在Python多線程下,每個線程的執行方式:
1、獲取GIL
2、執行代碼直到sleep或者是python虛擬機將其掛起。
3、釋放GIL
1、CPU密集型代碼(各種循環處理、計數等等),在這種情況下,由于計算工作多,ticks計數很快就會達到閾值,然后觸發GIL的釋放與再競爭(多個線程來回切換當然是需要消耗資源的),所以python下的多線程對CPU密集型代碼并不友好。???????
2、IO密集型代碼(文件處理、網絡爬蟲等),多線程能夠有效提升效率(單線程下有IO操作會進行IO等待,造成不必要的時間浪費,而開啟多線程能在線程A等待時,自動切換到線程B,可以不浪費CPU的資源,從而能提升程序執行效率)。所以python的多線程對IO密集型代碼比較友好。
而在python3.x中,GIL不使用ticks計數,改為使用計時器(執行時間達到閾值后,當前線程釋放GIL),這樣對CPU密集型程序更加友好,但依然沒有解決GIL導致的同一時間只能執行一個線程的問題,所以效率依然不盡如人意。??????? ?????????????????????????
多核多線程比單核多線程更差,原因是單核下多線程,每次釋放GIL,喚醒的那個線程都能獲取到GIL鎖,所以能夠無縫執行,但多核下,CPU0釋放GIL后,其他CPU上的線程都會進行競爭,但GIL可能會馬上又被CPU0拿到,導致其他幾個CPU上被喚醒后的線程會醒著等待到切換時間后又進入待調度狀態,這樣會造成線程顛簸(thrashing),導致效率更低。
14.redis中的事務和mysql中的事務有什么區別?
1、Redis中的事務(transaction)是一組命令的集合。事務同命令一樣都是Redis最小的執行單位,一個事務中的命令要么都執行,要么都不執行。Redis事務的實現需要用到?MULTI?和?EXEC?兩個命令,事務開始的時候先向Redis服務器發送?MULTI?命令,然后依次發送需要在本次事務中處理的命令,最后再發送?EXEC?命令表示事務命令結束。
2、mysql的事務特性,要求這組操作,要不全都成功,要不全都失敗,這樣就避免了某個操作成功某個操作失敗。利于數據的安全
15.請簡述什么是三次握手和四次揮手?為什么要這樣?
建立連接的過程是利用客戶服務器模式,假設主機A為客戶端,主機B為服務器端。
(1)TCP的三次握手過程:主機A向B發送連接請求;主機B對收到的主機A的報文段進行確認;主機A再次對主機B的確認進行確認。
(2)采用三次握手是為了防止失效的連接請求報文段突然又傳送到主機B,因而產生錯誤。失效的連接請求報文段是指:主機A發出的連接請求沒有收到主機B的確認,于是經過一段時間后,主機A又重新向主機B發送連接請求,且建立成功,順序完成數據傳輸??紤]這樣一種特殊情況,主機A第一次發送的連接請求并沒有丟失,而是因為網絡節點導致延遲達到主機B,主機B以為是主機A又發起的新連接,于是主機B同意連接,并向主機A發回確認,但是此時主機A根本不會理會,主機B就一直在等待主機A發送數據,導致主機B的資源浪費。
(3)采用兩次握手不行,原因就是上面說的失效的連接請求的特殊情況,因此采用三次握手剛剛好,兩次可能出現失效,四次甚至更多次則沒必要,反而復雜了。
四次揮手:
先由客戶端向服務器端發送一個FIN,請求關閉數據傳輸。
當服務器接收到客戶端的FIN時,向客戶端發送一個ACK,其中ack的值等于FIN+SEQ
然后服務器向客戶端發送一個FIN,告訴客戶端應用程序關閉。
當客戶端收到服務器端的FIN是,回復一個ACK給服務器端。其中ack的值等于FIN+SEQ
為什么要4次揮手?
確保數據能夠完成傳輸
16.python是如何進行內存管理的?
一、垃圾回收:python不像C++,Java等語言一樣,他們可以不用事先聲明變量類型而直接對變量進行賦值。對Python語言來講,對象的類型和內存都是在運行時確定的。這也是為什么我們稱Python語言為動態類型的原因(這里我們把動態類型可以簡單的歸結為對變量內存地址的分配是在運行時自動判斷變量類型并對變量進行賦值)。
二、引用計數:Python采用了類似Windows內核對象一樣的方式來對內存進行管理。每一個對象,都維護這一個對指向該對對象的引用的計數。當變量被綁定在一個對象上的時候,該變量的引用計數就是1,(還有另外一些情況也會導致變量引用計數的增加),系統會自動維護這些標簽,并定時掃描,當某標簽的引用計數變為0的時候,該對就會被回收。
三、內存池機制Python的內存機制以金字塔行,-1,-2層主要有操作系統進行操作,
第0層是C中的malloc,free等內存分配和釋放函數進行操作;
第1層和第2層是內存池,有Python的接口函數PyMem_Malloc函數實現,當對象小于256K時有該層直接分配內存;
第3層是最上層,也就是我們對Python對象的直接操作;
在 C 中如果頻繁的調用 malloc 與 free 時,是會產生性能問題的.再加上頻繁的分配與釋放小塊的內存會產生內存碎片. Python 在這里主要干的工作有:
如果請求分配的內存在1~256字節之間就使用自己的內存管理系統,否則直接使用 malloc.
這里還是會調用 malloc 分配內存,但每次會分配一塊大小為256k的大塊內存.
經由內存池登記的內存到最后還是會回收到內存池,并不會調用 C 的 free 釋放掉.以便下次使用.對于簡單的Python對象,例如數值、字符串,元組(tuple不允許被更改)采用的是復制的方式(深拷貝?),也就是說當將另一個變量B賦值給變量A時,雖然A和B的內存空間仍然相同,但當A的值發生變化時,會重新給A分配空間,A和B的地址變得不再相同
17.談談你對線程安全的理解?
線程安全是在多線程的環境下,能夠保證多個線程同時執行時程序依舊運行正確, 而且要保證對于共享的數據可以由多個線程存取,但是同一時刻只能有一個線程進行存取。多線程環境下解決資源競爭問題的辦法是加鎖來保證存取操作的唯一性。
18.事務的特性?
1、原子性(Atomicity):事務中的全部操作在數據庫中是不可分割的,要么全部完成,要么均不執行。
2、一致性(Consistency):幾個并行執行的事務,其執行結果必須與按某一順序串行執行的結果相一致。
3、隔離性(Isolation):事務的執行不受其他事務的干擾,事務執行的中間結果對其他事務必須是透明的。
4、持久性(Durability):對于任意已提交事務,系統必須保證該事務對數據庫的改變不被丟失,即使數據庫出現故障
18.什么是阻塞,什么是非阻塞?
阻塞調用是指調用結果返回之前,當前線程會被掛起。函數只有在得到結果之后才會返回。有人也許會把阻塞調用和同步調用等同起來,實際上他是不同的。對于同步調用來說,很多時候當前線程還是激活的,只是從邏輯上當前函數沒有返回而已。例如,我們在CSocket中調用Receive函數,如果緩沖區中沒有數據,這個函數就會一直等待,直到有數據才返回。而此時,當前線程還會繼續處理各種各樣的消息。如果主窗口和調用函數在同一個線程中,除非你在特殊的界面操作函數中調用,其實主界面還是應該可以刷新。socket接收數據的另外一個函數recv則是一個阻塞調用的例子。當socket工作在阻塞模式的時候,如果沒有數據的情況下調用該函數,則當前線程就會被掛起,直到有數據為止。
非阻塞和阻塞的概念相對應,指在不能立刻得到結果之前,該函數不會阻塞當前線程,而會立刻返回。
對象的阻塞模式和阻塞函數調用。對象是否處于阻塞模式和函數是不是阻塞調用有很強的相關性,但是并不是一一對應的。阻塞對象上可以有非阻塞的調用方式,我們可以通過一定的API去輪詢狀態,在適當的時候調用阻塞函數,就可以避免阻塞。而對于非阻塞對象,調用特殊的函數也可以進入阻塞調用。函數select就是這樣的一個例子。
19.父子進程間有哪些異同,是否共享數據?(共享哪些數據?)
子進程會復制父進程所有可寫的資源,包括:
堆、棧、數據段、未初始化數據段、打開的文件描述符、信號安裝過的 handler、共享庫、ipc(共享內存、消息隊列、信號量)。注意未決信號不會繼承過來, 新進程會重置它的未決信號鏈;
子進程和父進程共享:
所有只讀的資源都不用復制, 父子進程共享, 包括正文段和字符串常量
子進程不會從父進程繼承:
進程 id、各種鎖(內存鎖、文件鎖)、定時器、未決信號
20.Mysql的常用引擎及選擇?
常用:InnoDB MyISAM
一、 InnoDB 支持事務,MyISAM 不支持,這一點是非常之重要。事務是一種高級的處理方式,如在一些列增刪改中只要哪個出錯還可以回滾還原,而 MyISAM就不可以了;
二、MyISAM 適合查詢以及插入為主的應用,InnoDB適合頻繁修改以及涉及到安全性較高的應用;
三、InnoDB 支持外鍵,MyISAM 不支持;
四、MyISAM 是默認引擎,InnoDB需要指定;
五、InnoDB 不支持 FULLTEXT 類型的索引;
六、InnoDB 中不保存表的行數,如select count(*) from table 時,InnoDB;需要掃描一遍整個表來計算有多少行,但是 MyISAM 只要簡單的讀出保存好的行數即可。注意的是,當 count(*)語句包含 where 條件時 MyISAM 也需要掃描整個表;
七、對于自增長的字段,InnoDB中必須包含只有該字段的索引,但是在MyISAM表中可以和其他字段一起建立聯合索引;
八、清空整個表時,InnoDB是一行一行的刪除,效率非常慢。MyISAM則會重
建表;
九、InnoDB 支持行鎖(某些情況下還是鎖整表,如update table set a=1 where user like '%lee%'
總結
以上是生活随笔為你收集整理的Python面试常用二十题总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: flutter 图解_【Flutter
- 下一篇: python简单实践作业答案_pytho