[Python面试][基础算法题]Python基础面试(基础算法题目较多)
- Python基礎(chǔ) - 文件操作 - 1.有一個jsonline格式的文件file.txt大小約為10K
- 2.補(bǔ)充缺失的代碼
 
- 模塊與包 - 3.輸入日期, 判斷這一天是這一年的第幾天?
- 4.打亂一個排好序的list對象alist?
 
- 數(shù)據(jù)類型 - 5.現(xiàn)有字典 d= {‘a(chǎn)’:24,‘g’:52,‘i’:12,‘k’:33}請按value值進(jìn)行排序?
- 6.字典推導(dǎo)式
- 7.請反轉(zhuǎn)字符串 “aStr”?
- 8.將字符串 “k:1 |k1:2|k2:3|k3:4”,處理成字典 {k:1,k1:2,…}
- 9.請按alist中元素的age由大到小排序
- 10.下面代碼的輸出結(jié)果將是什么?
- 11.寫一個列表生成式,產(chǎn)生一個公差為11的等差數(shù)列
- 12.給定兩個列表,怎么找出他們相同的元素和不同的元素?
- 13.請寫出一段python代碼實(shí)現(xiàn)刪除list里面的重復(fù)元素?
- 14.給定兩個list A,B ,請用找出A,B中相同與不同的元素
 
- 企業(yè)面試題 - 15.python新式類和經(jīng)典類的區(qū)別?
- 16.python中內(nèi)置的數(shù)據(jù)結(jié)構(gòu)有幾種?
- 17.python如何實(shí)現(xiàn)單例模式?請寫出兩種實(shí)現(xiàn)方式?
- 18.反轉(zhuǎn)一個整數(shù),例如-123 --> -321
- 19.設(shè)計(jì)實(shí)現(xiàn)遍歷目錄與子目錄,抓取.pyc文件
- 20.一行代碼實(shí)現(xiàn)1-100之和
- 21.Python-遍歷列表時刪除元素的正確做法
- 22.字符串的操作題目
- 23.可變類型和不可變類型
- 24.is和==有什么區(qū)別?
- 25.求出列表所有奇數(shù)并構(gòu)造新列表
- 26.用一行python代碼寫出1+2+3+10248
- 27.Python中變量的作用域?(變量查找順序)
- 28.字符串”123″轉(zhuǎn)換成123,不使用內(nèi)置api,例如int()
- 29.Given an array of integers
- 30.python代碼實(shí)現(xiàn)刪除一個list里面的重復(fù)元素
- 31.統(tǒng)計(jì)一個文本中單詞頻次最高的10個單詞?
- 32.請寫出一個函數(shù)滿足以下條件
- 33.使用單一的列表生成式來產(chǎn)生一個新的列表
- 34.用一行代碼生成[1,4,9,16,25,36,49,64,81,100]
- 35.輸入某年某月某日,判斷這一天是這一年的第幾天?
- 36.兩個有序列表,l1,l2,對這兩個列表進(jìn)行合并不可使用extend
- 37.給定一個任意長度數(shù)組,實(shí)現(xiàn)一個函數(shù)
- 38.寫一個函數(shù)找出一個整數(shù)數(shù)組中,第二大的數(shù)
- 39.閱讀一下代碼他們的輸出結(jié)果是什么?
- 40.統(tǒng)計(jì)一段字符串中字符出現(xiàn)的次數(shù)
- 41.super函數(shù)的具體用法和場景
 
 
- 文件操作 
- Python高級 - 元類 - 42.Python中類方法、類實(shí)例方法、靜態(tài)方法有何區(qū)別?
- 43.遍歷一個object的所有屬性,并print每一個屬性名?
- 44.寫一個類,并讓它盡可能多的支持操作符?
- 45.介紹Cython,Pypy Cpython Numba各有什么缺點(diǎn)
- 46.請描述抽象類和接口類的區(qū)別和聯(lián)系
- 47.Python中如何動態(tài)獲取和設(shè)置對象的屬性?
 
- 內(nèi)存管理與垃圾回收機(jī)制 - 48.哪些操作會導(dǎo)致Python內(nèi)存溢出,怎么處理?
- 49.關(guān)于Python內(nèi)存管理,下列說法錯誤的是
- 50.Python的內(nèi)存管理機(jī)制及調(diào)優(yōu)手段?
- 51.內(nèi)存泄露是什么?如何避免?
 
- 函數(shù) - 52.python常見的列表推導(dǎo)式?
- 53.簡述read、readline、readlines的區(qū)別?
- 54.什么是Hash(散列函數(shù))?
- 55.python函數(shù)重載機(jī)制?
- 56.寫一個函數(shù)找出一個整數(shù)數(shù)組中,第二大的數(shù)
- 57.手寫一個判斷時間的裝飾器
- 58.使用Python內(nèi)置的filter()方法來過濾?
- 59.編寫函數(shù)的4個原則
- 60.函數(shù)調(diào)用參數(shù)的傳遞方式是值傳遞還是引用傳遞?
- 61.如何在function里面設(shè)置一個全局變量
- 62.對缺省參數(shù)的理解 ?
- 63.Mysql怎么限制IP訪問?
- 64.帶參數(shù)的裝飾器?
- 65.為什么函數(shù)名字可以當(dāng)做參數(shù)用?
- 66.Python中pass語句的作用是什么?
- 67.有這樣一段代碼,print c會輸出什么,為什么?
- 68.交換兩個變量的值?
- 69.map函數(shù)和reduce函數(shù)?
- 70.回調(diào)函數(shù),如何通信的?
- 71.Python主要的內(nèi)置數(shù)據(jù)類型都有哪些? print dir( ‘a(chǎn) ’) 的輸出?
- 72.map(lambda x:xx,[y for y in range(3)])的輸出?
- 73.hasattr() getattr() setattr() 函數(shù)使用詳解?
- 74.一句話解決階乘函數(shù)?
- 75.什么是lambda函數(shù)? 有什么好處?
- 76.遞歸函數(shù)停止的條件?
- 77.下面這段代碼的輸出結(jié)果將是什么?請解釋。
- 78.什么是lambda函數(shù)?它有什么好處?寫一個匿名函數(shù)求兩個數(shù)的和
 
- 設(shè)計(jì)模式 - 79.對設(shè)計(jì)模式的理解,簡述你了解的設(shè)計(jì)模式?
- 80.請手寫一個單例
- 81.單例模式的應(yīng)用場景有那些?
- 82.用一行代碼生成[1,4,9,16,25,36,49,64,81,100]
- 83.對裝飾器的理解,并寫出一個計(jì)時器記錄方法執(zhí)行性能的裝飾器?
- 84.解釋以下什么是閉包?
- 85.函數(shù)裝飾器有什么作用?
- 86.生成器,迭代器的區(qū)別?
- 87.X是什么類型?
- 88.請用一行代碼 實(shí)現(xiàn)將1-N 的整數(shù)列表以3為單位分組
- 89.Python中yield的用法?
 
- 面向?qū)ο?- 90.Python中的可變對象和不可變對象?
- 91.Python的魔法方法
- 92.面向?qū)ο笾性趺磳?shí)現(xiàn)只讀屬性?
- 93.談?wù)勀銓γ嫦驅(qū)ο蟮睦斫?#xff1f;
 
- 正則表達(dá)式 - 94.請寫出一段代碼用正則匹配出ip?
- 95.a = “abbbccc”,用正則匹配為abccc,不管有多少b,就出現(xiàn)一次?
- 96.Python字符串查找和替換?
- 97.用Python匹配HTML g tag的時候,<.> 和 <.*?> 有什么區(qū)別
- 98.正則表達(dá)式貪婪與非貪婪模式的區(qū)別?
- 99.寫出開頭匹配字母和下劃線,末尾是數(shù)字的正則表達(dá)式?
- 100.正則表達(dá)式操作
- 101.請匹配出變量A 中的json字符串。
- 102.怎么過濾評論中的表情?
- 103.簡述Python里面search和match的區(qū)別
- 104.請寫出匹配ip的Python正則表達(dá)式
- 105.Python里match與search的區(qū)別?
 
- 系統(tǒng)編程 - 106.進(jìn)程總結(jié)
- 107.談?wù)勀銓Χ噙M(jìn)程,多線程,以及協(xié)程的理解,項(xiàng)目是否用?
- 108.Python異常使用場景有那些?
- 109.多線程共同操作同一個數(shù)據(jù)互斥鎖同步?
- 110.什么是多線程競爭?
- 111.請介紹一下Python的線程同步?
- 112.解釋以下什么是鎖,有哪幾種鎖?
- 113.什么是死鎖?
- 114.多線程交互訪問數(shù)據(jù),如果訪問到了就不訪問了?
- 115.什么是線程安全,什么是互斥鎖?
- 116.說說下面幾個概念:同步,異步,阻塞,非阻塞?
- 117.什么是僵尸進(jìn)程和孤兒進(jìn)程?怎么避免僵尸進(jìn)程?
- 118.python中進(jìn)程與線程的使用場景?
- 119.線程是并發(fā)還是并行,進(jìn)程是并發(fā)還是并行?
- 120.并行(parallel)和并發(fā)(concurrency)?
- 121.IO密集型和CPU密集型區(qū)別?
- 122.python asyncio的原理?
 
- 網(wǎng)絡(luò)編程 - 123.怎么實(shí)現(xiàn)強(qiáng)行關(guān)閉客戶端和服務(wù)器之間的連接?
- 124.簡述TCP和UDP的區(qū)別以及優(yōu)缺點(diǎn)?
- 125.簡述瀏覽器通過WSGI請求動態(tài)資源的過程?
- 126.描述用瀏覽器訪問www.baidu.com的過程
- 127.Post和Get請求的區(qū)別?
- 128.cookie 和session 的區(qū)別?
- 129.列出你知道的HTTP協(xié)議的狀態(tài)碼,說出表示什么意思?
- 130.請簡單說一下三次握手和四次揮手?
- 131.說一下什么是tcp的2MSL?
- 132.為什么客戶端在TIME-WAIT狀態(tài)必須等待2MSL的時間?
- 133.說說HTTP和HTTPS區(qū)別?
- 134.談一下HTTP協(xié)議以及協(xié)議頭部中表示數(shù)據(jù)類型的字段?
- 135.HTTP請求方法都有什么?
- 136.使用Socket套接字需要傳入哪些參數(shù) ?
- 137.HTTP常見請求頭?
- 138.七層模型?
- 139.url的形式?
 
 
- 元類 
- Web - Flask - 140.對Flask藍(lán)圖(Blueprint)的理解?
- 141.Flask 和 Django 路由映射的區(qū)別?
 
- Django - 142.什么是wsgi,uwsgi,uWSGI?
- 143.Django、Flask、Tornado的對比?
- 144.CORS 和 CSRF的區(qū)別?
- 145.Session,Cookie,JWT的理解
- 146.簡述Django請求生命周期
- 147.用的restframework完成api發(fā)送時間時區(qū)
- 148.nginx,tomcat,apach到都是什么?
- 149.請給出你熟悉關(guān)系數(shù)據(jù)庫范式有哪些,有什么作用?
- 150.簡述QQ登陸過程
- 151.post 和 get的區(qū)別?
- 152.項(xiàng)目中日志的作用
- 153.django中間件的使用?
- 154.談一下你對uWSGI和nginx的理解?
- 155.Python中三大框架各自的應(yīng)用場景?
- 156.Django中哪里用到了線程?哪里用到了協(xié)程?哪里用到了進(jìn)程?
- 157.有用過Django REST framework嗎?
- 158.對cookies與session的了解?他們能單獨(dú)用嗎?
 
- 爬蟲 - 159.試列出至少三種目前流行的大型數(shù)據(jù)庫
- 160.列舉您使用過的Python網(wǎng)絡(luò)爬蟲所用到的網(wǎng)絡(luò)數(shù)據(jù)包?
- 161.爬取數(shù)據(jù)后使用哪個數(shù)據(jù)庫存儲數(shù)據(jù)的,為什么?
- 162.你用過的爬蟲框架或者模塊有哪些?優(yōu)缺點(diǎn)?
- 163.寫爬蟲是用多進(jìn)程好?還是多線程好?
- 164.常見的反爬蟲和應(yīng)對方法?
- 165.解析網(wǎng)頁的解析器使用最多的是哪幾個?
- 166.需要登錄的網(wǎng)頁,如何解決同時限制ip,cookie,session
- 167.驗(yàn)證碼的解決?
- 168.使用最多的數(shù)據(jù)庫,對他們的理解?
- 169.編寫過哪些爬蟲中間件?
- 170.“極驗(yàn)”滑動驗(yàn)證碼如何破解?
- 171.爬蟲多久爬一次,爬下來的數(shù)據(jù)是怎么存儲?
- 172.cookie過期的處理問題?
- 173.動態(tài)加載又對及時性要求很高怎么處理?
- 174.HTTPS有什么優(yōu)點(diǎn)和缺點(diǎn)?
- 175.HTTPS是如何實(shí)現(xiàn)安全傳輸數(shù)據(jù)的?
- 176.TTL,MSL,RTT各是什么?
- 177.談一談你對Selenium和PhantomJS了解
- 178.平常怎么使用代理的 ?
- 179.存放在數(shù)據(jù)庫(redis、mysql等)。
- 180.怎么監(jiān)控爬蟲的狀態(tài)?
- 181.描述下scrapy框架運(yùn)行的機(jī)制?
- 182.談?wù)勀銓crapy的理解?
- 183.怎么樣讓 scrapy 框架發(fā)送一個 post 請求(具體寫出來)
- 184.怎么監(jiān)控爬蟲的狀態(tài) ?
- 185.怎么判斷網(wǎng)站是否更新?
- 186.圖片、視頻爬取怎么繞過防盜連接
- 187.你爬出來的數(shù)據(jù)量大概有多大?大概多長時間爬一次?
- 188.用什么數(shù)據(jù)庫存爬下來的數(shù)據(jù)?部署是你做的嗎?怎么部署?
- 189.增量爬取
- 190.爬取下來的數(shù)據(jù)如何去重,說一下scrapy的具體的算法依據(jù)。
- 191.Scrapy的優(yōu)缺點(diǎn)?
- 192.怎么設(shè)置爬取深度?
- 193.scrapy和scrapy-redis有什么區(qū)別?為什么選擇redis數(shù)據(jù)庫?
- 194.分布式爬蟲主要解決什么問題?
- 195.什么是分布式存儲?
- 196.你所知道的分布式爬蟲方案有哪些?
- 197.scrapy-redis,有做過其他的分布式爬蟲嗎?
 
 
- Flask 
- 數(shù)據(jù)庫 - MySQL - 198.主鍵 超鍵 候選鍵 外鍵
- 199.視圖的作用,視圖可以更改么?
- 200.drop,delete與truncate的區(qū)別
- 201.索引的工作原理及其種類
- 202.連接的種類
- 203.數(shù)據(jù)庫優(yōu)化的思路
- 204.存儲過程與觸發(fā)器的區(qū)別
- 205.悲觀鎖和樂觀鎖是什么?
- 206.你常用的mysql引擎有哪些?各引擎間有什么區(qū)別?
 
- Redis - 207.Redis宕機(jī)怎么解決?
- 208.redis和mecached的區(qū)別,以及使用場景
- 209.Redis集群方案該怎么做?都有哪些方案?
- 210.Redis回收進(jìn)程是如何工作的
 
- MongoDB - 211.MongoDB中對多條記錄做更新操作命令是什么?
- 212.MongoDB如何才會拓展到多個shard里?
 
- 測試 - 213.編寫測試計(jì)劃的目的是
- 214.對關(guān)鍵詞觸發(fā)模塊進(jìn)行測試
- 215.其他常用筆試題目網(wǎng)址匯總
- 216.測試人員在軟件開發(fā)過程中的任務(wù)是什么
- 217.一條軟件Bug記錄都包含了哪些內(nèi)容?
- 218.簡述黑盒測試和白盒測試的優(yōu)缺點(diǎn)
- 219.請列出你所知道的軟件測試種類,至少5項(xiàng)
- 220.Alpha測試與Beta測試的區(qū)別是什么?
- 221.舉例說明什么是Bug?一個bug report應(yīng)包含什么關(guān)鍵字?
 
- 數(shù)據(jù)結(jié)構(gòu) - 222.數(shù)組中出現(xiàn)次數(shù)超過一半的數(shù)字-Python版
- 223.求100以內(nèi)的質(zhì)數(shù)
- 224.無重復(fù)字符的最長子串-Python實(shí)現(xiàn)
- 225.通過2個5/6升得水壺從池塘得到3升水
- 226.什么是MD5加密,有什么特點(diǎn)?
- 227.什么是對稱加密和非對稱加密
- 228.冒泡排序的思想?
- 229.快速排序的思想?
- 230.如何判斷單向鏈表中是否有環(huán)?
- 231.你知道哪些排序算法(一般是通過問題考算法)
- 232.斐波那契數(shù)列
- 233.如何翻轉(zhuǎn)一個單鏈表?
- 234.青蛙跳臺階問題
- 235.兩數(shù)之和 Two Sum
- 236.搜索旋轉(zhuǎn)排序數(shù)組 Search in Rotated Sorted Array
- 237.Python實(shí)現(xiàn)一個Stack的數(shù)據(jù)結(jié)構(gòu)
- 238.寫一個二分查找
- 239.set 用 in 時間復(fù)雜度是多少,為什么?
- 240.列表中有n個正整數(shù)范圍在[0,1000],進(jìn)行排序;
- 241.面向?qū)ο缶幊讨杏薪M合和繼承的方法實(shí)現(xiàn)新的類
 
- 大數(shù)據(jù) - 242.找出1G的文件中高頻詞
- 243.一個大約有一萬行的文本文件統(tǒng)計(jì)高頻詞
- 244.怎么在海量數(shù)據(jù)中找出重復(fù)次數(shù)最多的一個?
- 245.判斷數(shù)據(jù)是否在大量數(shù)據(jù)中
 
 
- MySQL 
Python基礎(chǔ)
文件操作
1.有一個jsonline格式的文件file.txt大小約為10K
def get_lines():with open('file.txt','rb') as f:return f.readlines()if __name__ == '__main__':for e in get_lines():process(e) # 處理每一行數(shù)據(jù)現(xiàn)在要處理一個大小為10G的文件,但是內(nèi)存只有4G,如果在只修改get_lines 函數(shù)而其他代碼保持不變的情況下,應(yīng)該如何實(shí)現(xiàn)?需要考慮的問題都有那些?
def get_lines():with open('file.txt','rb') as f:for i in f:yield iPandaaaa906提供的方法
from mmap import mmapdef get_lines(fp):with open(fp,"r+") as f:m = mmap(f.fileno(), 0)tmp = 0for i, char in enumerate(m):if char==b"\n":yield m[tmp:i+1].decode()tmp = i+1if __name__=="__main__":for i in get_lines("fp_some_huge_file"):print(i)要考慮的問題有:內(nèi)存只有4G無法一次性讀入10G文件,需要分批讀入分批讀入數(shù)據(jù)要記錄每次讀入數(shù)據(jù)的位置。分批每次讀取數(shù)據(jù)的大小,太小會在讀取操作花費(fèi)過多時間。
 https://stackoverflow.com/questions/30294146/python-fastest-way-to-process-large-file
2.補(bǔ)充缺失的代碼
def print_directory_contents(sPath): """ 這個函數(shù)接收文件夾的名稱作為輸入?yún)?shù) 返回該文件夾中文件的路徑 以及其包含文件夾中文件的路徑 """ import os for s_child in os.listdir(s_path):s_child_path = os.path.join(s_path, s_child)if os.path.isdir(s_child_path):print_directory_contents(s_child_path)else:print(s_child_path)模塊與包
3.輸入日期, 判斷這一天是這一年的第幾天?
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+14.打亂一個排好序的list對象alist?
import random alist = [1,2,3,4,5] random.shuffle(alist) print(alist)數(shù)據(jù)類型
5.現(xiàn)有字典 d= {‘a(chǎn)’:24,‘g’:52,‘i’:12,‘k’:33}請按value值進(jìn)行排序?
sorted(d.items(),key=lambda x:x[1])6.字典推導(dǎo)式
d = {key:value for (key,value) in iterable}7.請反轉(zhuǎn)字符串 “aStr”?
print("aStr"[::-1])8.將字符串 “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] = valuereturn dict1 #字典推導(dǎo)式 d = {k:int(v) for t in str1.split("|") for k, v in (t.split(":"), )}9.請按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)10.下面代碼的輸出結(jié)果將是什么?
list = ['a','b','c','d','e'] print(list[10:])代碼將輸出[],不會產(chǎn)生IndexError錯誤,就像所期望的那樣,嘗試用超出成員的個數(shù)的index來獲取某個列表的成員。例如,嘗試獲取list[10]和之后的成員,會導(dǎo)致IndexError。然而,嘗試獲取列表的切片,開始的index超過了成員個數(shù)不會產(chǎn)生IndexError,而是僅僅返回一個空列表。這成為特別讓人惡心的疑難雜癥,因?yàn)檫\(yùn)行的時候沒有錯誤產(chǎn)生,導(dǎo)致Bug很難被追蹤到。
11.寫一個列表生成式,產(chǎn)生一個公差為11的等差數(shù)列
print([x*11 for x in range(10)])12.給定兩個列表,怎么找出他們相同的元素和不同的元素?
list1 = [1,2,3] list2 = [3,4,5] set1 = set(list1) set2 = set(list2) print(set1 & set2) print(set1 ^ set2)13.請寫出一段python代碼實(shí)現(xiàn)刪除list里面的重復(fù)元素?
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)14.給定兩個list A,B ,請用找出A,B中相同與不同的元素
A,B 中相同元素: print(set(A)&set(B)) A,B 中不同元素: print(set(A)^set(B))企業(yè)面試題
15.python新式類和經(jīng)典類的區(qū)別?
a. 在python里凡是繼承了object的類,都是新式類
b. Python3里只有新式類
c. Python2里面繼承object的是新式類,沒有寫父類的是經(jīng)典類
d. 經(jīng)典類目前在Python里基本沒有應(yīng)用
16.python中內(nèi)置的數(shù)據(jù)結(jié)構(gòu)有幾種?
a. 整型 int、 長整型 long、浮點(diǎn)型 float、 復(fù)數(shù) complex
b. 字符串 str、 列表 list、 元祖 tuple
c. 字典 dict 、 集合 set
d. Python3 中沒有 long,只有無限精度的 int
17.python如何實(shí)現(xiàn)單例模式?請寫出兩種實(shí)現(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)建實(shí)例對象的方法,所以重寫基類的new 方法,以此保證創(chuàng)建對象的時候只生成一個實(shí)例
第三種方法:元類,元類是用于創(chuàng)建類對象的類,類對象創(chuàng)建實(shí)例對象時一定要調(diào)用call方法,因此在調(diào)用call時候保證始終只創(chuàng)建一個實(shí)例即可,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__ = Singletonfoo1 = Foo() foo2 = Foo() print foo1 is foo2 #True18.反轉(zhuǎn)一個整數(shù),例如-123 --> -321
class Solution(object):def reverse(self,x):if -10<x<10:return xstr_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 = -xreturn x if -2147483648<x<2147483647 else 0 if __name__ == '__main__':s = Solution()reverse_int = s.reverse(-120)print(reverse_int)19.設(shè)計(jì)實(shí)現(xiàn)遍歷目錄與子目錄,抓取.pyc文件
第一種方法:
import osdef get_files(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)get_files("./",'.pyc')第二種方法:
import osdef pick(obj):if ob.endswith(".pyc"):print(obj)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)第三種方法
from glob import iglobdef func(fp, postfix):for i in iglob(f"{fp}/**/*{postfix}", recursive=True):print(i)if __name__ == "__main__":postfix = ".pyc"func("K:\Python_script", postfix)20.一行代碼實(shí)現(xiàn)1-100之和
count = sum(range(0,101)) print(count)21.Python-遍歷列表時刪除元素的正確做法
遍歷在新在列表操作,刪除時在原來的列表操作
a = [1,2,3,4,5,6,7,8] print(id(a)) print(id(a[:])) for i in a[:]:if i>5:passelse:a.remove(i)print(a) print('-----------') print(id(a)) #filter a=[1,2,3,4,5,6,7,8] b = filter(lambda x: x>5,a) print(list(b))列表解析
a=[1,2,3,4,5,6,7,8] b = [i for i in a if i>5] print(b)倒序刪除
 因?yàn)榱斜砜偸恰蚯耙啤?#xff0c;所以可以倒序遍歷,即使后面的元素被修改了,還沒有被遍歷的元素和其坐標(biāo)還是保持不變的
22.字符串的操作題目
全字母短句 PANGRAM 是包含所有英文字母的句子,比如:A QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 定義并實(shí)現(xiàn)一個方法 get_missing_letter, 傳入一個字符串采納數(shù),返回參數(shù)字符串變成一個 PANGRAM 中所缺失的字符。應(yīng)該忽略傳入字符串參數(shù)中的大小寫,返回應(yīng)該都是小寫字符并按字母順序排序(請忽略所有非 ACSII 字符)
下面示例是用來解釋,雙引號不需要考慮:
(0)輸入: “A quick brown for jumps over the lazy dog”
返回: “”
(1)輸入: “A slow yellow fox crawls under the proactive dog”
返回: “bjkmqz”
(2)輸入: “Lions, and tigers, and bears, oh my!”
返回: “cfjkpquvwxz”
(3)輸入: “”
返回:“abcdefghijklmnopqrstuvwxyz”
def get_missing_letter(a):s1 = set("abcdefghijklmnopqrstuvwxyz")s2 = set(a)ret = "".join(sorted(s1-s2))return retprint(get_missing_letter("python"))23.可變類型和不可變類型
1,可變類型有l(wèi)ist,dict.不可變類型有string,number,tuple.
2,當(dāng)進(jìn)行修改操作時,可變類型傳遞的是內(nèi)存中的地址,也就是說,直接修改內(nèi)存中的值,并沒有開辟新的內(nèi)存。
3,不可變類型被改變時,并沒有改變原內(nèi)存地址中的值,而是開辟一塊新的內(nèi)存,將原地址中的值復(fù)制過去,對這塊新開辟的內(nèi)存中的值進(jìn)行操作。
24.is和==有什么區(qū)別?
is:比較的是兩個對象的id值是否相等,也就是比較倆對象是否為同一個實(shí)例對象。是否指向同一個內(nèi)存地址
== : 比較的兩個對象的內(nèi)容/值是否相等,默認(rèn)會調(diào)用對象的eq()方法
25.求出列表所有奇數(shù)并構(gòu)造新列表
a = [1,2,3,4,5,6,7,8,9,10] res = [ i for i in a if i%2==1] print(res)26.用一行python代碼寫出1+2+3+10248
from functools import reduce #1.使用sum內(nèi)置求和函數(shù) num = sum([1,2,3,10248]) print(num) #2.reduce 函數(shù) num1 = reduce(lambda x,y :x+y,[1,2,3,10248]) print(num1)27.Python中變量的作用域?(變量查找順序)
函數(shù)作用域的LEGB順序
1.什么是LEGB?
L: local 函數(shù)內(nèi)部作用域
E: enclosing 函數(shù)內(nèi)部與內(nèi)嵌函數(shù)之間
G: global 全局作用域
B: build-in 內(nèi)置作用
python在函數(shù)里面的查找分為4種,稱之為LEGB,也正是按照這是順序來查找的
28.字符串 "123" 轉(zhuǎn)換成 123,不使用內(nèi)置api,例如 int()
方法一: 利用 str 函數(shù)
def atoi(s):num = 0for v in s:for j in range(10):if v == str(j):num = num * 10 + jreturn num方法二: 利用 ord 函數(shù)
def atoi(s):num = 0for v in s:num = num * 10 + ord(v) - ord('0')return num方法三: 利用 eval 函數(shù)
def atoi(s):num = 0for v in s:t = "%s * 1" % vn = eval(t)num = num * 10 + nreturn num方法四: 結(jié)合方法二,使用 reduce,一行解決
from functools import reduce def atoi(s):return reduce(lambda num, v: num * 10 + ord(v) - ord('0'), s, 0)29.Given an array of integers
給定一個整數(shù)數(shù)組和一個目標(biāo)值,找出數(shù)組中和為目標(biāo)值的兩個數(shù)。你可以假設(shè)每個輸入只對應(yīng)一種答案,且同樣的元素不能被重復(fù)利用。示例:給定nums = [2,7,11,15],target=9 因?yàn)?nums[0]+nums[1] = 2+7 =9,所以返回[0,1]
class Solution:def twoSum(self,nums,target):""":type nums: List[int]:type target: int:rtype: List[int]"""d = {}size = 0while size < len(nums):if target-nums[size] in d:if d[target-nums[size]] <size:return [d[target-nums[size]],size]else:d[nums[size]] = sizesize = size +1 solution = Solution() list = [2,7,11,15] target = 9 nums = solution.twoSum(list,target) print(nums)給列表中的字典排序:假設(shè)有如下list對象,alist=[{“name”:“a”,“age”:20},{“name”:“b”,“age”:30},{“name”:“c”,“age”:25}],將alist中的元素按照age從大到小排序 alist=[{“name”:“a”,“age”:20},{“name”:“b”,“age”:30},{“name”:“c”,“age”:25}]
alist_sort = sorted(alist,key=lambda e: e.__getitem__('age'),reverse=True)30.python代碼實(shí)現(xiàn)刪除一個list里面的重復(fù)元素
def distFunc1(a):"""使用集合去重"""a = list(set(a))print(a)def distFunc2(a):"""將一個列表的數(shù)據(jù)取出放到另一個列表中,中間作判斷"""list = []for i in a:if i not in list:list.append(i)#如果需要排序的話用sortlist.sort()print(list)def distFunc3(a):"""使用字典"""b = {}b = b.fromkeys(a)c = list(b.keys())print(c)if __name__ == "__main__":a = [1,2,4,2,4,5,7,10,5,5,7,8,9,0,3]distFunc1(a)distFunc2(a)distFunc3(a)31.統(tǒng)計(jì)一個文本中單詞頻次最高的10個單詞?
import re# 方法一 def test(filepath):distone = {}with open(filepath) as f:for line in f:line = re.sub("\W+", " ", line)lineone = line.split()for keyone in lineone:if not distone.get(keyone):distone[keyone] = 1else:distone[keyone] += 1num_ten = sorted(distone.items(), key=lambda x:x[1], reverse=True)[:10]num_ten =[x[0] for x in num_ten]return num_ten# 方法二 # 使用 built-in 的 Counter 里面的 most_common import re from collections import Counterdef test2(filepath):with open(filepath) as f:return list(map(lambda c: c[0], Counter(re.sub("\W+", " ", f.read()).split()).most_common(10)))32.請寫出一個函數(shù)滿足以下條件
該函數(shù)的輸入是一個僅包含數(shù)字的list,輸出一個新的list,其中每一個元素要滿足以下條件:
1、該元素是偶數(shù)
2、該元素在原list中是在偶數(shù)的位置(index是偶數(shù))
def num_list(num):return [i for i in num if i %2 ==0 and num.index(i)%2==0]num = [0,1,2,3,4,5,6,7,8,9,10] result = num_list(num) print(result)33.使用單一的列表生成式來產(chǎn)生一個新的列表
該列表只包含滿足以下條件的值,元素為原始列表中偶數(shù)切片
list_data = [1,2,5,8,10,3,18,6,20] res = [x for x in list_data[::2] if x %2 ==0] print(res)34.用一行代碼生成[1,4,9,16,25,36,49,64,81,100]
[x * x for x in range(1,11)]35.輸入某年某月某日,判斷這一天是這一年的第幾天?
import datetimey = int(input("請輸入4位數(shù)字的年份:")) m = int(input("請輸入月份:")) d = int(input("請輸入是哪一天"))targetDay = datetime.date(y,m,d) dayCount = targetDay - datetime.date(targetDay.year -1,12,31) print("%s是 %s年的第%s天。"%(targetDay,y,dayCount.days))36.兩個有序列表,l1,l2,對這兩個列表進(jìn)行合并不可使用extend
def loop_merge_sort(l1,l2):tmp = []while len(l1)>0 and len(l2)>0:if l1[0] <l2[0]:tmp.append(l1[0])del l1[0]else:tmp.append(l2[0])del l2[0]37.給定一個任意長度數(shù)組,實(shí)現(xiàn)一個函數(shù)
讓所有奇數(shù)都在偶數(shù)前面,而且奇數(shù)升序排列,偶數(shù)降序排序,如字符串’1982376455’,變成’1355798642’
# 方法一 def func1(l):if isinstance(l, str):l = [int(i) for i in l]l.sort(reverse=True)for i in range(len(l)):if l[i] % 2 > 0:l.insert(0, l.pop(i))print(''.join(str(e) for e in l))# 方法二 def func2(l):print("".join(sorted(l, key=lambda x: int(x) % 2 == 0 and 20 - int(x) or int(x))))38.寫一個函數(shù)找出一個整數(shù)數(shù)組中,第二大的數(shù)
def find_second_large_num(num_list):"""找出數(shù)組第2大的數(shù)字"""# 方法一# 直接排序,輸出倒數(shù)第二個數(shù)即可tmp_list = sorted(num_list)print("方法一\nSecond_large_num is :", tmp_list[-2])# 方法二# 設(shè)置兩個標(biāo)志位一個存儲最大數(shù)一個存儲次大數(shù)# two 存儲次大值,one 存儲最大值,遍歷一次數(shù)組即可,先判斷是否大于 one,若大于將 one 的值給 two,將 num_list[i] 的值給 one,否則比較是否大于two,若大于直接將 num_list[i] 的值給two,否則passone = num_list[0]two = num_list[0]for i in range(1, len(num_list)):if num_list[i] > one:two = oneone = num_list[i]elif num_list[i] > two:two = num_list[i]print("方法二\nSecond_large_num is :", two)# 方法三# 用 reduce 與邏輯符號 (and, or)# 基本思路與方法二一樣,但是不需要用 if 進(jìn)行判斷。from functools import reducenum = reduce(lambda ot, x: ot[1] < x and (ot[1], x) or ot[0] < x and (x, ot[1]) or ot, num_list, (0, 0))[0]print("方法三\nSecond_large_num is :", num)if __name__ == '__main___':num_list = [34, 11, 23, 56, 78, 0, 9, 12, 3, 7, 5]find_second_large_num(num_list)39.閱讀一下代碼他們的輸出結(jié)果是什么?
def multi():return [lambda x : i*x for i in range(4)] print([m(3) for m in multi()])正確答案是[9,9,9,9],而不是[0,3,6,9]產(chǎn)生的原因是Python的閉包的后期綁定導(dǎo)致的,這意味著在閉包中的變量是在內(nèi)部函數(shù)被調(diào)用的時候被查找的,因?yàn)?#xff0c;最后函數(shù)被調(diào)用的時候,for循環(huán)已經(jīng)完成, i 的值最后是3,因此每一個返回值的i都是3,所以最后的結(jié)果是[9,9,9,9]
40.統(tǒng)計(jì)一段字符串中字符出現(xiàn)的次數(shù)
# 方法一 def count_str(str_data):"""定義一個字符出現(xiàn)次數(shù)的函數(shù)"""dict_str = {} for i in str_data:dict_str[i] = dict_str.get(i, 0) + 1return dict_str dict_str = count_str("AAABBCCAC") str_count_data = "" for k, v in dict_str.items():str_count_data += k + str(v) print(str_count_data)# 方法二 from collections import Counterprint("".join(map(lambda x: x[0] + str(x[1]), Counter("AAABBCCAC").most_common())))41.super函數(shù)的具體用法和場景
https://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p07_calling_method_on_parent_class.html
Python高級
元類
42.Python中類方法、類實(shí)例方法、靜態(tài)方法有何區(qū)別?
類方法: 是類對象的方法,在定義時需要在上方使用 @classmethod 進(jìn)行裝飾,形參為cls,表示類對象,類對象和實(shí)例對象都可調(diào)用
類實(shí)例方法: 是類實(shí)例化對象的方法,只有實(shí)例對象可以調(diào)用,形參為self,指代對象本身;
靜態(tài)方法: 是一個任意函數(shù),在其上方使用 @staticmethod 進(jìn)行裝飾,可以用對象直接調(diào)用,靜態(tài)方法實(shí)際上跟該類沒有太大關(guān)系
43.遍歷一個object的所有屬性,并print每一個屬性名?
class Car:def __init__(self,name,loss): # loss [價格,油耗,公里數(shù)]self.name = nameself.loss = lossdef getName(self):return self.namedef getPrice(self):# 獲取汽車價格return self.loss[0]def getLoss(self):# 獲取汽車損耗值return self.loss[1] * self.loss[2]Bmw = Car("寶馬",[60,9,500]) # 實(shí)例化一個寶馬車對象 print(getattr(Bmw,"name")) # 使用getattr()傳入對象名字,屬性值。 print(dir(Bmw)) # 獲Bmw所有的屬性和方法44.寫一個類,并讓它盡可能多的支持操作符?
class Array:__list = []def __init__(self):print "constructor"def __del__(self):print "destruct"def __str__(self):return "this self-defined array class"def __getitem__(self,key):return self.__list[key]def __len__(self):return len(self.__list)def Add(self,value):self.__list.append(value)def Remove(self,index):del self.__list[index]def DisplayItems(self):print "show all items---"for item in self.__list:print item45.介紹Cython,Pypy Cpython Numba各有什么缺點(diǎn)
Cython
46.請描述抽象類和接口類的區(qū)別和聯(lián)系
47.Python中如何動態(tài)獲取和設(shè)置對象的屬性?
內(nèi)存管理與垃圾回收機(jī)制
48.哪些操作會導(dǎo)致Python內(nèi)存溢出,怎么處理?
49.關(guān)于Python內(nèi)存管理,下列說法錯誤的是
50.Python的內(nèi)存管理機(jī)制及調(diào)優(yōu)手段?
51.內(nèi)存泄露是什么?如何避免?
函數(shù)
52.python常見的列表推導(dǎo)式?
53.簡述read、readline、readlines的區(qū)別?
54.什么是Hash(散列函數(shù))?
55.python函數(shù)重載機(jī)制?
56.寫一個函數(shù)找出一個整數(shù)數(shù)組中,第二大的數(shù)
57.手寫一個判斷時間的裝飾器
import datetimeclass TimeException(Exception):def __init__(self, exception_info):super().__init__()self.info = exception_infodef __str__(self):return self.infodef timecheck(func):def wrapper(*args, **kwargs):if datetime.datetime.now().year == 2019:func(*args, **kwargs)else:raise TimeException("函數(shù)已過時")return wrapper@timecheck def test(name):print("Hello {}, 2019 Happy".format(name))if __name__ == "__main__":test("backbp")58.使用Python內(nèi)置的filter()方法來過濾?
list(filter(lambda x: x % 2 == 0, range(10)))59.編寫函數(shù)的4個原則
60.函數(shù)調(diào)用參數(shù)的傳遞方式是值傳遞還是引用傳遞?
61.如何在function里面設(shè)置一個全局變量
62.對缺省參數(shù)的理解 ?
63.Mysql怎么限制IP訪問?
64.帶參數(shù)的裝飾器?
65.為什么函數(shù)名字可以當(dāng)做參數(shù)用?
66.Python中pass語句的作用是什么?
67.有這樣一段代碼,print c會輸出什么,為什么?
68.交換兩個變量的值?
69.map函數(shù)和reduce函數(shù)?
70.回調(diào)函數(shù),如何通信的?
71.Python主要的內(nèi)置數(shù)據(jù)類型都有哪些? print dir( ‘a(chǎn) ’) 的輸出?
72.map(lambda x:xx,[y for y in range(3)])的輸出?
73.hasattr() getattr() setattr() 函數(shù)使用詳解?
74.一句話解決階乘函數(shù)?
75.什么是lambda函數(shù)? 有什么好處?
76.遞歸函數(shù)停止的條件?
77.下面這段代碼的輸出結(jié)果將是什么?請解釋。
78.什么是lambda函數(shù)?它有什么好處?寫一個匿名函數(shù)求兩個數(shù)的和
設(shè)計(jì)模式
79.對設(shè)計(jì)模式的理解,簡述你了解的設(shè)計(jì)模式?
設(shè)計(jì)模式是經(jīng)過總結(jié),優(yōu)化的,對我們經(jīng)常會碰到的一些編程問題的可重用解決方案。一個設(shè)計(jì)模式并不像一個類或一個庫那樣能夠直接作用于我們的代碼,反之,設(shè)計(jì)模式更為高級,它是一種必須在特定情形下實(shí)現(xiàn)的一種方法模板。
 常見的是工廠模式和單例模式
80.請手寫一個單例
#python2 class A(object):__instance = Nonedef __new__(cls,*args,**kwargs):if cls.__instance is None:cls.__instance = objecet.__new__(cls)return cls.__instanceelse:return cls.__instance81.單例模式的應(yīng)用場景有那些?
單例模式應(yīng)用的場景一般發(fā)現(xiàn)在以下條件下:
 資源共享的情況下,避免由于資源操作時導(dǎo)致的性能或損耗等,如日志文件,應(yīng)用配置。
 控制資源的情況下,方便資源之間的互相通信。如線程池等,1,網(wǎng)站的計(jì)數(shù)器 2,應(yīng)用配置 3.多線程池 4數(shù)據(jù)庫配置 數(shù)據(jù)庫連接池 5.應(yīng)用程序的日志應(yīng)用…
82.用一行代碼生成[1,4,9,16,25,36,49,64,81,100]
print([x*x for x in range(1, 11)])83.對裝飾器的理解,并寫出一個計(jì)時器記錄方法執(zhí)行性能的裝飾器?
裝飾器本質(zhì)上是一個callable object ,它可以讓其他函數(shù)在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個函數(shù)對象。
import time from functools import wrapsdef timeit(func):@wraps(func)def wrapper(*args, **kwargs):start = time.clock()ret = func(*args, **kwargs)end = time.clock()print('used:',end-start)return retreturn wrapper @timeit def foo():print('in foo()'foo())84.解釋以下什么是閉包?
在函數(shù)內(nèi)部再定義一個函數(shù),并且這個函數(shù)用到了外邊函數(shù)的變量,那么將這個函數(shù)以及用到的一些變量稱之為閉包。
85.函數(shù)裝飾器有什么作用?
裝飾器本質(zhì)上是一個callable object,它可以在讓其他函數(shù)在不需要做任何代碼的變動的前提下增加額外的功能。裝飾器的返回值也是一個函數(shù)的對象,它經(jīng)常用于有切面需求的場景。比如:插入日志,性能測試,事務(wù)處理,緩存。權(quán)限的校驗(yàn)等場景,有了裝飾器就可以抽離出大量的與函數(shù)功能本身無關(guān)的雷同代碼并發(fā)并繼續(xù)使用。
 詳細(xì)參考:https://manjusaka.itscoder.com/2018/02/23/something-about-decorator/
86.生成器,迭代器的區(qū)別?
迭代器是遵循迭代協(xié)議的對象。用戶可以使用 iter() 以從任何序列得到迭代器(如 list, tuple, dictionary, set 等)。另一個方法則是創(chuàng)建一個另一種形式的迭代器 —— generator 。要獲取下一個元素,則使用成員函數(shù) next()(Python 2)或函數(shù) next() function (Python 3) 。當(dāng)沒有元素時,則引發(fā) StopIteration 此例外。若要實(shí)現(xiàn)自己的迭代器,則只要實(shí)現(xiàn) next()(Python 2)或 __next__()( Python 3)
生成器(Generator),只是在需要返回數(shù)據(jù)的時候使用yield語句。每次next()被調(diào)用時,生成器會返回它脫離的位置(它記憶語句最后一次執(zhí)行的位置和所有的數(shù)據(jù)值)
區(qū)別: 生成器能做到迭代器能做的所有事,而且因?yàn)樽詣觿?chuàng)建iter()和next()方法,生成器顯得特別簡潔,而且生成器也是高效的,使用生成器表達(dá)式取代列表解析可以同時節(jié)省內(nèi)存。除了創(chuàng)建和保存程序狀態(tài)的自動方法,當(dāng)發(fā)生器終結(jié)時,還會自動拋出StopIteration異常。
官方介紹:https://docs.python.org/3/tutorial/classes.html#iterators
87.X是什么類型?
X= (i for i in range(10)) X是 generator類型88.請用一行代碼 實(shí)現(xiàn)將1-N 的整數(shù)列表以3為單位分組
N =100 print ([[x for x in range(1,100)] [i:i+3] for i in range(0,100,3)])89.Python中yield的用法?
yield就是保存當(dāng)前程序執(zhí)行狀態(tài)。你用for循環(huán)的時候,每次取一個元素的時候就會計(jì)算一次。用yield的函數(shù)叫g(shù)enerator,和iterator一樣,它的好處是不用一次計(jì)算所有元素,而是用一次算一次,可以節(jié)省很多空間,generator每次計(jì)算需要上一次計(jì)算結(jié)果,所以用yield,否則一return,上次計(jì)算結(jié)果就沒了
面向?qū)ο?/h2> 
90.Python中的可變對象和不可變對象?
 
91.Python的魔法方法
 
92.面向?qū)ο笾性趺磳?shí)現(xiàn)只讀屬性?
 
用私有屬性+@property定義只讀屬性, 需要預(yù)先定義好屬性名, 然后實(shí)現(xiàn)對應(yīng)的getter方法.
class Vector2D(object):def __init__(self, x, y):self.__x = float(x)self.__y = float(y)@propertydef x(self):return self.__x@propertydef y(self):return self.__yif __name__ == "__main__":v = Vector2D(3, 4)print(v.x, v.y)v.x = 8 # error will be raised.輸出
(3.0, 4.0) Traceback (most recent call last):File ...., line 16, in <module>v.x = 8 # error will be raised. AttributeError: can't set attribute通過__setattr__
 當(dāng)我們調(diào)用obj.attr=value時發(fā)生了什么?
很簡單, 調(diào)用了obj的__setattr__方法. 可通過以下代碼驗(yàn)證:
class MyCls():def __init__(self):passdef __setattr__(self, f, v):print 'setting %r = %r'%(f, v) if __name__ == '__main__':obj = MyCls()obj.new_field = 1輸出
setting 'new_field' = 193.談?wù)勀銓γ嫦驅(qū)ο蟮睦斫?#xff1f;
正則表達(dá)式
94.請寫出一段代碼用正則匹配出ip?
95.a = “abbbccc”,用正則匹配為abccc,不管有多少b,就出現(xiàn)一次?
96.Python字符串查找和替換?
97.用Python匹配HTML g tag的時候,<.> 和 <.*?> 有什么區(qū)別
98.正則表達(dá)式貪婪與非貪婪模式的區(qū)別?
99.寫出開頭匹配字母和下劃線,末尾是數(shù)字的正則表達(dá)式?
100.正則表達(dá)式操作
101.請匹配出變量A 中的json字符串。
102.怎么過濾評論中的表情?
103.簡述Python里面search和match的區(qū)別
104.請寫出匹配ip的Python正則表達(dá)式
105.Python里match與search的區(qū)別?
系統(tǒng)編程
106.進(jìn)程總結(jié)
進(jìn)程:程序運(yùn)行在操作系統(tǒng)上的一個實(shí)例,就稱之為進(jìn)程。進(jìn)程需要相應(yīng)的系統(tǒng)資源:內(nèi)存、時間片、pid。
 創(chuàng)建進(jìn)程:
 首先要導(dǎo)入multiprocessing中的Process:
 創(chuàng)建一個Process對象;
 創(chuàng)建Process對象時,可以傳遞參數(shù);
使用start()啟動進(jìn)程
 結(jié)束進(jìn)程
 給子進(jìn)程指定函數(shù)傳遞參數(shù)Demo
注意:進(jìn)程間不共享全局變量
進(jìn)程之間的通信-Queue
在初始化Queue()對象時(例如q=Queue(),若在括號中沒有指定最大可接受的消息數(shù)量,獲數(shù)量為負(fù)值時,那么就代表可接受的消息數(shù)量沒有上限一直到內(nèi)存盡頭)
Queue.qsize():返回當(dāng)前隊(duì)列包含的消息數(shù)量
Queue.empty():如果隊(duì)列為空,返回True,反之False
Queue.full():如果隊(duì)列滿了,返回True,反之False
Queue.get([block[,timeout]]):獲取隊(duì)列中的一條消息,然后將其從隊(duì)列中移除,
block默認(rèn)值為True。
如果block使用默認(rèn)值,且沒有設(shè)置timeout(單位秒),消息隊(duì)列如果為空,此時程序?qū)⒈蛔枞?#xff08;停在讀中狀態(tài)),直到消息隊(duì)列讀到消息為止,如果設(shè)置了timeout,則會等待timeout秒,若還沒讀取到任何消息,則拋出“Queue.Empty"異常:
Queue.get_nowait()相當(dāng)于Queue.get(False)
Queue.put(item,[block[,timeout]]):將item消息寫入隊(duì)列,block默認(rèn)值為True;
 如果block使用默認(rèn)值,且沒有設(shè)置timeout(單位秒),消息隊(duì)列如果已經(jīng)沒有空間可寫入,此時程序?qū)⒈蛔枞?#xff08;停在寫入狀態(tài)),直到從消息隊(duì)列騰出空間為止,如果設(shè)置了timeout,則會等待timeout秒,若還沒空間,則拋出”Queue.Full"異常
 如果block值為False,消息隊(duì)列如果沒有空間可寫入,則會立刻拋出"Queue.Full"異常;
 Queue.put_nowait(item):相當(dāng)Queue.put(item,False)
進(jìn)程間通信Demo:
from multiprocessing import Process.Queue import os,time,random #寫數(shù)據(jù)進(jìn)程執(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ù)進(jìn)程執(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__':#父進(jìn)程創(chuàng)建Queue,并傳給各個子進(jìn)程q = Queue()pw = Process(target=write,args=(q,))pr = Process(target=read,args=(q,))#啟動子進(jìn)程pw ,寫入:pw.start()#等待pw結(jié)束pw.join()#啟動子進(jìn)程pr,讀取:pr.start()pr.join()#pr 進(jìn)程里是死循環(huán),無法等待其結(jié)束,只能強(qiáng)行終止:print('')print('所有數(shù)據(jù)都寫入并且讀完')進(jìn)程池Pool
#coding:utf-8 from multiprocessing import Pool import os,time,randomdef worker(msg):t_start = time.time()print("%s 開始執(zhí)行,進(jìn)程號為%d"%(msg,os.getpid()))# random.random()隨機(jī)生成0-1之間的浮點(diǎn)數(shù)time.sleep(random.random()*2)t_stop = time.time()print(msg,"執(zhí)行完畢,耗時%0.2f”%(t_stop-t_start))po = Pool(3)#定義一個進(jìn)程池,最大進(jìn)程數(shù)3 for i in range(0,10):po.apply_async(worker,(i,)) print("---start----") po.close() po.join() print("----end----")進(jìn)程池中使用Queue
如果要使用Pool創(chuàng)建進(jìn)程,就需要使用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),父進(jìn)程為(%s)"%(os.getpid(),os.getpid()))for i in range(q.qsize()):print("reader 從Queue獲取到消息:%s"%q.get(True))def writer(q):print("writer 啟動(%s),父進(jìn)程為(%s)"%(os.getpid(),os.getpid()))for i ini "itcast":q.put(i) if __name__ == "__main__":print("(%s)start"%os.getpid())q = Manager().Queue()#使用Manager中的Queuepo = Pool()po.apply_async(wrtier,(q,))time.sleep(1)po.apply_async(reader,(q,))po.close()po.join()print("(%s)End"%os.getpid())107.談?wù)勀銓Χ噙M(jìn)程,多線程,以及協(xié)程的理解,項(xiàng)目是否用?
這個問題被問的概念相當(dāng)之大,
 進(jìn)程:一個運(yùn)行的程序(代碼)就是一個進(jìn)程,沒有運(yùn)行的代碼叫程序,進(jìn)程是系統(tǒng)資源分配的最小單位,進(jìn)程擁有自己獨(dú)立的內(nèi)存空間,所有進(jìn)程間數(shù)據(jù)不共享,開銷大。
線程: cpu調(diào)度執(zhí)行的最小單位,也叫執(zhí)行路徑,不能獨(dú)立存在,依賴進(jìn)程存在,一個進(jìn)程至少有一個線程,叫主線程,而多個線程共享內(nèi)存(數(shù)據(jù)共享,共享全局變量),從而極大地提高了程序的運(yùn)行效率。
協(xié)程: 是一種用戶態(tài)的輕量級線程,協(xié)程的調(diào)度完全由用戶控制。協(xié)程擁有自己的寄存器上下文和棧。協(xié)程調(diào)度時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復(fù)先前保存的寄存器上下文和棧,直接操中棧則基本沒有內(nèi)核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切換非常快。
108.Python異常使用場景有那些?
異步的使用場景:
1、 不涉及共享資源,獲對共享資源只讀,即非互斥操作
2、 沒有時序上的嚴(yán)格關(guān)系
3、 不需要原子操作,或可以通過其他方式控制原子性
4、 常用于IO操作等耗時操作,因?yàn)楸容^影響客戶體驗(yàn)和使用性能
5、 不影響主線程邏輯
109.多線程共同操作同一個數(shù)據(jù)互斥鎖同步?
import threading import time class MyThread(threading.Thread):def run(self):global numtime.sleep(1)if mutex.acquire(1):num +=1msg = self.name + 'set num to ' +str(num)print msgmutex.release() num = 0 mutex = threading.Lock() def test():for i in range(5):t = MyThread()t.start() if __name__=="__main__":test()110.什么是多線程競爭?
線程是非獨(dú)立的,同一個進(jìn)程里線程是數(shù)據(jù)共享的,當(dāng)各個線程訪問數(shù)據(jù)資源時會出現(xiàn)競爭狀態(tài)即:數(shù)據(jù)幾乎同步會被多個線程占用,造成數(shù)據(jù)混亂,即所謂的線程不安全
那么怎么解決多線程競爭問題?—鎖
鎖的好處: 確保了某段關(guān)鍵代碼(共享數(shù)據(jù)資源)只能由一個線程從頭到尾完整地執(zhí)行能解決多線程資源競爭下的原子操作問題。
鎖的壞處: 阻止了多線程并發(fā)執(zhí)行,包含鎖的某段代碼實(shí)際上只能以單線程模式執(zhí)行,效率就大大地下降了
鎖的致命問題: 死鎖
111.請介紹一下Python的線程同步?
一、 setDaemon(False)
 當(dāng)一個進(jìn)程啟動之后,會默認(rèn)產(chǎn)生一個主線程,因?yàn)榫€程是程序執(zhí)行的最小單位,當(dāng)設(shè)置多線程時,主線程會創(chuàng)建多個子線程,在Python中,默認(rèn)情況下就是setDaemon(False),主線程執(zhí)行完自己的任務(wù)以后,就退出了,此時子線程會繼續(xù)執(zhí)行自己的任務(wù),直到自己的任務(wù)結(jié)束。
例子
import threading import timedef thread():time.sleep(2)print('---子線程結(jié)束---')def main():t1 = threading.Thread(target=thread)t1.start()print('---主線程--結(jié)束')if __name__ =='__main__':main() #執(zhí)行結(jié)果 ---主線程--結(jié)束 ---子線程結(jié)束---二、 setDaemon(True)
 當(dāng)我們使用setDaemon(True)時,這是子線程為守護(hù)線程,主線程一旦執(zhí)行結(jié)束,則全部子線程被強(qiáng)制終止
例子
import threading import time def thread():time.sleep(2)print(’---子線程結(jié)束---') def main():t1 = threading.Thread(target=thread)t1.setDaemon(True)#設(shè)置子線程守護(hù)主線程t1.start()print('---主線程結(jié)束---')if __name__ =='__main__':main() #執(zhí)行結(jié)果 ---主線程結(jié)束--- #只有主線程結(jié)束,子線程來不及執(zhí)行就被強(qiáng)制結(jié)束三、 join(線程同步)
 join 所完成的工作就是線程同步,即主線程任務(wù)結(jié)束以后,進(jìn)入堵塞狀態(tài),一直等待所有的子線程結(jié)束以后,主線程再終止。
當(dāng)設(shè)置守護(hù)線程時,含義是主線程對于子線程等待timeout的時間將會殺死該子線程,最后退出程序,所以說,如果有10個子線程,全部的等待時間就是每個timeout的累加和,簡單的來說,就是給每個子線程一個timeou的時間,讓他去執(zhí)行,時間一到,不管任務(wù)有沒有完成,直接殺死。
沒有設(shè)置守護(hù)線程時,主線程將會等待timeout的累加和這樣的一段時間,時間一到,主線程結(jié)束,但是并沒有殺死子線程,子線程依然可以繼續(xù)執(zhí)行,直到子線程全部結(jié)束,程序退出。
例子
import threading import timedef thread():time.sleep(2)print('---子線程結(jié)束---')def main():t1 = threading.Thread(target=thread)t1.setDaemon(True)t1.start()t1.join(timeout=1)#1 線程同步,主線程堵塞1s 然后主線程結(jié)束,子線程繼續(xù)執(zhí)行#2 如果不設(shè)置timeout參數(shù)就等子線程結(jié)束主線程再結(jié)束#3 如果設(shè)置了setDaemon=True和timeout=1主線程等待1s后會強(qiáng)制殺死子線程,然后主線程結(jié)束print('---主線程結(jié)束---')if __name__=='__main___':main()112.解釋以下什么是鎖,有哪幾種鎖?
鎖(Lock)是python提供的對線程控制的對象。有互斥鎖,可重入鎖,死鎖。
113.什么是死鎖?
若干子線程在系統(tǒng)資源競爭時,都在等待對方對某部分資源解除占用狀態(tài),結(jié)果是誰也不愿先解鎖,互相干等著,程序無法執(zhí)行下去,這就是死鎖。
GIL鎖 全局解釋器鎖(只在cython里才有)
作用: 限制多線程同時執(zhí)行,保證同一時間只有一個線程執(zhí)行,所以cython里的多線程其實(shí)是偽多線程!
所以python里常常使用協(xié)程技術(shù)來代替多線程,協(xié)程是一種更輕量級的線程。
進(jìn)程和線程的切換時由系統(tǒng)決定,而協(xié)程由我們程序員自己決定,而模塊gevent下切換是遇到了耗時操作時才會切換
三者的關(guān)系:進(jìn)程里有線程,線程里有協(xié)程。
114.多線程交互訪問數(shù)據(jù),如果訪問到了就不訪問了?
怎么避免重讀?
創(chuàng)建一個已訪問數(shù)據(jù)列表,用于存儲已經(jīng)訪問過的數(shù)據(jù),并加上互斥鎖,在多線程訪問數(shù)據(jù)的時候先查看數(shù)據(jù)是否在已訪問的列表中,若已存在就直接跳過。
115.什么是線程安全,什么是互斥鎖?
每個對象都對應(yīng)于一個可稱為’互斥鎖‘的標(biāo)記,這個標(biāo)記用來保證在任一時刻,只能有一個線程訪問該對象。
同一進(jìn)程中的多線程之間是共享系統(tǒng)資源的,多個線程同時對一個對象進(jìn)行操作,一個線程操作尚未結(jié)束,另一線程已經(jīng)對其進(jìn)行操作,導(dǎo)致最終結(jié)果出現(xiàn)錯誤,此時需要對被操作對象添加互斥鎖,保證每個線程對該對象的操作都得到正確的結(jié)果。
116.說說下面幾個概念:同步,異步,阻塞,非阻塞?
同步: 多個任務(wù)之間有先后順序執(zhí)行,一個執(zhí)行完下個才能執(zhí)行。
異步: 多個任務(wù)之間沒有先后順序,可以同時執(zhí)行,有時候一個任務(wù)可能要在必要的時候獲取另一個同時執(zhí)行的任務(wù)的結(jié)果,這個就叫回調(diào)!
阻塞: 如果卡住了調(diào)用者,調(diào)用者不能繼續(xù)往下執(zhí)行,就是說調(diào)用者阻塞了。
非阻塞: 如果不會卡住,可以繼續(xù)執(zhí)行,就是說非阻塞的。
同步異步相對于多任務(wù)而言,阻塞非阻塞相對于代碼執(zhí)行而言。
117.什么是僵尸進(jìn)程和孤兒進(jìn)程?怎么避免僵尸進(jìn)程?
孤兒進(jìn)程: 父進(jìn)程退出,子進(jìn)程還在運(yùn)行的這些子進(jìn)程都是孤兒進(jìn)程,孤兒進(jìn)程將被init 進(jìn)程(進(jìn)程號為1)所收養(yǎng),并由init 進(jìn)程對他們完成狀態(tài)收集工作。
僵尸進(jìn)程: 進(jìn)程使用fork 創(chuàng)建子進(jìn)程,如果子進(jìn)程退出,而父進(jìn)程并沒有調(diào)用wait 獲waitpid 獲取子進(jìn)程的狀態(tài)信息,那么子進(jìn)程的進(jìn)程描述符仍然保存在系統(tǒng)中的這些進(jìn)程是僵尸進(jìn)程。
避免僵尸進(jìn)程的方法:
1.fork 兩次用孫子進(jìn)程去完成子進(jìn)程的任務(wù)
2.用wait()函數(shù)使父進(jìn)程阻塞
3.使用信號量,在signal handler 中調(diào)用waitpid,這樣父進(jìn)程不用阻塞
118.python中進(jìn)程與線程的使用場景?
多進(jìn)程適合在CPU密集操作(cpu操作指令比較多,如位多的的浮點(diǎn)運(yùn)算)。
多線程適合在IO密性型操作(讀寫數(shù)據(jù)操作比多的的,比如爬蟲)
119.線程是并發(fā)還是并行,進(jìn)程是并發(fā)還是并行?
線程是并發(fā),進(jìn)程是并行;
進(jìn)程之間互相獨(dú)立,是系統(tǒng)分配資源的最小單位,同一個線程中的所有線程共享資源。
120.并行(parallel)和并發(fā)(concurrency)?
并行: 同一時刻多個任務(wù)同時在運(yùn)行
不會在同一時刻同時運(yùn)行,存在交替執(zhí)行的情況。
實(shí)現(xiàn)并行的庫有: multiprocessing
實(shí)現(xiàn)并發(fā)的庫有: threading
程序需要執(zhí)行較多的讀寫、請求和回復(fù)任務(wù)的需要大量的IO操作,IO密集型操作使用并發(fā)更好。
CPU運(yùn)算量大的程序,使用并行會更好
121.IO密集型和CPU密集型區(qū)別?
IO密集型: 系統(tǒng)運(yùn)行,大部分的狀況是CPU在等 I/O(硬盤/內(nèi)存)的讀/寫
CPU密集型: 大部分時間用來做計(jì)算,邏輯判斷等CPU動作的程序稱之CPU密集型。
122.python asyncio的原理?
asyncio這個庫就是使用python的yield這個可以打斷保存當(dāng)前函數(shù)的上下文的機(jī)制, 封裝好了selector 擺脫掉了復(fù)雜的回調(diào)關(guān)系
網(wǎng)絡(luò)編程
123.怎么實(shí)現(xiàn)強(qiáng)行關(guān)閉客戶端和服務(wù)器之間的連接?
124.簡述TCP和UDP的區(qū)別以及優(yōu)缺點(diǎn)?
125.簡述瀏覽器通過WSGI請求動態(tài)資源的過程?
1發(fā)送 http 請求動態(tài)資源給 web 服務(wù)器
 2web 服務(wù)器收到請求后通過 WSGI 調(diào)用一個屬性給應(yīng)用程序框架
 3應(yīng)用程序框架通過引用 WSGI 調(diào)用 web 服務(wù)器的方法,設(shè)置返回的狀態(tài)和頭信息。
 4調(diào)用后返回,此時 web 服務(wù)器保存了剛剛設(shè)置的信息
 5應(yīng)用程序框架查詢數(shù)據(jù)庫,生成動態(tài)頁面的 body 的信息
 6把生成的 body 信息返回給 web 服務(wù)器
 7web 服務(wù)器吧數(shù)據(jù)返回給瀏覽器
126.描述用瀏覽器訪問www.baidu.com的過程
127.Post和Get請求的區(qū)別?
128.cookie 和session 的區(qū)別?
129.列出你知道的HTTP協(xié)議的狀態(tài)碼,說出表示什么意思?
130.請簡單說一下三次握手和四次揮手?
131.說一下什么是tcp的2MSL?
132.為什么客戶端在TIME-WAIT狀態(tài)必須等待2MSL的時間?
133.說說HTTP和HTTPS區(qū)別?
134.談一下HTTP協(xié)議以及協(xié)議頭部中表示數(shù)據(jù)類型的字段?
135.HTTP請求方法都有什么?
136.使用Socket套接字需要傳入哪些參數(shù) ?
137.HTTP常見請求頭?
138.七層模型?
139.url的形式?
Web
Flask
140.對Flask藍(lán)圖(Blueprint)的理解?
藍(lán)圖的定義
藍(lán)圖 /Blueprint 是Flask應(yīng)用程序組件化的方法,可以在一個應(yīng)用內(nèi)或跨越多個項(xiàng)目共用藍(lán)圖。使用藍(lán)圖可以極大簡化大型應(yīng)用的開發(fā)難度,也為Flask擴(kuò)展提供了一種在應(yīng)用中注冊服務(wù)的集中式機(jī)制。
藍(lán)圖的應(yīng)用場景:
把一個應(yīng)用分解為一個藍(lán)圖的集合。這對大型應(yīng)用是理想的。一個項(xiàng)目可以實(shí)例化一個應(yīng)用對象,初始化幾個擴(kuò)展,并注冊一集合的藍(lán)圖。
以URL前綴和/或子域名,在應(yīng)用上注冊一個藍(lán)圖。URL前綴/子域名中的參數(shù)即成為這個藍(lán)圖下的所有視圖函數(shù)的共同的視圖參數(shù)(默認(rèn)情況下)
 在一個應(yīng)用中用不同的URL規(guī)則多次注冊一個藍(lán)圖。
通過藍(lán)圖提供模板過濾器、靜態(tài)文件、模板和其他功能。一個藍(lán)圖不一定要實(shí)現(xiàn)應(yīng)用或視圖函數(shù)。
初始化一個Flask擴(kuò)展時,在這些情況中注冊一個藍(lán)圖。
藍(lán)圖的缺點(diǎn):
不能在應(yīng)用創(chuàng)建后撤銷注冊一個藍(lán)圖而不銷毀整個應(yīng)用對象。
使用藍(lán)圖的三個步驟
1.創(chuàng)建一個藍(lán)圖對象
blue = Blueprint("blue",__name__)2.在這個藍(lán)圖對象上進(jìn)行操作,例如注冊路由、指定靜態(tài)文件夾、注冊模板過濾器…
@blue.route('/') def blue_index():return "Welcome to my blueprint"3.在應(yīng)用對象上注冊這個藍(lán)圖對象
app.register_blueprint(blue,url_prefix="/blue")141.Flask 和 Django 路由映射的區(qū)別?
在django中,路由是瀏覽器訪問服務(wù)器時,先訪問的項(xiàng)目中的url,再由項(xiàng)目中的url找到應(yīng)用中url,這些url是放在一個列表里,遵從從前往后匹配的規(guī)則。在flask中,路由是通過裝飾器給每個視圖函數(shù)提供的,而且根據(jù)請求方式的不同可以一個url用于不同的作用。
Django
142.什么是wsgi,uwsgi,uWSGI?
WSGI:
web服務(wù)器網(wǎng)關(guān)接口,是一套協(xié)議。用于接收用戶請求并將請求進(jìn)行初次封裝,然后將請求交給web框架。
實(shí)現(xiàn)wsgi協(xié)議的模塊:wsgiref,本質(zhì)上就是編寫一socket服務(wù)端,用于接收用戶請求(django)
werkzeug,本質(zhì)上就是編寫一個socket服務(wù)端,用于接收用戶請求(flask)
uwsgi:
與WSGI一樣是一種通信協(xié)議,它是uWSGI服務(wù)器的獨(dú)占協(xié)議,用于定義傳輸信息的類型。
 uWSGI:
是一個web服務(wù)器,實(shí)現(xiàn)了WSGI的協(xié)議,uWSGI協(xié)議,http協(xié)議
143.Django、Flask、Tornado的對比?
1、 Django走的大而全的方向,開發(fā)效率高。它的MTV框架,自帶的ORM,admin后臺管理,自帶的sqlite數(shù)據(jù)庫和開發(fā)測試用的服務(wù)器,給開發(fā)者提高了超高的開發(fā)效率。
 重量級web框架,功能齊全,提供一站式解決的思路,能讓開發(fā)者不用在選擇上花費(fèi)大量時間。
自帶ORM和模板引擎,支持jinja等非官方模板引擎。
自帶ORM使Django和關(guān)系型數(shù)據(jù)庫耦合度高,如果要使用非關(guān)系型數(shù)據(jù)庫,需要使用第三方庫
自帶數(shù)據(jù)庫管理app
成熟,穩(wěn)定,開發(fā)效率高,相對于Flask,Django的整體封閉性比較好,適合做企業(yè)級網(wǎng)站的開發(fā)。python web框架的先驅(qū),第三方庫豐富
2、 Flask 是輕量級的框架,自由,靈活,可擴(kuò)展性強(qiáng),核心基于Werkzeug WSGI工具 和jinja2 模板引擎
適用于做小網(wǎng)站以及web服務(wù)的API,開發(fā)大型網(wǎng)站無壓力,但架構(gòu)需要自己設(shè)計(jì)
與關(guān)系型數(shù)據(jù)庫的結(jié)合不弱于Django,而與非關(guān)系型數(shù)據(jù)庫的結(jié)合遠(yuǎn)遠(yuǎn)優(yōu)于Django
3、 Tornado走的是少而精的方向,性能優(yōu)越,它最出名的異步非阻塞的設(shè)計(jì)方式
Tornado的兩大核心模塊:
iostraem:對非阻塞的socket進(jìn)行簡單的封裝
ioloop: 對I/O 多路復(fù)用的封裝,它實(shí)現(xiàn)一個單例
144.CORS 和 CSRF的區(qū)別?
什么是CORS?
CORS是一個W3C標(biāo)準(zhǔn),全稱是“跨域資源共享"(Cross-origin resoure sharing).
 它允許瀏覽器向跨源服務(wù)器,發(fā)出XMLHttpRequest請求,從而客服了AJAX只能同源使用的限制。
什么是CSRF?
CSRF主流防御方式是在后端生成表單的時候生成一串隨機(jī)token,內(nèi)置到表單里成為一個字段,同時,將此串token置入session中。每次表單提交到后端時都會檢查這兩個值是否一致,以此來判斷此次表單提交是否是可信的,提交過一次之后,如果這個頁面沒有生成CSRF token,那么token將會被清空,如果有新的需求,那么token會被更新。
 攻擊者可以偽造POST表單提交,但是他沒有后端生成的內(nèi)置于表單的token,session中沒有token都無濟(jì)于事。
145.Session,Cookie,JWT的理解
為什么要使用會話管理
眾所周知,HTTP協(xié)議是一個無狀態(tài)的協(xié)議,也就是說每個請求都是一個獨(dú)立的請求,請求與請求之間并無關(guān)系。但在實(shí)際的應(yīng)用場景,這種方式并不能滿足我們的需求。舉個大家都喜歡用的例子,把商品加入購物車,單獨(dú)考慮這個請求,服務(wù)端并不知道這個商品是誰的,應(yīng)該加入誰的購物車?因此這個請求的上下文環(huán)境實(shí)際上應(yīng)該包含用戶的相關(guān)信息,在每次用戶發(fā)出請求時把這一小部分額外信息,也做為請求的一部分,這樣服務(wù)端就可以根據(jù)上下文中的信息,針對具體的用戶進(jìn)行操作。所以這幾種技術(shù)的出現(xiàn)都是對HTTP協(xié)議的一個補(bǔ)充,使得我們可以用HTTP協(xié)議+狀態(tài)管理構(gòu)建一個的面向用戶的WEB應(yīng)用。
Session 和Cookie的區(qū)別
這里我想先談?wù)剆ession與cookies,因?yàn)檫@兩個技術(shù)是做為開發(fā)最為常見的。那么session與cookies的區(qū)別是什么?個人認(rèn)為session與cookies最核心區(qū)別在于額外信息由誰來維護(hù)。利用cookies來實(shí)現(xiàn)會話管理時,用戶的相關(guān)信息或者其他我們想要保持在每個請求中的信息,都是放在cookies中,而cookies是由客戶端來保存,每當(dāng)客戶端發(fā)出新請求時,就會稍帶上cookies,服務(wù)端會根據(jù)其中的信息進(jìn)行操作。
 當(dāng)利用session來進(jìn)行會話管理時,客戶端實(shí)際上只存了一個由服務(wù)端發(fā)送的session_id,而由這個session_id,可以在服務(wù)端還原出所需要的所有狀態(tài)信息,從這里可以看出這部分信息是由服務(wù)端來維護(hù)的。
除此以外,session與cookies都有一些自己的缺點(diǎn):
cookies的安全性不好,攻擊者可以通過獲取本地cookies進(jìn)行欺騙或者利用cookies進(jìn)行CSRF攻擊。使用cookies時,在多個域名下,會存在跨域問題。
 session 在一定的時間里,需要存放在服務(wù)端,因此當(dāng)擁有大量用戶時,也會大幅度降低服務(wù)端的性能,當(dāng)有多臺機(jī)器時,如何共享session也會是一個問題.(redis集群)也就是說,用戶第一個訪問的時候是服務(wù)器A,而第二個請求被轉(zhuǎn)發(fā)給了服務(wù)器B,那服務(wù)器B如何得知其狀態(tài)。實(shí)際上,session與cookies是有聯(lián)系的,比如我們可以把session_id存放在cookies中的。
JWT是如何工作的
首先用戶發(fā)出登錄請求,服務(wù)端根據(jù)用戶的登錄請求進(jìn)行匹配,如果匹配成功,將相關(guān)的信息放入payload中,利用算法,加上服務(wù)端的密鑰生成token,這里需要注意的是secret_key很重要,如果這個泄露的話,客戶端就可以隨機(jī)篡改發(fā)送的額外信息,它是信息完整性的保證。生成token后服務(wù)端將其返回給客戶端,客戶端可以在下次請求時,將token一起交給服務(wù)端,一般是說我們可以將其放在Authorization首部中,這樣也就可以避免跨域問題。
146.簡述Django請求生命周期
一般是用戶通過瀏覽器向我們的服務(wù)器發(fā)起一個請求(request),這個請求會去訪問視圖函數(shù),如果不涉及到數(shù)據(jù)調(diào)用,那么這個時候視圖函數(shù)返回一個模板也就是一個網(wǎng)頁給用戶)
 視圖函數(shù)調(diào)用模型毛模型去數(shù)據(jù)庫查找數(shù)據(jù),然后逐級返回,視圖函數(shù)把返回的數(shù)據(jù)填充到模板中空格中,最后返回網(wǎng)頁給用戶。
1.wsgi ,請求封裝后交給web框架(Flask,Django)
2.中間件,對請求進(jìn)行校驗(yàn)或在請求對象中添加其他相關(guān)數(shù)據(jù),例如:csrf,request.session
3.路由匹配 根據(jù)瀏覽器發(fā)送的不同url去匹配不同的視圖函數(shù)
4.視圖函數(shù),在視圖函數(shù)中進(jìn)行業(yè)務(wù)邏輯的處理,可能涉及到:orm,templates
5.中間件,對響應(yīng)的數(shù)據(jù)進(jìn)行處理
6.wsgi,將響應(yīng)的內(nèi)容發(fā)送給瀏覽器
147.用的restframework完成api發(fā)送時間時區(qū)
當(dāng)前的問題是用django的rest framework模塊做一個get請求的發(fā)送時間以及時區(qū)信息的api
class getCurrenttime(APIView):def get(self,request):local_time = time.localtime()time_zone =settings.TIME_ZONEtemp = {'localtime':local_time,'timezone':time_zone}return Response(temp)148.nginx,tomcat,apach到都是什么?
Nginx(engine x)是一個高性能的HTTP和反向代理服務(wù)器,也是 一個IMAP/POP3/SMTP服務(wù)器,工作在OSI七層,負(fù)載的實(shí)現(xiàn)方式:輪詢,IP_HASH,fair,session_sticky.
 Apache HTTP Server是一個模塊化的服務(wù)器,源于NCSAhttpd服務(wù)器
 Tomcat 服務(wù)器是一個免費(fèi)的開放源代碼的Web應(yīng)用服務(wù)器,屬于輕量級應(yīng)用服務(wù)器,是開發(fā)和調(diào)試JSP程序的首選。
149.請給出你熟悉關(guān)系數(shù)據(jù)庫范式有哪些,有什么作用?
在進(jìn)行數(shù)據(jù)庫的設(shè)計(jì)時,所遵循的一些規(guī)范,只要按照設(shè)計(jì)規(guī)范進(jìn)行設(shè)計(jì),就能設(shè)計(jì)出沒有數(shù)據(jù)冗余和數(shù)據(jù)維護(hù)異常的數(shù)據(jù)庫結(jié)構(gòu)。
數(shù)據(jù)庫的設(shè)計(jì)的規(guī)范有很多,通常來說我們在設(shè)是數(shù)據(jù)庫時只要達(dá)到其中一些規(guī)范就可以了,這些規(guī)范又稱之為數(shù)據(jù)庫的三范式,一共有三條,也存在著其他范式,我們只要做到滿足前三個范式的要求,就能設(shè)陳出符合我們的數(shù)據(jù)庫了,我們也不能全部來按照范式的要求來做,還要考慮實(shí)際的業(yè)務(wù)使用情況,所以有時候也需要做一些違反范式的要求。
 1.數(shù)據(jù)庫設(shè)計(jì)的第一范式(最基本),基本上所有數(shù)據(jù)庫的范式都是符合第一范式的,符合第一范式的表具有以下幾個特點(diǎn):
數(shù)據(jù)庫表中的所有字段都只具有單一屬性,單一屬性的列是由基本的數(shù)據(jù)類型(整型,浮點(diǎn)型,字符型等)所構(gòu)成的設(shè)計(jì)出來的表都是簡單的二比表
2.數(shù)據(jù)庫設(shè)計(jì)的第二范式(是在第一范式的基礎(chǔ)上設(shè)計(jì)的),要求一個表中只具有一個業(yè)務(wù)主鍵,也就是說符合第二范式的表中不能存在非主鍵列對只對部分主鍵的依賴關(guān)系
3.數(shù)據(jù)庫設(shè)計(jì)的第三范式,指每一個非主屬性既不部分依賴與也不傳遞依賴于業(yè)務(wù)主鍵,也就是第二范式的基礎(chǔ)上消除了非主屬性對主鍵的傳遞依賴
150.簡述QQ登陸過程
qq登錄,在我們的項(xiàng)目中分為了三個接口,
第一個接口是請求qq服務(wù)器返回一個qq登錄的界面;
第二個接口是通過掃碼或賬號登陸進(jìn)行驗(yàn)證,qq服務(wù)器返回給瀏覽器一個code和state,利用這個code通過本地服務(wù)器去向qq服務(wù)器獲取access_token覆返回給本地服務(wù)器,憑借access_token再向qq服務(wù)器獲取用戶的openid(openid用戶的唯一標(biāo)識)
第三個接口是判斷用戶是否是第一次qq登錄,如果不是的話直接登錄返回的jwt-token給用戶,對沒有綁定過本網(wǎng)站的用戶,對openid進(jìn)行加密生成token進(jìn)行綁定
151.post 和 get的區(qū)別?
1.GET是從服務(wù)器上獲取數(shù)據(jù),POST是向服務(wù)器傳送數(shù)據(jù)
2.在客戶端,GET方式在通過URL提交數(shù)據(jù),數(shù)據(jù)在URL中可以看到,POST方式,數(shù)據(jù)放置在HTML——HEADER內(nèi)提交
3.對于GET方式,服務(wù)器端用Request.QueryString獲取變量的值,對于POST方式,服務(wù)器端用Request.Form獲取提交的數(shù)據(jù)
152.項(xiàng)目中日志的作用
一、日志相關(guān)概念
1.日志是一種可以追蹤某些軟件運(yùn)行時所發(fā)生事件的方法
2.軟件開發(fā)人員可以向他們的代碼中調(diào)用日志記錄相關(guān)的方法來表明發(fā)生了某些事情
3.一個事件可以用一個包含可選變量數(shù)據(jù)的消息來描述
4.此外,事件也有重要性的概念,這個重要性也可以被成為嚴(yán)重性級別(level)
二、日志的作用
1.通過log的分析,可以方便用戶了解系統(tǒng)或軟件、應(yīng)用的運(yùn)行情況;
2.如果你的應(yīng)用log足夠豐富,可以分析以往用戶的操作行為、類型喜好,地域分布或其他更多信息;
3.如果一個應(yīng)用的log同時也分了多個級別,那么可以很輕易地分析得到該應(yīng)用的健康狀況,及時發(fā)現(xiàn)問題并快速定位、解決問題,補(bǔ)救損失。
4.簡單來講就是我們通過記錄和分析日志可以了解一個系統(tǒng)或軟件程序運(yùn)行情況是否正常,也可以在應(yīng)用程序出現(xiàn)故障時快速定位問題。不僅在開發(fā)中,在運(yùn)維中日志也很重要,日志的作用也可以簡單。總結(jié)為以下幾點(diǎn):
1.程序調(diào)試
2.了解軟件程序運(yùn)行情況,是否正常
3,軟件程序運(yùn)行故障分析與問題定位
4,如果應(yīng)用的日志信息足夠詳細(xì)和豐富,還可以用來做用戶行為分析
153.django中間件的使用?
Django在中間件中預(yù)置了六個方法,這六個方法的區(qū)別在于不同的階段執(zhí)行,對輸入或輸出進(jìn)行干預(yù),方法如下:
1.初始化:無需任何參數(shù),服務(wù)器響應(yīng)第一個請求的時候調(diào)用一次,用于確定是否啟用當(dāng)前中間件
def __init__():pass2.處理請求前:在每個請求上調(diào)用,返回None或HttpResponse對象。
def process_request(request):pass3.處理視圖前:在每個請求上調(diào)用,返回None或HttpResponse對象。
def process_view(request,view_func,view_args,view_kwargs):pass4.處理模板響應(yīng)前:在每個請求上調(diào)用,返回實(shí)現(xiàn)了render方法的響應(yīng)對象。
def process_template_response(request,response):pass5.處理響應(yīng)后:所有響應(yīng)返回瀏覽器之前被調(diào)用,在每個請求上調(diào)用,返回HttpResponse對象。
def process_response(request,response):pass6.異常處理:當(dāng)視圖拋出異常時調(diào)用,在每個請求上調(diào)用,返回一個HttpResponse對象。
def process_exception(request,exception):pass154.談一下你對uWSGI和nginx的理解?
1.uWSGI是一個Web服務(wù)器,它實(shí)現(xiàn)了WSGI協(xié)議、uwsgi、http等協(xié)議。Nginx中HttpUwsgiModule的作用是與uWSGI服務(wù)器進(jìn)行交換。WSGI是一種Web服務(wù)器網(wǎng)關(guān)接口。它是一個Web服務(wù)器(如nginx,uWSGI等服務(wù)器)與web應(yīng)用(如用Flask框架寫的程序)通信的一種規(guī)范。
要注意WSGI/uwsgi/uWSGI這三個概念的區(qū)分。
WSGI是一種通信協(xié)議。
uwsgi是一種線路協(xié)議而不是通信協(xié)議,在此常用于在uWSGI服務(wù)器與其他網(wǎng)絡(luò)服務(wù)器的數(shù)據(jù)通信。
uWSGI是實(shí)現(xiàn)了uwsgi和WSGI兩種協(xié)議的Web服務(wù)器。
nginx 是一個開源的高性能的HTTP服務(wù)器和反向代理:
1.作為web服務(wù)器,它處理靜態(tài)文件和索引文件效果非常高
2.它的設(shè)計(jì)非常注重效率,最大支持5萬個并發(fā)連接,但只占用很少的內(nèi)存空間
3.穩(wěn)定性高,配置簡潔。
4.強(qiáng)大的反向代理和負(fù)載均衡功能,平衡集群中各個服務(wù)器的負(fù)載壓力應(yīng)用
155.Python中三大框架各自的應(yīng)用場景?
django:主要是用來搞快速開發(fā)的,他的亮點(diǎn)就是快速開發(fā),節(jié)約成本,,如果要實(shí)現(xiàn)高并發(fā)的話,就要對django進(jìn)行二次開發(fā),比如把整個笨重的框架給拆掉自己寫socket實(shí)現(xiàn)http的通信,底層用純c,c++寫提升效率,ORM框架給干掉,自己編寫封裝與數(shù)據(jù)庫交互的框架,ORM雖然面向?qū)ο髞聿僮鲾?shù)據(jù)庫,但是它的效率很低,使用外鍵來聯(lián)系表與表之間的查詢;
 flask: 輕量級,主要是用來寫接口的一個框架,實(shí)現(xiàn)前后端分離,提考開發(fā)效率,Flask本身相當(dāng)于一個內(nèi)核,其他幾乎所有的功能都要用到擴(kuò)展(郵件擴(kuò)展Flask-Mail,用戶認(rèn)證Flask-Login),都需要用第三方的擴(kuò)展來實(shí)現(xiàn)。比如可以用Flask-extension加入ORM、文件上傳、身份驗(yàn)證等。Flask沒有默認(rèn)使用的數(shù)據(jù)庫,你可以選擇MySQL,也可以用NoSQL。
其WSGI工具箱用Werkzeug(路由模塊),模板引擎則使用Jinja2,這兩個也是Flask框架的核心。
Tornado: Tornado是一種Web服務(wù)器軟件的開源版本。Tornado和現(xiàn)在的主流Web服務(wù)器框架(包括大多數(shù)Python的框架)有著明顯的區(qū)別:它是非阻塞式服務(wù)器,而且速度相當(dāng)快。得利于其非阻塞的方式和對epoll的運(yùn)用,Tornado每秒可以處理數(shù)以千計(jì)的連接因此Tornado是實(shí)時Web服務(wù)的一個理想框架
156.Django中哪里用到了線程?哪里用到了協(xié)程?哪里用到了進(jìn)程?
1.Django中耗時的任務(wù)用一個進(jìn)程或者線程來執(zhí)行,比如發(fā)郵件,使用celery.
2.部署django項(xiàng)目是時候,配置文件中設(shè)置了進(jìn)程和協(xié)程的相關(guān)配置。
157.有用過Django REST framework嗎?
Django REST framework是一個強(qiáng)大而靈活的Web API工具。使用RESTframework的理由有:
Web browsable API對開發(fā)者有極大的好處
包括OAuth1a和OAuth2的認(rèn)證策略
支持ORM和非ORM數(shù)據(jù)資源的序列化
全程自定義開發(fā)–如果不想使用更加強(qiáng)大的功能,可僅僅使用常規(guī)的function-based views額外的文檔和強(qiáng)大的社區(qū)支持
158.對cookies與session的了解?他們能單獨(dú)用嗎?
Session采用的是在服務(wù)器端保持狀態(tài)的方案,而Cookie采用的是在客戶端保持狀態(tài)的方案。但是禁用Cookie就不能得到Session。因?yàn)镾ession是用Session ID來確定當(dāng)前對話所對應(yīng)的服務(wù)器Session,而Session ID是通過Cookie來傳遞的,禁用Cookie相當(dāng)于SessionID,也就得不到Session。
爬蟲
159.試列出至少三種目前流行的大型數(shù)據(jù)庫
160.列舉您使用過的Python網(wǎng)絡(luò)爬蟲所用到的網(wǎng)絡(luò)數(shù)據(jù)包?
161.爬取數(shù)據(jù)后使用哪個數(shù)據(jù)庫存儲數(shù)據(jù)的,為什么?
162.你用過的爬蟲框架或者模塊有哪些?優(yōu)缺點(diǎn)?
163.寫爬蟲是用多進(jìn)程好?還是多線程好?
164.常見的反爬蟲和應(yīng)對方法?
165.解析網(wǎng)頁的解析器使用最多的是哪幾個?
166.需要登錄的網(wǎng)頁,如何解決同時限制ip,cookie,session
167.驗(yàn)證碼的解決?
168.使用最多的數(shù)據(jù)庫,對他們的理解?
169.編寫過哪些爬蟲中間件?
170.“極驗(yàn)”滑動驗(yàn)證碼如何破解?
171.爬蟲多久爬一次,爬下來的數(shù)據(jù)是怎么存儲?
172.cookie過期的處理問題?
173.動態(tài)加載又對及時性要求很高怎么處理?
174.HTTPS有什么優(yōu)點(diǎn)和缺點(diǎn)?
175.HTTPS是如何實(shí)現(xiàn)安全傳輸數(shù)據(jù)的?
176.TTL,MSL,RTT各是什么?
177.談一談你對Selenium和PhantomJS了解
178.平常怎么使用代理的 ?
179.存放在數(shù)據(jù)庫(redis、mysql等)。
180.怎么監(jiān)控爬蟲的狀態(tài)?
181.描述下scrapy框架運(yùn)行的機(jī)制?
182.談?wù)勀銓crapy的理解?
183.怎么樣讓 scrapy 框架發(fā)送一個 post 請求(具體寫出來)
184.怎么監(jiān)控爬蟲的狀態(tài) ?
185.怎么判斷網(wǎng)站是否更新?
186.圖片、視頻爬取怎么繞過防盜連接
187.你爬出來的數(shù)據(jù)量大概有多大?大概多長時間爬一次?
188.用什么數(shù)據(jù)庫存爬下來的數(shù)據(jù)?部署是你做的嗎?怎么部署?
189.增量爬取
190.爬取下來的數(shù)據(jù)如何去重,說一下scrapy的具體的算法依據(jù)。
191.Scrapy的優(yōu)缺點(diǎn)?
192.怎么設(shè)置爬取深度?
193.scrapy和scrapy-redis有什么區(qū)別?為什么選擇redis數(shù)據(jù)庫?
194.分布式爬蟲主要解決什么問題?
195.什么是分布式存儲?
196.你所知道的分布式爬蟲方案有哪些?
197.scrapy-redis,有做過其他的分布式爬蟲嗎?
數(shù)據(jù)庫
MySQL
198.主鍵 超鍵 候選鍵 外鍵
199.視圖的作用,視圖可以更改么?
200.drop,delete與truncate的區(qū)別
201.索引的工作原理及其種類
202.連接的種類
203.數(shù)據(jù)庫優(yōu)化的思路
204.存儲過程與觸發(fā)器的區(qū)別
205.悲觀鎖和樂觀鎖是什么?
206.你常用的mysql引擎有哪些?各引擎間有什么區(qū)別?
Redis
207.Redis宕機(jī)怎么解決?
208.redis和mecached的區(qū)別,以及使用場景
209.Redis集群方案該怎么做?都有哪些方案?
210.Redis回收進(jìn)程是如何工作的
MongoDB
211.MongoDB中對多條記錄做更新操作命令是什么?
212.MongoDB如何才會拓展到多個shard里?
測試
213.編寫測試計(jì)劃的目的是
214.對關(guān)鍵詞觸發(fā)模塊進(jìn)行測試
215.其他常用筆試題目網(wǎng)址匯總
216.測試人員在軟件開發(fā)過程中的任務(wù)是什么
217.一條軟件Bug記錄都包含了哪些內(nèi)容?
218.簡述黑盒測試和白盒測試的優(yōu)缺點(diǎn)
219.請列出你所知道的軟件測試種類,至少5項(xiàng)
220.Alpha測試與Beta測試的區(qū)別是什么?
221.舉例說明什么是Bug?一個bug report應(yīng)包含什么關(guān)鍵字?
數(shù)據(jù)結(jié)構(gòu)
222.數(shù)組中出現(xiàn)次數(shù)超過一半的數(shù)字-Python版
223.求100以內(nèi)的質(zhì)數(shù)
224.無重復(fù)字符的最長子串-Python實(shí)現(xiàn)
225.通過2個5/6升得水壺從池塘得到3升水
226.什么是MD5加密,有什么特點(diǎn)?
227.什么是對稱加密和非對稱加密
228.冒泡排序的思想?
229.快速排序的思想?
230.如何判斷單向鏈表中是否有環(huán)?
231.你知道哪些排序算法(一般是通過問題考算法)
232.斐波那契數(shù)列
233.如何翻轉(zhuǎn)一個單鏈表?
234.青蛙跳臺階問題
235.兩數(shù)之和 Two Sum
236.搜索旋轉(zhuǎn)排序數(shù)組 Search in Rotated Sorted Array
237.Python實(shí)現(xiàn)一個Stack的數(shù)據(jù)結(jié)構(gòu)
238.寫一個二分查找
239.set 用 in 時間復(fù)雜度是多少,為什么?
240.列表中有n個正整數(shù)范圍在[0,1000],進(jìn)行排序;
241.面向?qū)ο缶幊讨杏薪M合和繼承的方法實(shí)現(xiàn)新的類
大數(shù)據(jù)
242.找出1G的文件中高頻詞
243.一個大約有一萬行的文本文件統(tǒng)計(jì)高頻詞
244.怎么在海量數(shù)據(jù)中找出重復(fù)次數(shù)最多的一個?
245.判斷數(shù)據(jù)是否在大量數(shù)據(jù)中
總結(jié)
以上是生活随笔為你收集整理的[Python面试][基础算法题]Python基础面试(基础算法题目较多)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 把电脑端的图片链接转换为API接口可以调
- 下一篇: RTB 广告投放流程详解
