python的一些基本概念知识和面试题
對于機器學習算法工程師而言,Python是不可或缺的語言,它的優(yōu)美與簡潔令人無法自拔。那么你了解過Python編程面試題嗎?從Python基礎(chǔ)到網(wǎng)頁爬蟲你是否能全方位Hold住?今天,機器之心為讀者們推薦一個Github項目。
?
在這個項目中,作者 kenwoodjw 準備了近 300 道 Python 面試題,同時還包含解決方案與代碼。作者主要從 Python 基礎(chǔ)、高級語句、網(wǎng)頁應用、數(shù)據(jù)庫和測試等角度提問,讀者可只關(guān)注自己需要的領(lǐng)域。目前該項目已經(jīng)完成了很多基礎(chǔ)和高級面試題,本文主要摘取一些 Python 面試題供大家參考。
?
項目地址:https://github.com/kenwoodjw/python_interview_question
?
總體而言,項目有近300道面試題。雖然該項目剛開始創(chuàng)建,但很多Python面試題都已經(jīng)提供了解決方案。如下所示為面試題示例:
?
?
本文截取了一些面試題及解決方案:
?
-
Python 基礎(chǔ)
?
-
文件操作
-
模塊與包
-
數(shù)據(jù)類型
-
企業(yè)面試題
?
-
Python 高級
?
-
設(shè)計模式
-
系統(tǒng)編程
?
如果希望了解機器學習面試題,可閱讀:春招已近,這份GitHub萬星的ML算法面試大全請收下?
?
Python 基礎(chǔ)
?
什么是 Python?根據(jù)Python 創(chuàng)建者 Guido van Rossum 所言,Python是一種高級編程語言,其設(shè)計的核心理念是代碼的易讀性,以及允許編程者通過若干行代碼輕松表達想法創(chuàng)意。實際上,很多開發(fā)者選擇學習 Python 的首要原因是其編程的優(yōu)美性,用它編碼和表達想法非常自然。
?
文件操作
?
1.若有一個jsonline格式的文件file.txt,大小約為10K,我們的處理方式為:
?
?
def?get_lines():????????l?=?[]
????????with?open('file.txt',?'rb')?as?f:
????????????for?eachline?in?f:
????????????????l.append(eachline)
????????????return?l
if?__name__?==?'__main__':
????for?e?in?get_lines():
????????process(e)?#處理每一行數(shù)據(jù)
?
現(xiàn)在要處理一個大小為10G的file.txt文件,但是內(nèi)存只有4G。如果在只修改get_lines 函數(shù)而其他代碼保持不變的情況下,應該如何實現(xiàn)?需要考慮的問題都有那些?
?
def?get_lines():????????l?=?[]
????????with?open('file.txt','rb')?as?f:
????????????data?=?f.readlines(60000)
????????l.append(data)
????????yield?l
?
?
要考慮的問題有:內(nèi)存只有4G,無法一次性讀入10G文件。而分批讀入數(shù)據(jù)要記錄每次讀入數(shù)據(jù)的位置,且分批每次讀取得太小會在讀取操作上花費過多時間。
?
模塊與包
?
2.如何輸入日期, 判斷這一天是這一年的第幾天?
?
import?datetimedef?dayofyear():
????year?=?input("請輸入年份:?")
????month?=?input("請輸入月份:?")
????day?=?input("請輸入天:?")
????date1?=?datetime.date(year=int(year),month=int(month),day=int(day))
????date2?=?datetime.date(year=int(year),month=1,day=1)
????return?(date1-date2).days+1
?
數(shù)據(jù)類型
?
3.如何反轉(zhuǎn)字符串"aStr"?
?
print("aStr"[::-1])?
4.下面代碼的輸出結(jié)果將是什么?會報錯嗎?
?
list?=?['a','b','c','d','e']print(list[10:])
?
代碼將輸出[],并不會產(chǎn)生IndexError 錯誤。如果嘗試用超出成員的個數(shù)的index來獲取某個列表的成員,那就會報錯。例如,嘗試獲取 list[10] 和之后的成員,會導致IndexError。然而當我們嘗試獲取列表的切片時,開始的index超過成員個數(shù)并不會產(chǎn)生IndexError,而是僅僅返回一個空列表。因為并不會報錯,所以這種Bug很難追蹤到。
?
5.請寫出一段Python代碼,實現(xiàn)刪除list里面的重復元素?
?
l1?=?['b','c','d','c','a','a']l2?=?list(set(l1))
print(l2)
?
?
用list類的sort方法可以保證順序不變:
?
l1?=?['b',?'c',?'d',?'c',?'a',?'a']l2?=?list(set(l1))
l2.sort(key=l1.index)
print(l2)
?
也可以這樣寫:
?
?
l1?=?['b',?'c',?'d',?'c',?'a',?'a']l2?=?sorted(set(l1),?key=l1.index)
print(l2)
?
也可以用遍歷:
?
l1?=?['b',?'c',?'d',?'c',?'a',?'a']l2?=?[]
for?i?in?l1:
????if?not?i?in?l2:
????????l2.append(i)
print(l2)
?
??
企業(yè)面試題
?
6.設(shè)計實現(xiàn)遍歷目錄與子目錄,抓取.pyc文件
?
第一種方法:
?
import?osdef?getFiles(dir,?suffix):
????res?=?[]
????for?root,?dirs,?files?in?os.walk(dir):
????????for?filename?in?files:
????????????name,?suf?=?os.path.splitext(filename)
????????????if?suf?==?suffix:
????????????????res.append(os.path.join(root,?filename))
????print(res)
getFiles("./",?'.pyc')
?
第二種方法:
?
import?osdef?pick(obj):
????try:
????????if?obj.[-4:]?==?".pyc":
????????????print(obj)
????????except:
????????return?None
def?scan_path(ph):
????file_list?=?os.listdir(ph)
????for?obj?in?file_list:
????????if?os.path.isfile(obj):
????pick(obj)
????elif?os.path.isdir(obj):
????scan_path(obj)
if?__name__?==?'__main__':
????path?=?input('輸入目錄')
????scan_path(path)
?
7.如何反轉(zhuǎn)一個整數(shù),例如-123--> -321?
?
?
class?Solution(object):????def?reverse(self,?x):
????????if?-10?<?x?<?10:
????????????return?x
????????str_x?=?str(x)
????????if?str_x[0]?!=?"-":
????????????str_x?=?str_x[::-1]
????????????x?=?int(str_x)
????????else:
????????????str_x?=?str_x[1:][::-1]
????????????x?=?int(str_x)
????????????x?=?-x
????????return?x?if?-2147483648?<?x?<?2147483647?else?0
if?__name__?==?'__main__':
????s?=?Solution()
????reverse_int?=?s.reverse(-120)
????print(reverse_int)
?
Python高級
?
Python高級包含很多重要的模塊,例如函數(shù)、類和實例、系統(tǒng)編程、正則表達式、網(wǎng)絡編程等等。根據(jù)這些高級屬性,Python可用于數(shù)據(jù)科學、網(wǎng)頁開發(fā)、機器學習等等。
?
設(shè)計模式
?
8.對設(shè)計模式的理解,簡述你了解的設(shè)計模式?
?
設(shè)計模式是為我們經(jīng)常會碰到的一些編程問題構(gòu)建的可重用解決方案,它是總結(jié)性和經(jīng)優(yōu)化的。一個設(shè)計模式并不像一個類或一個庫那樣能夠直接作用于我們的代碼,反之,設(shè)計模式更為高級,它是一種在特定情形下實現(xiàn)的方法模板。常見的是工廠模式和單例模式。
?
單例模式應用的場景一般發(fā)現(xiàn)在以下條件下: 資源共享的情況下,避免由于資源操作時導致的性能或損耗等,如日志文件,應用配置。控制資源的情況下,方便資源之間的互相通信。
?
9.生成器和迭代器的區(qū)別?
?
迭代器是一個更抽象的概念,任何對象,如果它的類有 next 方法和 iter 方法返回自己本身,它就是可迭代的。對于 string、list、dict、tuple 等這類容器對象,使用for循環(huán)遍歷是很方便的,for 語句實際上會對容器對象調(diào)用 iter() 函數(shù)。iter() 會返回一個定義了 next() 方法的迭代器對象,它在容器中逐個訪問容器內(nèi)元素,在沒有后續(xù)元素時,next()會拋出一個StopIteration異常。
?
生成器(Generator)是創(chuàng)建迭代器的簡單而強大的工具。它們寫起來就像是正規(guī)的函數(shù),只是在需要返回數(shù)據(jù)的時候使用yield語句。生成器能做到迭代器能做的所有事,而且因為自動創(chuàng)建iter()和next()方法,生成器顯得特別簡潔,而且生成器也是高效的,使用生成器表達式取代列表解析可以同時節(jié)省內(nèi)存。除了創(chuàng)建和保存程序狀態(tài)的自動方法,當發(fā)生器終結(jié)時,還會自動拋出StopIteration異常。
?
10.對裝飾器的理解,你能寫出一個計時器裝飾器,它能記錄函數(shù)的執(zhí)行時間嗎?
?
裝飾器本質(zhì)上是一個Python函數(shù),它可以讓其他函數(shù)在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個函數(shù)對象。
?
import?time????def?timeit(func):
????????def?wrapper():
????????????start?=?time.clock()
????????????func()
????????????end?=?time.clock()
????????????print('used:',end-start)
????????????return?wrapper
????@timeit
????def?foo():
????????print('in?foo()'foo())
?
系統(tǒng)編程
?
11.介紹一下你了解的進程。
?
程序運行在操作系統(tǒng)上的一個實例,就稱之為進程。進程需要相應的系統(tǒng)資源:內(nèi)存、時間片、pid。創(chuàng)建進程: 首先要導入multiprocessing中的Process;創(chuàng)建一個Process對象;創(chuàng)建Process對象時,可以傳遞參數(shù)。
?
p?=?Process(target=XXX,?args=(tuple,),?kwargs={key:?value})target?=?XXX?#?指定的任務函數(shù),不用加()
args?=?(tuple,)
kwargs?=?{key:?value}?#?給任務函數(shù)傳遞的參數(shù)
?
使用start()啟動進程 結(jié)束進程 給子進程指定函數(shù)傳遞參數(shù)Demo
?
import?osfrom?mulitprocessing?import?Process
import?time
def?pro_func(name,?age,?**kwargs):
????for?i?in?range(5):
????????print("子進程正在運行中,name=%s,age=%d,pid=%d"?%?(name,?age,?os.getpid()))
????????print(kwargs)
????????time.sleep(0.2)
if?__name__?==?"__main__":
????#?創(chuàng)建Process對象
????p?=?Process(target=pro_func,?args=('小明',?18),?kwargs={'m':?20})
????#?啟動進程
????p.start()
????time.sleep(1)
????#?1秒鐘之后,立刻結(jié)束子進程
????p.terminate()
????p.join()
?
12.談談你對多進程、多線程、以及協(xié)程的理解,項目是否用?
?
進程:一個運行的程序(代碼)就是一個進程,沒有運行的代碼叫程序,進程是系統(tǒng)資源分配的最小單位,進程擁有自己獨立的內(nèi)存空間,所有進程間數(shù)據(jù)不共享,開銷大。線程: cpu調(diào)度執(zhí)行的最小單位,也叫執(zhí)行路徑,不能獨立存在,依賴進程存在,一個進程至少有一個線程,叫主線程,而多個線程共享內(nèi)存可以極大地提高了程序的運行效率。協(xié)程: 是一種用戶態(tài)的輕量級線程,協(xié)程的調(diào)度完全由用戶控制,協(xié)程擁有自己的寄存器上下文和棧。協(xié)程調(diào)度時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操中棧則基本沒有內(nèi)核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切換非常快。
?
關(guān)于系統(tǒng)編程還有很多問題,例如:
?
?
?
本文為機器之心編輯,轉(zhuǎn)載請聯(lián)系本公眾號獲得授權(quán)。
轉(zhuǎn)載于:https://www.cnblogs.com/fengff/p/10485078.html
總結(jié)
以上是生活随笔為你收集整理的python的一些基本概念知识和面试题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。