面試寶典

  • Python基礎

  • 1、文件操作

    • 1.1、有一個jsonline格式的文件file.txt大小約為10K
    • 1.2、補充缺失的代碼?
  • 2、模塊與包

    • 2.1輸入日期,判斷這一天是這一年的第幾天?
    • 2.2打亂一個排好序的list對象 alist?
  • 3、數(shù)據(jù)類型

    • 3.1、現(xiàn)有字典 d={‘a(chǎn)’:24,‘g’:52,‘i’:12,‘k’:33}請按value值進行
    • 3.2、字典推導式?
    • 3.3、請反轉字符串“aStr”?
    • 3.4、將字符串"k:1|k1:2|k2:3|k3:4",處理成字典:{k:1, k1:2, ...
    • 3.5、請按alist中元素的age由大到小排序
    • 3.6下面代碼的輸出結果將是什么?
    • 3.7、寫一個列表生成式,產(chǎn)生一個公差為11的等差數(shù)列
    • 3.8、給定兩個列表,怎么找出他們相同的元素和不同的元素?
    • 3.9、請寫出一段Python代碼實現(xiàn)刪除一個list里面的重復元素?
    • 3.10、給定兩個list A ,B,請用找出 A ,B中相同與不同的元素
  • 4、企業(yè)面試題

    • 4.1、Python新式類和經(jīng)典類的區(qū)別?
    • 4.2、python中內(nèi)置的數(shù)據(jù)結構有幾種?
    • 4.3、Python如何實現(xiàn)單例模式?請寫出兩種實現(xiàn)方法
    • 4.4、反轉一個整數(shù),例如-123-->-321,Python語言實現(xiàn)
    • 4.5、設計實現(xiàn)遍歷目錄與子目錄,抓取.pyc文件
    • 4.6、一行代碼實現(xiàn)1-100之和
    • 4.7、Python-遍歷列表時刪除元素的正確做法
    • 4.8、字符串的操作題目
    • 4.9、可變類型和不可變類型
    • 4.10、is和==有什么區(qū)別?
    • 4.11、求出列表所有奇數(shù)并構造新列表
    • 4.12、用一行python代碼寫出1+2+3+10248
    • 4.13、Python中變量的作用域?(變量查找順序)
    • 4.14、字符串”123″轉換成123,不使用內(nèi)置api,例如int()
    • 4.15、Given an array of integers
    • 4.16、python代碼實現(xiàn)刪除一個list里面的重復元素
    • 4.17、統(tǒng)計一個文本中單詞頻次最高的10個單詞?
    • 4.18、請寫出一個函數(shù)滿足以下條件
    • 4.19、使用單一的列表生成式來產(chǎn)生一個新的列表
    • 4.20、用一行代碼生成[1,4,9,16,25,36,49,64,81,100]
    • 4.21、輸入某年某月某日,判斷這一天是這一年的第幾天?
    • 4.22、兩個有序列表,l1,l2,對這兩個列表進行合并不可使用extend
    • 4.23、給定一個任意長度數(shù)組,實現(xiàn)一個函數(shù)
    • 4.23、寫一個函數(shù)找出一個整數(shù)數(shù)組中,第二大的數(shù)
    • 4.24、閱讀一下代碼他們的輸出結果是什么?
    • 4.25、統(tǒng)計一段字符串中字符出現(xiàn)的次數(shù)
    • 4.26、super函數(shù)的具體用法和場景
  • 二、Python高級

    • 1、元類
      • 1.1、Python中類方法、類實例方法、靜態(tài)方法有何區(qū)別?
      • 1.2、super函數(shù)的具體用法和場景?
      • 1.3、歷一個object的所有屬性,并print每一個屬性名?
      • 1.4、寫一個類,并讓它盡可能多的支持操作符?
      • 1.5、介紹Cpython,Pypy Cpython Numba各有什優(yōu)缺點
      • 1.6、請描述抽象類和接口類的區(qū)別和聯(lián)系?
      • 1.7、Python中如何動態(tài)獲取和設置對象的屬性?
    • 2、內(nèi)存管理與垃圾回收機制
      • 2.1、哪些操作會導致Python內(nèi)存溢出,怎么處理?
      • 2.2、關于 Python內(nèi)存管理,下列說法錯誤的是(B)
      • 2.3、Python的內(nèi)存管理機制及調(diào)優(yōu)手段?
      • 2.4、內(nèi)存泄露是什么?如何避免?
    • 3、函數(shù)
      • 3.1、python常見的列表推導式?
      • 3.2、簡述read、readline、readlines的區(qū)別?
      • 3.3、什么是Hash(散列函數(shù))?
      • 3.4、python函數(shù)重載機制?
      • 3.5、寫一個函數(shù)找出一個整數(shù)數(shù)組中,第二大的數(shù)
      • 3.6、手寫一個判斷時間的裝飾器
      • 3.7、使用Python內(nèi)置的filter()方法來過濾?
      • 3.8、編寫函數(shù)的4個原則
      • 3.9、函數(shù)調(diào)用參數(shù)的傳遞方式是值傳遞還是引用傳遞?
      • 3.10、如何在function里面設置一個全局變量
      • 3.11、對缺省參數(shù)的理解 ?
      • 3.12、Mysql怎么限制IP訪問?
      • 3.13、帶參數(shù)的裝飾器?
      • 3.14、為什么函數(shù)名字可以當做參數(shù)用?
      • 3.15、Python中pass語句的作用是什么?
      • 3.16、有這樣一段代碼,print c會輸出什么,為什么?
      • 3.17、交換兩個變量的值?
      • 3.18、map函數(shù)和reduce函數(shù)?
      • 3.19、回調(diào)函數(shù),如何通信的?
      • 3.20、Python主要的內(nèi)置數(shù)據(jù)類型都有哪些? print dir( ‘a(chǎn) ’) 的輸出?
      • 3.21、map(lambda x:xx,[y for y in range(3)])的輸出?
      • 3.22、 hasattr() getattr() setattr() 函數(shù)使用詳解?
      • 3.23、一句話解決階乘函數(shù)?
      • 3.24、什么是lambda函數(shù)? 有什么好處?
      • 3.25、遞歸函數(shù)停止的條件?
      • 3.26、下面這段代碼的輸出結果將是什么?請解釋。
      • 3.27、什么是lambda函數(shù)?它有什么好處?寫一個匿名函數(shù)求兩個數(shù)的
    • 4、設計模式
      • 4.1、對設計模式的理解,簡述你了解的設計模式?
      • 4.2、請手寫一個單例
      • 4.3、單例模式的應用場景有哪些?
      • 4.4、Python 如何實現(xiàn)單例模式?請寫出兩種實現(xiàn)方法?
      • 4.5、對裝飾器的理解 ,并寫出一個計時器記錄方法執(zhí)行性能的裝飾器?
      • 4.6、解釋一下什么是閉包?
      • 4.7、函數(shù)裝飾器有什么作用?
      • 4.8、生成器、迭代器的區(qū)別?
      • 4.9 X是什么類型?
      • 4.10、請用“一行代碼”實現(xiàn)將1-N的整數(shù)列表以3為單位分組
      • 4.11、Python中yield的用法?
    • 5、面向?qū)ο?
      • 5.1、Python中的可變對象和不可變對象?
      • 5.2、
      • 5.3、Python的魔法方法
      • 5.4、面向?qū)ο笾性趺磳崿F(xiàn)只讀屬性?
      • 5.5、談談你對面向?qū)ο蟮睦斫猓?/li>
    • 6、正則表達式
      • 6.1、請寫出一段代碼用正則匹配出ip?
      • 6.2、a = “abbbccc”,用正則匹配為abccc,不管有多少b,就出現(xiàn)一次?
      • 6.3、Python字符串查找和替換?
      • 6.4、 用Python匹配HTML g tag的時候,<.> 和 <.*?> 有什么區(qū)別
      • 6.5、正則表達式貪婪與非貪婪模式的區(qū)別?
      • 6.6、寫出開頭匹配字母和下劃線,末尾是數(shù)字的正則表達式?
      • 6.7、正則表達式操作
      • 6.8、請匹配出變量A 中的json字符串。
      • 6.9、怎么過濾評論中的表情?
      • 6.10、簡述Python里面search和match的區(qū)別
      • 6.11、請寫出匹配ip的Python正則表達式
      • 6.12、Python里match與search的區(qū)別?
    • 7、系統(tǒng)編程
      • 7.1、進程總結
      • 7.2、談談你對多進程,多線程,以及協(xié)程的理解,項目是否用?
      • 7.3、Python異步使用場景有那些?
      • 7.4、多線程共同操作同一個數(shù)據(jù)互斥鎖同步?
      • 7.5、什么是多線程競爭?
      • 7.6、請介紹一下Python的線程同步?
      • 7.7、解釋一下什么是鎖,有哪幾種鎖?
      • 7.8、什么是死鎖呢?
      • 7.9、多線程交互訪問數(shù)據(jù),如果訪問到了就不訪問了
      • 7.10、什么是線程安全,什么是互斥鎖?
      • 7.11、說說下面幾個概念:同步,異步,阻塞,非阻塞?
      • 7.12、什么是僵尸進程和孤兒進程?怎么避免僵尸進程?
      • 7.13、Python中的進程與線程的使用場景?
      • 7.14、線程是并發(fā)還是并行,進程是并發(fā)還是并行?
      • 7.15、并行(parallel)和并發(fā)(concurrency)?
      • 7.16、IO密集型和CPU密集型區(qū)別?
    • 8、網(wǎng)絡編程
      • 8.1、怎么實現(xiàn)強行關閉客戶端和服務器之間的連接?
      • 8.2、簡述TCP和UDP的區(qū)別以及優(yōu)缺點?
      • 8.3、簡述瀏覽器通過WSGI請求動態(tài)資源的過程?
      • 8.4、描述用瀏覽器訪問www.baidu.com的過程
      • 8.5、Post和Get請求的區(qū)別?
      • 8.6、cookie 和session 的區(qū)別?
      • 8.7、列出你知道的HTTP協(xié)議的狀態(tài)碼,說出表示什么意思?
      • 8.8、請簡單說一下三次握手和四次揮手?
      • 8.9、說一下什么是tcp的2MSL?
      • 8.10、為什么客戶端在TIME-WAIT狀態(tài)必須等待2MSL的時間?
      • 8.11、說說HTTP和HTTPS區(qū)別?
      • 8.12、談一下HTTP協(xié)議以及協(xié)議頭部中表示數(shù)據(jù)類型的字段?
      • 8.13、HTTP請求方法都有什么?
      • 8.14、使用Socket套接字需要傳入哪些參數(shù) ?
      • 8.15、HTTP常見請求頭?
      • 8.16、七層模型?
      • 8.17、url的形式?
    • 三、Web
      • 1、Flask
        • 1.1、對Flask藍圖(Blueprint)的理解?
        • 1.2、Flask和Django路由映射的區(qū)別?
      • Django
        • 2.1、什么是wsgi,uwsgi,uWSGI?
        • 2.3、CORS和CSRF的區(qū)別?
        • 2.4、Session、Cookie、JWT的理解
        • 2.5、簡述Django請求生命周期
        • 2.6、什么是wsgi,uwsgi,uWSGI?
        • 2.7、Django 、Flask、Tornado的對比
        • 2.8、用的restframework完成api發(fā)送時間時區(qū)
        • 2.9、nginx,tomcat,apache 都是什么?
        • 2.10、請給出你熟悉關系數(shù)據(jù)庫范式有那些,有什么作用
        • 2.11、簡述QQ登陸過程
        • 2.12、post和get 的區(qū)別?
        • 2.13、項目中日志的作用
        • 2.14、django中間件的使用?
        • 2.15、談一下你對uWSGI和 nginx的理解?
        • 2.16、Python中三大框架各自的應用場景?
        • 2.17、有過部署經(jīng)驗?用的什么技術?可以滿足多少壓力?
        • 2.18、Django中哪里用到了線程?哪里用到了協(xié)程?哪里用到了進程?
        • 2.19、有用過Django REST framework 嗎?
        • 2.20、對cookie與session的了解?他們能單獨用嗎?
      • 爬蟲
        • 1.1、試列出至少三種目前流行的大型數(shù)據(jù)庫
        • 1.2、列舉您使用過的Python網(wǎng)絡爬蟲所用到的網(wǎng)絡數(shù)據(jù)包?
        • 1.3、列舉您使用過的Python網(wǎng)絡爬蟲所用到的解析數(shù)據(jù)包?
        • 1.4、爬取數(shù)據(jù)后使用哪個數(shù)據(jù)庫存儲數(shù)據(jù)的,為什么?
        • 1.5、你用過的爬蟲框架或者模塊有哪些?優(yōu)缺點?
        • 1.6、寫爬蟲是用多進程好?還是多線程好?
        • 1.7、常見的反爬蟲和應對方法?
        • 1.8、解析網(wǎng)頁的解析器使用最多的是哪幾個?
        • 1.9、需要登錄的網(wǎng)頁,如何解決同時限制ip,cookie,session
        • 1.10、驗證碼的解決?
        • 1.11、使用最多的數(shù)據(jù)庫,對他們的理解?
        • 1.12、編寫過哪些爬蟲中間件?
        • 1.13、“極驗”滑動驗證碼如何破解?
        • 1.14、爬蟲多久爬一次,爬下來的數(shù)據(jù)是怎么存儲?
        • 1.15、cookie過期的處理問題?
        • 1.16、動態(tài)加載又對及時性要求很高怎么處理?
        • 1.17、HTTPS有什么優(yōu)點和缺點?
        • 1.18、HTTPS是如何實現(xiàn)安全傳輸數(shù)據(jù)的?
        • 1.19、TTL,MSL,RTT各是什么?
        • 1.20、談一談你對Selenium和PhantomJS了解
        • 1.21、平常怎么使用代理的 ?
        • 1.22、存放在數(shù)據(jù)庫(redis、mysql等)。
        • 1.23、怎么監(jiān)控爬蟲的狀態(tài)?
        • 1.24、描述下scrapy框架運行的機制?
        • 1.25、談談你對Scrapy的理解?
        • 1.26、怎么樣讓 scrapy 框架發(fā)送一個 post 請求(具體寫出來)
        • 1.27、怎么監(jiān)控爬蟲的狀態(tài) ?
        • 1.28、怎么判斷網(wǎng)站是否更新?
        • 1.29、圖片、視頻爬取怎么繞過防盜連接
        • 1.30、你爬出來的數(shù)據(jù)量大概有多大?大概多長時間爬一次?
        • 1.31、用什么數(shù)據(jù)庫存爬下來的數(shù)據(jù)?部署是你做的嗎?怎么部署?
        • 1.32、增量爬取
        • 1.33、爬取下來的數(shù)據(jù)如何去重,說一下scrapy的具體的算法依據(jù)。
        • 1.34、Scrapy的優(yōu)缺點?
        • 1.35、怎么設置爬取深度?
        • 1.36、scrapy和scrapy-redis有什么區(qū)別?為什么選擇redis數(shù)據(jù)庫?
        • 1.37、分布式爬蟲主要解決什么問題?
        • 1.38、什么是分布式存儲?
        • 1.39、你所知道的分布式爬蟲方案有哪些?
        • 1.40、scrapy-redis,有做過其他的分布式爬蟲嗎?
  • 五、數(shù)據(jù)庫

    • 1、MySQL
      • 1.1、主鍵 超鍵 候選鍵 外鍵
      • 1.2、視圖的作用,視圖可以更改么?
      • 1.3、drop,delete與truncate的區(qū)別
      • 1.4、索引的工作原理及其種類
      • 1.5、連接的種類
      • 1.6、數(shù)據(jù)庫優(yōu)化的思路
      • 1.7、存儲過程與觸發(fā)器的區(qū)別
      • 1.8、悲觀鎖和樂觀鎖是什么?
      • 1.9、你常用的mysql引擎有哪些?各引擎間有什么區(qū)別?
    • 2、Redis
      • 2.1、Redis宕機怎么解決?
      • 2.2、redis和mecached的區(qū)別,以及使用場景
      • 2.3、Redis集群方案該怎么做?都有哪些方案?
      • 2.4、Redis回收進程是如何工作的
    • 3、MongoDB
      • 3.1、MongoDB中對多條記錄做更新操作命令是什么?
      • 3.2、MongoDB如何才會拓展到多個shard里?
  • 六、測試

    • 1、編寫測試計劃的目的是
    • 2、對關鍵詞觸發(fā)模塊進行測試
    • 3、其他常用筆試題目網(wǎng)址匯總
    • 4、測試人員在軟件開發(fā)過程中的任務是什么
    • 5、一條軟件Bug記錄都包含了哪些內(nèi)容?
    • 6、簡述黑盒測試和白盒測試的優(yōu)缺點
    • 7、請列出你所知道的軟件測試種類,至少5項。
    • 8、Alpha測試與Beta測試的區(qū)別是什么?
    • 9、舉例說明什么是Bug?一個bug report應包含什么關鍵字?
  • 數(shù)據(jù)結構

    • 1.1、數(shù)組中出現(xiàn)次數(shù)超過一半的數(shù)字-Python版
    • 1.2、求100以內(nèi)的質(zhì)數(shù)
    • 1.3、無重復字符的最長子串-Python實現(xiàn)
    • 1.4、通過2個5/6升得水壺從池塘得到3升水
    • 1.5、什么是MD5加密,有什么特點?
    • 1.6、什么是對稱加密和非對稱加密
    • 1.7、冒泡排序的思想?
    • 1.8、快速排序的思想?
    • 1.9、如何判斷單向鏈表中是否有環(huán)?
    • 1.10、你知道哪些排序算法(一般是通過問題考算法)
    • 1.11、斐波那契數(shù)列
    • 1.12、如何翻轉一個單鏈表?
    • 1.13、青蛙跳臺階問題
    • 1.14、兩數(shù)之和 Two Sum
    • 1.15、搜索旋轉排序數(shù)組 Search in Rotated Sorted Array
    • 1.16、Python實現(xiàn)一個Stack的數(shù)據(jù)結構
    • 1.17、寫一個二分查找
    • 1.18、set 用 in 時間復雜度是多少,為什么?
    • 1.19、列表中有n個正整數(shù)范圍在[0,1000],進行排序;
    • 1.20、面向?qū)ο缶幊讨杏薪M合和繼承的方法實現(xiàn)新的類
  • 八、人工智能

    • 1.1、找出1G的文件中高頻詞
    • 1.2、一個大約有一萬行的文本文件統(tǒng)計高頻詞
    • 1.3、怎么在海量數(shù)據(jù)中找出重復次數(shù)最多的一個?
    • 1.4、判斷數(shù)據(jù)是否在大量數(shù)據(jù)中

Python基礎

1.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的文件,但是內(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ù)的位置。分批每次讀取數(shù)據(jù)的大小,太小會在讀取操作花費過多時間。

1.2 補充缺失的代碼

    def print_directory_contents(sPath):
    """
    這個函數(shù)接收文件夾的名稱作為輸入?yún)?shù)
    返回該文件夾中文件的路徑
    以及其包含文件夾中文件的路徑
    """
    import os
    for sChild in os.listdir(sPath):
        sChildPath = os.path.join(sPath,sChild)
        if os.path.isdir(sChildPath):
            print_directory_contents(sChildPath)
        else:
            print(sChildPath)

模塊與包

2.1 輸入日期, 判斷這一天是這一年的第幾天?

    import datetime
    def 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

2.2 打亂一個排好序的list對象alist?

    import random
    alist = [1,2,3,4,5]
    random.shuffle(alist)
    print(alist)

數(shù)據(jù)類型

3.1 現(xiàn)有字典 d= {'a':24,'g':52,'i':12,'k':33}請按value值進行排序?

    sorted(d.items(),key=lambda x:x[1])

3.2 字典推導式

 d = {key:value for (key,value) in iterable}

3.3 請反轉字符串 "aStr"?

    print("aStr"[::-1])

3.4 將字符串 "k:1 |k1:2|k2:3|k3:4",處理成字典 {k:1,k1:2,...}

    str1 = "k:1|k1:2|k2:3|k3:4"
    def str2dict(str1):
        dict1 = {}
        for iterms in str1.split('|'):
            key,value = iterms.split(':'):
                dict1[key] = value
        return dict1

3.5 請按alist中元素的age由小到大排序

    alist = [{'name':'a','age':20},{'name':'b','age':30},{'name':'c','age':25}]
    def sort_by_age(list1):
        return sorted(alist,key=lambda x:x['age'],reverse=True)

3.6 下面代碼的輸出結果將是什么?

    list = ['a','b','c','d','e']
    print(list[10:])

代碼將輸出[],不會產(chǎn)生IndexError錯誤,就像所期望的那樣,嘗試用超出成員的個數(shù)的index來獲取某個列表的成員。例如,嘗試獲取list[10]和之后的成員,會導致IndexError。然而,嘗試獲取列表的切片,開始的index超過了成員個數(shù)不會產(chǎn)生IndexError,而是僅僅返回一個空列表。這成為特別讓人惡心的疑難雜癥,因為運行的時候沒有錯誤產(chǎn)生,導致Bug很難被追蹤到。

3.7 寫一個列表生成式,產(chǎn)生一個公差為11的等差數(shù)列

    print([x*11 for x in range(10)])

3.8 給定兩個列表,怎么找出他們相同的元素和不同的元素?

    list1 = [1,2,3]
    list2 = [3,4,5]
    set1 = set(list1)
    set2 = set(list2)
    print(set1 & set2)
    print(set1 ^ set2)

3.9 請寫出一段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)

3.10 給定兩個list A,B ,請用找出A,B中相同與不同的元素

    A,B 中相同元素: print(set(A)&set(B))
    A,B 中不同元素:  print(set(A)^set(B))

企業(yè)面試題

4.1 python新式類和經(jīng)典類的區(qū)別?

a. 在python里凡是繼承了object的類,都是新式類
b. Python3里只有新式類
c. Python2里面繼承object的是新式類,沒有寫父類的是經(jīng)典類
d. 經(jīng)典類目前在Python里基本沒有應用

4.2 python中內(nèi)置的數(shù)據(jù)結構有幾種?

a. 整型 int、 長整型 long、浮點型 float、 復數(shù) complex
b. 字符串 str、 列表list、 元祖tuple
c. 字典 dict 、 集合 set

4.3 python如何實現(xiàn)單例模式?請寫出兩種實現(xiàn)方式?

第一種方法:使用裝飾器

    def singleton(cls):
        instances = {}
        def wrapper(*args, **kwargs):
            if cls not in instances:
                instances[cls] = cls(*args, **kwargs)
            return instances[cls]
        return wrapper
    @singleton
    class Foo(object):
        pass
    foo1 = Foo()
    foo2 = Foo()
    print foo1 is foo2 #True

第二種方法:使用基類
New 是真正創(chuàng)建實例對象的方法,所以重寫基類的new 方法,以此保證創(chuàng)建對象的時候只生成一個實例

    class Singleton(object):
        def __new__(cls,*args,**kwargs):
            if not hasattr(cls,'_instance'):
                cls._instance = super(Singleton,cls).__new__(cls,*args,**kwargs)
            return cls._instance
        
    class Foo(Singleton):
        pass
    
    foo1 = Foo()
    foo2 = Foo()

    print foo1 is foo2 #True

第三種方法:元類,元類是用于創(chuàng)建類對象的類,類對象創(chuàng)建實例對象時一定要調(diào)用call方法,因此在調(diào)用call時候保證始終只創(chuàng)建一個實例即可,type是python的元類

    class Singleton(type):
        def __call__(cls,*args,**kwargs):
            if not hasattr(cls,'_instance'):
                cls._instance = super(Singleton,cls).__call__(*args,**kwargs)
            return cls._instance
    class Foo(object):
        __metaclass__ = Singleton
    
    foo1 = Foo()
    foo2 = Foo()
    print foo1 is foo2 #True

4.4 反轉一個整數(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)

4.5 設計實現(xiàn)遍歷目錄與子目錄,抓取.pyc文件

第一種方法:

    import os

    def 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 os
    
    def 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)

4.6 一行代碼實現(xiàn)1-100之和

    count = sum(range(0,101))
    print(count)

Python高級

4設計模式

4.1 對設計模式的理解,簡述你了解的設計模式?

設計模式是經(jīng)過總結,優(yōu)化的,對我們經(jīng)常會碰到的一些編程問題的可重用解決方案。一個設計模式并不像一個類或一個庫那樣能夠直接作用于我們的代碼,反之,設計模式更為高級,它是一種必須在特定情形下實現(xiàn)的一種方法模板。
常見的是工廠模式和單例模式

4.2 請手寫一個單例

    #python2
    class A(object):
        __instance = None
        def __new__(cls,*args,**kwargs):
            if cls.__instance is None:
                cls.__instance = objecet.__new__(cls)
                return cls.__instance
            else:
                return cls.__instance

4.3 單例模式的應用場景有那些?

單例模式應用的場景一般發(fā)現(xiàn)在以下條件下:
資源共享的情況下,避免由于資源操作時導致的性能或損耗等,如日志文件,應用配置。
控制資源的情況下,方便資源之間的互相通信。如線程池等,1,網(wǎng)站的計數(shù)器 2,應用配置 3.多線程池 4數(shù)據(jù)庫配置 數(shù)據(jù)庫連接池 5.應用程序的日志應用...

4.5 對裝飾器的理解,并寫出一個計時器記錄方法執(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())

4.6 解釋以下什么是閉包?

在函數(shù)內(nèi)部再定義一個函數(shù),并且這個函數(shù)用到了外邊函數(shù)的變量,那么將這個函數(shù)以及用到的一些變量稱之為閉包。

4.7 函數(shù)裝飾器有什么作用?

裝飾器本質(zhì)上是一個python函數(shù),它可以在讓其他函數(shù)在不需要做任何代碼的變動的前提下增加額外的功能。裝飾器的返回值也是一個函數(shù)的對象,它經(jīng)常用于有切面需求的場景。比如:插入日志,性能測試,事務處理,緩存。權限的校驗等場景,有了裝飾器就可以抽離出大量的與函數(shù)功能本身無關的雷同代碼并發(fā)并繼續(xù)使用。

4.8 生成器,迭代器的區(qū)別?

迭代器是一個更抽象的概念,任何對象,如果它的類有next方法和iter方法返回自己本身,對于string,list,dict,tuple等這類容器對象,使用for循環(huán)遍歷是很方便的,在后臺for語句對容器對象調(diào)用iter()函數(shù),iter()是python的內(nèi)置函數(shù),iter()會返回一個定義了next()方法的迭代器對象,它在容器中逐個訪問容器內(nèi)元素,next()也是python的內(nèi)置函數(shù),在沒有后續(xù)元素時,next()會拋出一個StopIteration異常。
生成器(Generator)是創(chuàng)建迭代器的簡單而強大的工具。它們寫起來就像是正規(guī)的函數(shù),只是在需要返回數(shù)據(jù)的時候使用yield語句。每次next()被調(diào)用時,生成器會返回它脫離的位置(它記憶語句最后一次執(zhí)行的位置和所有的數(shù)據(jù)值)
區(qū)別: 生成器能做到迭代器能做的所有事,而且因為自動創(chuàng)建iter()和next()方法,生成器顯得特別簡潔,而且生成器也是高效的,使用生成器表達式取代列表解析可以同時節(jié)省內(nèi)存。除了創(chuàng)建和保存程序狀態(tài)的自動方法,當發(fā)生器終結時,還會自動拋出StopIteration異常。

4.9 X是什么類型?

X= (fo ri in ramg(10))
X是 generator類型

4.10 請用一行代碼 實現(xiàn)將1-N 的整數(shù)列表以3為單位分組

    print ([[x for x in range(1,100)] [i:i+3] for i in range(0,len(list_a),3)])

4.11 Python中yield的用法》

yield就是保存當前程序執(zhí)行狀態(tài)。你用for循環(huán)的時候,每次取一個元素的時候就會計算一次。用yield的函數(shù)叫generator,和iterator一樣,它的好處是不用一次計算所有元素,而是用一次算一次,可以節(jié)省很多空間,generator每次計算需要上一次計算結果,所以用yield,否則一return,上次計算結果就沒了

7系統(tǒng)編程

7.1 進程總結

進程:程序運行在操作系統(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()啟動進程
結束進程
給子進程指定函數(shù)傳遞參數(shù)Demo

    import os
    from 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秒鐘之后,立刻結束子進程
        p.terminate()
        p.join()

注意:進程間不共享全局變量
進程之間的通信-Queue
在初始化Queue()對象時(例如q=Queue(),若在括號中沒有指定最大可接受的消息數(shù)量,獲數(shù)量為負值時,那么就代表可接受的消息數(shù)量沒有上限一直到內(nèi)存盡頭)
Queue.qsize():返回當前隊列包含的消息數(shù)量
Queue.empty():如果隊列為空,返回True,反之False
Queue.full():如果隊列滿了,返回True,反之False
Queue.get([block[,timeout]]):獲取隊列中的一條消息,然后將其從隊列中移除,block默認值為True。
如果block使用默認值,且沒有設置timeout(單位秒),消息隊列如果為空,此時程序?qū)⒈蛔枞ㄍT谧x中狀態(tài)),直到消息隊列讀到消息為止,如果設置了timeout,則會等待timeout秒,若還沒讀取到任何消息,則拋出“Queue.Empty"異常:
Queue.get_nowait()相當于Queue.get(False)
Queue.put(item,[block[,timeout]]):將item消息寫入隊列,block默認值為True;
如果block使用默認值,且沒有設置timeout(單位秒),消息隊列如果已經(jīng)沒有空間可寫入,此時程序?qū)⒈蛔枞ㄍT趯懭霠顟B(tài)),直到從消息隊列騰出空間為止,如果設置了timeout,則會等待timeout秒,若還沒空間,則拋出”Queue.Full"異常
如果block值為False,消息隊列如果沒有空間可寫入,則會立刻拋出"Queue.Full"異常;
Queue.put_nowait(item):相當Queue.put(item,False)
進程間通信Demo:

    from multiprocessing import Process.Queue
    import os,time,random
    #寫數(shù)據(jù)進程執(zhí)行的代碼:
    def write(q):
        for value in ['A','B','C']:
            print("Put %s to queue...",%value)
            q.put(value)
            time.sleep(random.random())
    #讀數(shù)據(jù)進程執(zhí)行的代碼
    def read(q):
        while True:
            if not q.empty():
                value = q.get(True)
                print("Get %s from queue.",%value)
                time.sleep(random.random())
            else:
                break
    if __name__=='__main__':
        #父進程創(chuàng)建Queue,并傳給各個子進程
        q = Queue()
        pw = Process(target=write,args=(q,))
        pr = Process(target=read,args=(q,))
        #啟動子進程pw ,寫入:
        pw.start()
        #等待pw結束
        pw.join()
        #啟動子進程pr,讀?。?        pr.start()
        pr.join()
        #pr 進程里是死循環(huán),無法等待其結束,只能強行終止:
        print('')
        print('所有數(shù)據(jù)都寫入并且讀完')
進程池Pool
        #coding:utf-8
        from multiprocessing import Pool
        import os,time,random
        
        def worker(msg):
            t_start = time.time()
            print("%s 開始執(zhí)行,進程號為%d"%(msg,os.getpid()))
            # random.random()隨機生成0-1之間的浮點數(shù)
            time.sleep(random.random()*2)
            t_stop = time.time()
            print(msg,"執(zhí)行完畢,耗時%0.2f”%(t_stop-t_start))
        
        po = Pool(3)#定義一個進程池,最大進程數(shù)3
        for i in range(0,10):
            po.apply_async(worker,(i,))
        print("---start----")
        po.close()
        po.join()
        print("----end----")

進程池中使用Queue
如果要使用Pool創(chuàng)建進程,就需要使用multiprocessing.Manager()中的Queue(),而不是multiprocessing.Queue(),否則會得到如下的錯誤信息:
RuntimeError: Queue objects should only be shared between processs through inheritance

        from multiprocessing import Manager,Pool
        import os,time,random
        def reader(q):
            print("reader 啟動(%s),父進程為(%s)"%(os.getpid(),os.getpid()))
            for i in range(q.qsize()):
                print("reader 從Queue獲取到消息:%s"%q.get(True))

        def writer(q):
            print("writer 啟動(%s),父進程為(%s)"%(os.getpid(),os.getpid()))
            for i ini "itcast":
                q.put(i)
        if __name__ == "__main__":
            print("(%s)start"%os.getpid())
            q = Manager().Queue()#使用Manager中的Queue
            po = Pool()
            po.apply_async(wrtier,(q,))
            time.sleep(1)
            po.apply_async(reader,(q,))
            po.close()
            po.join()
            print("(%s)End"%os.getpid())

7.2 談談你對多進程,多線程,以及協(xié)程的理解,項目是否用?

這個問題被問的概念相當之大,
進程:一個運行的程序(代碼)就是一個進程,沒有運行的代碼叫程序,進程是系統(tǒng)資源分配的最小單位,進程擁有自己獨立的內(nèi)存空間,所有進程間數(shù)據(jù)不共享,開銷大。
線程: cpu調(diào)度執(zhí)行的最小單位,也叫執(zhí)行路徑,不能獨立存在,依賴進程存在,一個進程至少有一個線程,叫主線程,而多個線程共享內(nèi)存(數(shù)據(jù)共享,共享全局變量),從而極大地提高了程序的運行效率。
協(xié)程: 是一種用戶態(tài)的輕量級線程,協(xié)程的調(diào)度完全由用戶控制。協(xié)程擁有自己的寄存器上下文和棧。協(xié)程調(diào)度時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操中棧則基本沒有內(nèi)核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切換非???。

7.3 Python異常使用場景有那些?

異步的使用場景:
1、 不涉及共享資源,獲對共享資源只讀,即非互斥操作
2、 沒有時序上的嚴格關系
3、 不需要原子操作,或可以通過其他方式控制原子性
4、 常用于IO操作等耗時操作,因為比較影響客戶體驗和使用性能
5、 不影響主線程邏輯

7.4 多線程共同操作同一個數(shù)據(jù)互斥鎖同步?

    import threading
    import time
    class MyThread(threading.Thread):
        def run(self):
            global num
            time.sleep(1)
        
            if mutex.acquire(1):
                num +=1
                msg = self.name + 'set num to ' +str(num)
                print msg
                mutex.release()
    num = 0
    mutex = threading.Lock()
    def test():
        for i in range(5):
            t = MyThread()
            t.start()
    if __name__=="__main__":
        test()

7.5 什么是多線程競爭?

線程是非獨立的,同一個進程里線程是數(shù)據(jù)共享的,當各個線程訪問數(shù)據(jù)資源時會出現(xiàn)競爭狀態(tài)即:數(shù)據(jù)幾乎同步會被多個線程占用,造成數(shù)據(jù)混亂,即所謂的線程不安全
那么怎么解決多線程競爭問題?---鎖
鎖的好處: 確保了某段關鍵代碼(共享數(shù)據(jù)資源)只能由一個線程從頭到尾完整地執(zhí)行能解決多線程資源競爭下的原子操作問題。
鎖的壞處: 阻止了多線程并發(fā)執(zhí)行,包含鎖的某段代碼實際上只能以單線程模式執(zhí)行,效率就大大地下降了
鎖的致命問題: 死鎖

7.6 請介紹一下Python的線程同步?

一、 setDaemon(False)
當一個進程啟動之后,會默認產(chǎn)生一個主線程,因為線程是程序執(zhí)行的最小單位,當設置多線程時,主線程會創(chuàng)建多個子線程,在Python中,默認情況下就是setDaemon(False),主線程執(zhí)行完自己的任務以后,就退出了,此時子線程會繼續(xù)執(zhí)行自己的任務,直到自己的任務結束。
例子

    import threading 
    import time
    
    def thread():
        time.sleep(2)
        print('---子線程結束---')
    
    def main():
        t1 = threading.Thread(target=thread)
        t1.start()
        print('---主線程--結束')
    
    if __name__ =='__main__':
        main()
    #執(zhí)行結果
    ---主線程--結束
    ---子線程結束---

二、 setDaemon(True)
當我們使用setDaemon(True)時,這是子線程為守護線程,主線程一旦執(zhí)行結束,則全部子線程被強制終止
例子

    import threading
    import time
    def thread():
        time.sleep(2)
        print(’---子線程結束---')
    def main():
        t1 = threading.Thread(target=thread)
        t1.setDaemon(True)#設置子線程守護主線程
        t1.start()
        print('---主線程結束---')
    
    if __name__ =='__main__':
        main()
    #執(zhí)行結果
    ---主線程結束--- #只有主線程結束,子線程來不及執(zhí)行就被強制結束

三、 join(線程同步)
join 所完成的工作就是線程同步,即主線程任務結束以后,進入堵塞狀態(tài),一直等待所有的子線程結束以后,主線程再終止。
當設置守護線程時,含義是主線程對于子線程等待timeout的時間將會殺死該子線程,最后退出程序,所以說,如果有10個子線程,全部的等待時間就是每個timeout的累加和,簡單的來說,就是給每個子線程一個timeou的時間,讓他去執(zhí)行,時間一到,不管任務有沒有完成,直接殺死。
沒有設置守護線程時,主線程將會等待timeout的累加和這樣的一段時間,時間一到,主線程結束,但是并沒有殺死子線程,子線程依然可以繼續(xù)執(zhí)行,直到子線程全部結束,程序退出。
例子

    import threading
    import time

    def thread():
        time.sleep(2)
        print('---子線程結束---')
    
    def main():
        t1 = threading.Thread(target=thread)
        t1.setDaemon(True)
        t1.start()
        t1.join(timeout=1)#1 線程同步,主線程堵塞1s 然后主線程結束,子線程繼續(xù)執(zhí)行
                          #2 如果不設置timeout參數(shù)就等子線程結束主線程再結束
                          #3 如果設置了setDaemon=True和timeout=1主線程等待1s后會強制殺死子線程,然后主線程結束
        print('---主線程結束---')
    
    if __name__=='__main___':
        main()

7.7 解釋以下什么是鎖,有哪幾種鎖?

鎖(Lock)是python提供的對線程控制的對象。有互斥鎖,可重入鎖,死鎖。

7.8 什么是死鎖?

若干子線程在系統(tǒng)資源競爭時,都在等待對方對某部分資源解除占用狀態(tài),結果是誰也不愿先解鎖,互相干等著,程序無法執(zhí)行下去,這就是死鎖。
GIL鎖 全局解釋器鎖(只在cython里才有)
作用: 限制多線程同時執(zhí)行,保證同一時間只有一個線程執(zhí)行,所以cython里的多線程其實是偽多線程!
所以python里常常使用協(xié)程技術來代替多線程,協(xié)程是一種更輕量級的線程。
進程和線程的切換時由系統(tǒng)決定,而協(xié)程由我們程序員自己決定,而模塊gevent下切換是遇到了耗時操作時才會切換
三者的關系:進程里有線程,線程里有協(xié)程。

7.9 多線程交互訪問數(shù)據(jù),如果訪問到了就不訪問了?

怎么避免重讀?
創(chuàng)建一個已訪問數(shù)據(jù)列表,用于存儲已經(jīng)訪問過的數(shù)據(jù),并加上互斥鎖,在多線程訪問數(shù)據(jù)的時候先查看數(shù)據(jù)是否在已訪問的列表中,若已存在就直接跳過。

7.10 什么是線程安全,什么是互斥鎖?

每個對象都對應于一個可稱為’互斥鎖‘的標記,這個標記用來保證在任一時刻,只能有一個線程訪問該對象。
同一進程中的多線程之間是共享系統(tǒng)資源的,多個線程同時對一個對象進行操作,一個線程操作尚未結束,另一線程已經(jīng)對其進行操作,導致最終結果出現(xiàn)錯誤,此時需要對被操作對象添加互斥鎖,保證每個線程對該對象的操作都得到正確的結果。

7.11說說下面幾個概念:同步,異步,阻塞,非阻塞?

同步: 多個任務之間有先后順序執(zhí)行,一個執(zhí)行完下個才能執(zhí)行。
異步: 多個任務之間沒有先后順序,可以同時執(zhí)行,有時候一個任務可能要在必要的時候獲取另一個同時執(zhí)行的任務的結果,這個就叫回調(diào)!
阻塞: 如果卡住了調(diào)用者,調(diào)用者不能繼續(xù)往下執(zhí)行,就是說調(diào)用者阻塞了。
非阻塞: 如果不會卡住,可以繼續(xù)執(zhí)行,就是說非阻塞的。
同步異步相對于多任務而言,阻塞非阻塞相對于代碼執(zhí)行而言。

7.12 什么是僵尸進程和孤兒進程?怎么避免僵尸進程?

孤兒進程: 父進程退出,子進程還在運行的這些子進程都是孤兒進程,孤兒進程將被init 進程(進程號為1)所收養(yǎng),并由init 進程對他們完成狀態(tài)收集工作。
僵尸進程: 進程使用fork 創(chuàng)建子進程,如果子進程退出,而父進程并沒有調(diào)用wait 獲waitpid 獲取子進程的狀態(tài)信息,那么子進程的進程描述符仍然保存在系統(tǒng)中的這些進程是僵尸進程。
避免僵尸進程的方法:
1.fork 兩次用孫子進程去完成子進程的任務
2.用wait()函數(shù)使父進程阻塞
3.使用信號量,在signal handler 中調(diào)用waitpid,這樣父進程不用阻塞

7.13 python中進程與線程的使用場景?

多進程適合在CPU密集操作(cpu操作指令比較多,如位多的的浮點運算)。
多線程適合在IO密性型操作(讀寫數(shù)據(jù)操作比多的的,比如爬蟲)

7.14 線程是并發(fā)還是并行,進程是并發(fā)還是并行?

線程是并發(fā),進程是并行;
進程之間互相獨立,是系統(tǒng)分配資源的最小單位,同一個線程中的所有線程共享資源。

7.15 并行(parallel)和并發(fā)(concurrency)?

并行: 同一時刻多個任務同時在運行
并發(fā): 在同一時間間隔內(nèi)多個任務都在運行,但是并不會在同一時刻同時運行,存在交替執(zhí)行的情況。
實現(xiàn)并行的庫有: multiprocessing
實現(xiàn)并發(fā)的庫有: threading
程序需要執(zhí)行較多的讀寫、請求和回復任務的需要大量的IO操作,IO密集型操作使用并發(fā)更好。
CPU運算量大的程序,使用并行會更好

7.16 IO密集型和CPU密集型區(qū)別?

IO密集型: 系統(tǒng)運行,大部分的狀況是CPU在等 I/O(硬盤/內(nèi)存)的讀/寫
CPU密集型: 大部分時間用來做計算,邏輯判斷等CPU動作的程序稱之CPU密集型。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 在一個方法內(nèi)部定義的變量都存儲在棧中,當這個函數(shù)運行結束后,其對應的棧就會被回收,此時,在其方法體中定義的變量將不...
    Y了個J閱讀 4,547評論 1 14
  • 1. Object-c的類可以多重繼承么?可以實現(xiàn)多個接口么?Category是什么?重寫一個類的方式用繼承好還是...
    Charls丶閱讀 790評論 0 0
  • 1. Object-c的類可以多重繼承么?可以實現(xiàn)多個接口么?Category是什么?重寫一個類的方式用繼承好還是...
    方圓十里不留母狗閱讀 2,426評論 5 6
  • 1 Java 基礎 JVM JRE JDK 的區(qū)別 基本數(shù)據(jù)類型 int和Integer的區(qū)別 1、Intege...
    積土成城閱讀 1,296評論 0 1
  • 一、Python簡介和環(huán)境搭建以及pip的安裝 4課時實驗課主要內(nèi)容 【Python簡介】: Python 是一個...
    _小老虎_閱讀 6,313評論 0 10

友情鏈接更多精彩內(nèi)容