2019年 阿里巴巴Python 面试必备 !100 问
?
0 遇到過得反爬蟲策略以及解決方法?
1.通過headers反爬蟲
2.基于用戶行為的發(fā)爬蟲:(同一IP短時(shí)間內(nèi)訪問的頻率)
3.動(dòng)態(tài)網(wǎng)頁反爬蟲(通過ajax請(qǐng)求數(shù)據(jù),或者通過JavaScript生成)
4.對(duì)部分?jǐn)?shù)據(jù)進(jìn)行加密處理的(數(shù)據(jù)是亂碼)
解決方法:
對(duì)于基本網(wǎng)頁的抓取可以自定義headers,添加headers的數(shù)據(jù)
使用多個(gè)代理ip進(jìn)行抓取或者設(shè)置抓取的頻率降低一些,
動(dòng)態(tài)網(wǎng)頁的可以使用selenium + phantomjs 進(jìn)行抓取
對(duì)部分?jǐn)?shù)據(jù)進(jìn)行加密的,可以使用selenium進(jìn)行截圖,使用python自帶的pytesseract庫進(jìn)行識(shí)別,但是比較慢最直接的方法是找到加密的方法進(jìn)行逆向推理。
1 urllib 和 urllib2 的區(qū)別?
urllib 和urllib2都是接受URL請(qǐng)求的相關(guān)模塊,但是urllib2可以接受一個(gè)Request類的實(shí)例來設(shè)置URL請(qǐng)求的headers,urllib僅可以接受URL。urllib不可以偽裝你的User-Agent字符串。
urllib提供urlencode()方法用來GET查詢字符串的產(chǎn)生,而urllib2沒有。這是為何urllib常和urllib2一起使用的原因。在這里相信有許多想要學(xué)習(xí)Python的同學(xué),大家可以+下Python學(xué)習(xí)分享裙:五二八 三九七 六一七,即可免費(fèi)領(lǐng)取一整套系統(tǒng)的 Python學(xué)習(xí)教程!
2 列舉網(wǎng)絡(luò)爬蟲所用到的網(wǎng)絡(luò)數(shù)據(jù)包,解析包?
網(wǎng)絡(luò)數(shù)據(jù)包 urllib、urllib2、requests
解析包 re、xpath、beautiful soup、lxml
3 簡(jiǎn)述一下爬蟲的步驟?
確定需求;
確定資源;
通過url獲取網(wǎng)站的返回?cái)?shù)據(jù);
定位數(shù)據(jù);
存儲(chǔ)數(shù)據(jù)。
4 遇到反爬機(jī)制怎么處理?
反爬機(jī)制:
headers方向
判斷User-Agent、判斷Referer、判斷Cookie。
將瀏覽器的headers信息全部添加進(jìn)去
注意:Accept-Encoding;gzip,deflate需要注釋掉
5 常見的HTTP方法有哪些?
GET:請(qǐng)求指定的頁面信息,返回實(shí)體主體;
HEAD:類似于get請(qǐng)求,只不過返回的響應(yīng)中沒有具體的內(nèi)容,用于捕獲報(bào)頭;
POST:向指定資源提交數(shù)據(jù)進(jìn)行處理請(qǐng)求(比如表單提交或者上傳文件),。數(shù)據(jù)被包含在請(qǐng)求體中。
PUT:從客戶端向服務(wù)端傳送數(shù)據(jù)取代指定的文檔的內(nèi)容;
DELETE:請(qǐng)求刪除指定的頁面;
CONNNECT:HTTP1.1協(xié)議中預(yù)留給能夠?qū)⑦B接方式改為管道方式的代理服務(wù)器;
OPTIONS:允許客戶端查看服務(wù)器的性能;
TRACE:回顯服務(wù)器的請(qǐng)求,主要用于測(cè)試或者診斷。
6 說一說redis-scrapy中redis的作用?
它是將scrapy框架中Scheduler替換為redis數(shù)據(jù)庫,實(shí)現(xiàn)隊(duì)列管理共享。
優(yōu)點(diǎn):
可以充分利用多臺(tái)機(jī)器的帶寬;
可以充分利用多臺(tái)機(jī)器的IP地址。
7 遇到的反爬蟲策略以及解決方法?
通過headers反爬蟲:自定義headers,添加網(wǎng)頁中的headers數(shù)據(jù)。
基于用戶行為的反爬蟲(封IP):可以使用多個(gè)代理IP爬取或者將爬取的頻率降低。
動(dòng)態(tài)網(wǎng)頁反爬蟲(JS或者Ajax請(qǐng)求數(shù)據(jù)):動(dòng)態(tài)網(wǎng)頁可以使用 selenium + phantomjs 抓取。
對(duì)部分?jǐn)?shù)據(jù)加密處理(數(shù)據(jù)亂碼):找到加密方法進(jìn)行逆向推理。
8 如果讓你來防范網(wǎng)站爬蟲,你應(yīng)該怎么來提高爬取的難度 ?
判斷headers的User-Agent;
檢測(cè)同一個(gè)IP的訪問頻率;
數(shù)據(jù)通過Ajax獲取;
爬取行為是對(duì)頁面的源文件爬取,如果要爬取靜態(tài)網(wǎng)頁的html代碼,可以使用jquery去模仿寫html。
9 scrapy分為幾個(gè)組成部分?分別有什么作用?
分為5個(gè)部分;Spiders(爬蟲類),Scrapy Engine(引擎),Scheduler(調(diào)度器),Downloader(下載器),Item Pipeline(處理管道)。
Spiders:開發(fā)者自定義的一個(gè)類,用來解析網(wǎng)頁并抓取指定url返回的內(nèi)容。
Scrapy Engine:控制整個(gè)系統(tǒng)的數(shù)據(jù)處理流程,并進(jìn)行事務(wù)處理的觸發(fā)。
Scheduler:接收Engine發(fā)出的requests,并將這些requests放入到處理列隊(duì)中,以便之后engine需要時(shí)再提供。
Download:抓取網(wǎng)頁信息提供給engine,進(jìn)而轉(zhuǎn)發(fā)至Spiders。
Item Pipeline:負(fù)責(zé)處理Spiders類提取之后的數(shù)據(jù)。
比如清理HTML數(shù)據(jù)、驗(yàn)證爬取的數(shù)據(jù)(檢查item包含某些字段)、查重(并丟棄)、將爬取結(jié)果保存到數(shù)據(jù)庫中,遇到問題沒人解答,小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流裙:五二八 三九七 六一七, 尋找有志同道合的小伙伴,互幫互助,群里還有不錯(cuò)的學(xué)習(xí)視頻教程和PDF電子書分享!
10 簡(jiǎn)述一下scrapy的基本流程?
scrapy分為9個(gè)步驟:
Spiders需要初始的start_url或則函數(shù)stsrt_requests,會(huì)在內(nèi)部生成Requests給Engine;
Engine將requests發(fā)送給Scheduler;
Engine從Scheduler那獲取requests,交給Download下載;
在交給Dowmload過程中會(huì)經(jīng)過Downloader Middlewares(經(jīng)過process_request函數(shù));
Dowmloader下載頁面后生成一個(gè)response,這個(gè)response會(huì)傳給Engine,這個(gè)過程中又經(jīng)過了Downloader Middlerwares(經(jīng)過process_request函數(shù)),在傳送中出錯(cuò)的話經(jīng)過process_exception函數(shù);
Engine將從Downloader那傳送過來的response發(fā)送給Spiders處理,這個(gè)過程經(jīng)過Spiders Middlerwares(經(jīng)過process_spider_input函數(shù));
Spiders處理這個(gè)response,返回Requests或者Item兩個(gè)類型,傳給Engine,這個(gè)過程又經(jīng)過Spiders Middlewares(經(jīng)過porcess_spider_output函數(shù));
Engine接收返回的信息,如果使Item,將它傳給Items Pipeline中;如果是Requests,將它傳給Scheduler,繼續(xù)爬蟲;
重復(fù)第三步,直至沒有任何需要爬取的數(shù)據(jù)
11 python3.5語言中enumerate的意思是
對(duì)于一個(gè)可迭代的(iterable)/可遍歷的對(duì)象(如列表、字符串),enumerate將其組成一個(gè)索引序列,利用它可以同時(shí)獲得索引和值
enumerate多用于在for循環(huán)中得到計(jì)數(shù)
12 你是否了解谷歌的無頭瀏覽器?
無頭瀏覽器即headless browser,是一種沒有界面的瀏覽器。既然是瀏覽器那么瀏覽器該有的東西它都應(yīng)該有,只是看不到界面而已。
Python中selenium模塊中的PhantomJS即為無界面瀏覽器(無頭瀏覽器):是基于QtWebkit的無頭瀏覽器。
13 scrapy和scrapy-redis的區(qū)別?
scrapy是一個(gè)爬蟲通用框架,但不支持分布式,scrapy-redis是為了更方便的實(shí)現(xiàn)scrapy分布式爬蟲,而提供了一些以redis為基礎(chǔ)的組件
為什么會(huì)選擇redis數(shù)據(jù)庫?
因?yàn)閞edis支持主從同步,而且數(shù)據(jù)都是緩存在內(nèi)存中,所以基于redis的分布式爬蟲,對(duì)請(qǐng)求和數(shù)據(jù)的高頻讀取效率非常高
什么是主從同步?
在Redis中,用戶可以通過執(zhí)行SLAVEOF命令或者設(shè)置slaveof選項(xiàng),讓一個(gè)服務(wù)器去復(fù)制(replicate)另一個(gè)服務(wù)器,我們稱呼被復(fù)制的服務(wù)器為主服務(wù)器(master),而對(duì)主服務(wù)器進(jìn)行復(fù)制的服務(wù)器則被稱為從服務(wù)器(slave),當(dāng)客戶端向從服務(wù)器發(fā)送SLAVEOF命令,要求從服務(wù)器復(fù)制主服務(wù)器時(shí),從服務(wù)器首先需要執(zhí)行同步操作,也即是,將從服務(wù)器的數(shù)據(jù)庫狀態(tài)更新至主服務(wù)器當(dāng)前所處的數(shù)據(jù)庫狀態(tài)
14 scrapy的優(yōu)缺點(diǎn)?為什么要選擇scrapy框架?
優(yōu)點(diǎn):
采取可讀性更強(qiáng)的xpath代替正則 強(qiáng)大的統(tǒng)計(jì)和log系統(tǒng) 同時(shí)在不同的url上爬行 支持shell方式,方便獨(dú)立調(diào)試 寫middleware,方便寫一些統(tǒng)一的過濾器 通過管道的方式存入數(shù)據(jù)庫
缺點(diǎn):
基于python爬蟲框架,擴(kuò)展性比較差,基于twisted框架,運(yùn)行中exception是不會(huì)干掉reactor,并且異步框架出錯(cuò)后是不會(huì)停掉其他任務(wù)的,數(shù)據(jù)出錯(cuò)后難以察覺
15 scrapy和requests的使用情況?
requests 是 polling 方式的,會(huì)被網(wǎng)絡(luò)阻塞,不適合爬取大量數(shù)據(jù)
scapy 底層是異步框架 twisted ,并發(fā)是最大優(yōu)勢(shì)
16 描述一下scrapy框架的運(yùn)行機(jī)制?
從start_urls里面獲取第一批url發(fā)送請(qǐng)求,請(qǐng)求由請(qǐng)求引擎給調(diào)度器入請(qǐng)求對(duì)列,獲取完畢后,調(diào)度器將請(qǐng)求對(duì)列交給下載器去獲取請(qǐng)求對(duì)應(yīng)的響應(yīng)資源,并將響應(yīng)交給自己編寫的解析方法做提取處理,如果提取出需要的數(shù)據(jù),則交給管道處理,如果提取出url,則繼續(xù)執(zhí)行之前的步驟,直到多列里沒有請(qǐng)求,程序結(jié)束。
17 寫爬蟲使用多進(jìn)程好,還是用多線程好?
IO密集型代碼(文件處理、網(wǎng)絡(luò)爬蟲等),多線程能夠有效提升效率(單線程下有IO操作會(huì)進(jìn)行IO等待,造成不必要的時(shí)間浪費(fèi),而開啟多線程能在線程A等待時(shí),自動(dòng)切換到線程B,可以不浪費(fèi)CPU的資源,從而能提升程序執(zhí)行效率)。在實(shí)際的數(shù)據(jù)采集過程中,既考慮網(wǎng)速和響應(yīng)的問題,也需要考慮自身機(jī)器的硬件情況,來設(shè)置多進(jìn)程或多線程
18 常見的反爬蟲和應(yīng)對(duì)方法?
基于用戶行為,同一個(gè)ip段時(shí)間多次訪問同一頁面 利用代理ip,構(gòu)建ip池
請(qǐng)求頭里的user-agent 構(gòu)建user-agent池(操作系統(tǒng)、瀏覽器不同,模擬不同用戶)
動(dòng)態(tài)加載(抓到的數(shù)據(jù)和瀏覽器顯示的不一樣),js渲染 模擬ajax請(qǐng)求,返回json形式的數(shù)據(jù)
selenium / webdriver 模擬瀏覽器加載
對(duì)抓到的數(shù)據(jù)進(jìn)行分析
加密參數(shù)字段 會(huì)話跟蹤【cookie】 防盜鏈設(shè)置【Referer
19 分布式爬蟲主要解決什么問題?
面對(duì)海量待抓取網(wǎng)頁,只有采用分布式架構(gòu),才有可能在較短時(shí)間內(nèi)完成一輪抓取工作。
它的開發(fā)效率是比較快而且簡(jiǎn)單的。
20 如何提高爬取效率?
爬蟲下載慢主要原因是阻塞等待發(fā)往網(wǎng)站的請(qǐng)求和網(wǎng)站返回
1,采用異步與多線程,擴(kuò)大電腦的cpu利用率;
2,采用消息隊(duì)列模式
3,提高帶寬
21 說說什么是爬蟲協(xié)議?
Robots協(xié)議(也稱為爬蟲協(xié)議、爬蟲規(guī)則、機(jī)器人協(xié)議等)也就是robots.txt,網(wǎng)站通過robots協(xié)議告訴搜索引擎哪些頁面可以抓取,哪些頁面不能抓取。
Robots協(xié)議是網(wǎng)站國(guó)際互聯(lián)網(wǎng)界通行的道德規(guī)范,其目的是保護(hù)網(wǎng)站數(shù)據(jù)和敏感信息、確保用戶個(gè)人信息和隱私不被侵犯。因其不是命令,故需要搜索引擎自覺遵守。
22 如果對(duì)方網(wǎng)站反爬取,封IP了怎么辦?
放慢抓取熟速度,減小對(duì)目標(biāo)網(wǎng)站造成的壓力,但是這樣會(huì)減少單位時(shí)間內(nèi)的數(shù)據(jù)抓取量
使用代理IP(免費(fèi)的可能不穩(wěn)定,收費(fèi)的可能不劃算)
23 有一個(gè)jsonline格式的文件file
?
現(xiàn)在要處理一個(gè)大小為10G的文件,但是內(nèi)存只有4G,如果在只修改get_lines 函數(shù)而其他代碼保持不變的情況下,應(yīng)該如何實(shí)現(xiàn)?需要考慮的問題都有那些?
?
Pandaaaa906提供的方法
?
要考慮的問題有:內(nèi)存只有4G無法一次性讀入10G文件,需要分批讀入分批讀入數(shù)據(jù)要記錄每次讀入數(shù)據(jù)的位置。分批每次讀取數(shù)據(jù)的大小,太小會(huì)在讀取操作花費(fèi)過多時(shí)間。
24 補(bǔ)充缺失的代碼
?
25 輸入日期, 判斷這一天是這一年的第幾天?
?
26 打亂一個(gè)排好序的list對(duì)象alist?
?
27 現(xiàn)有字典 d= {'a':24,'g':52,'i':12,'k':33}請(qǐng)按value值進(jìn)行排序?
?
28 字典推導(dǎo)式
?
29 請(qǐng)反轉(zhuǎn)字符串 "aStr"?
?
?
30 將字符串 "k:1 |k1:2|k2:3|k3:4",處理成字典 {k:1,k1:2,
?
31 請(qǐng)按alist中元素的age由大到小排序
?
32 下面代碼的輸出結(jié)果將是什么?
?
代碼將輸出[],不會(huì)產(chǎn)生IndexError錯(cuò)誤,就像所期望的那樣,嘗試用超出成員的個(gè)數(shù)的index來獲取某個(gè)列表的成員。例如,嘗試獲取list[10]和之后的成員,會(huì)導(dǎo)致IndexError。然而,嘗試獲取列表的切片,開始的index超過了成員個(gè)數(shù)不會(huì)產(chǎn)生IndexError,而是僅僅返回一個(gè)空列表。這成為特別讓人惡心的疑難雜癥,因?yàn)檫\(yùn)行的時(shí)候沒有錯(cuò)誤產(chǎn)生,導(dǎo)致Bug很難被追蹤到。
?
33 寫一個(gè)列表生成式,產(chǎn)生一個(gè)公差為11的等差數(shù)列
?
34 給定兩個(gè)列表,怎么找出他們相同的元素和不同的元素?
?
35 請(qǐng)寫出一段python代碼實(shí)現(xiàn)刪除list里面的重復(fù)元素?
?
用list類的sort方法:
?
也可以這樣寫:
?
也可以用遍歷:
?
36 給定兩個(gè)list A,B ,請(qǐng)用找出A,B中相同與不同的元素
?
37 python新式類和經(jīng)典類的區(qū)別?
a. 在python里凡是繼承了object的類,都是新式類
b. Python3里只有新式類
c. Python2里面繼承object的是新式類,沒有寫父類的是經(jīng)典類
d. 經(jīng)典類目前在Python里基本沒有應(yīng)用
38 python中內(nèi)置的數(shù)據(jù)結(jié)構(gòu)有幾種?
a. 整型 int、 長(zhǎng)整型 long、浮點(diǎn)型 float、 復(fù)數(shù) complex
b. 字符串 str、 列表 list、 元祖 tuple
c. 字典 dict 、 集合 set
d. Python3 中沒有 long,只有無限精度的 int
39 python如何實(shí)現(xiàn)單例模式?請(qǐng)寫出兩種實(shí)現(xiàn)方式?
第一種方法:使用裝飾器
?
第二種方法:使用基類
New 是真正創(chuàng)建實(shí)例對(duì)象的方法,所以重寫基類的new 方法,以此保證創(chuàng)建對(duì)象的時(shí)候只生成一個(gè)實(shí)例
?
第三種方法:元類,元類是用于創(chuàng)建類對(duì)象的類,類對(duì)象創(chuàng)建實(shí)例對(duì)象時(shí)一定要調(diào)用call方法,因此在調(diào)用call時(shí)候保證始終只創(chuàng)建一個(gè)實(shí)例即可,type是python的元類
?
40 反轉(zhuǎn)一個(gè)整數(shù),例如-123 --> -321
?
41 設(shè)計(jì)實(shí)現(xiàn)遍歷目錄與子目錄,抓取.pyc文件?
第一種方法:
?
第二種方法:
?
第三種方法
?
42 Python-遍歷列表時(shí)刪除元素的正確做法
遍歷在新在列表操作,刪除時(shí)在原來的列表操作
?
列表解析
?
倒序刪除
因?yàn)榱斜砜偸恰蚯耙啤?#xff0c;所以可以倒序遍歷,即使后面的元素被修改了,還沒有被遍歷的元素和其坐標(biāo)還是保持不變的
?
43 字符串的操作題目
全字母短句 PANGRAM 是包含所有英文字母的句子,比如:A QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 定義并實(shí)現(xiàn)一個(gè)方法 get_missing_letter, 傳入一個(gè)字符串采納數(shù),返回參數(shù)字符串變成一個(gè) PANGRAM 中所缺失的字符。應(yīng)該忽略傳入字符串參數(shù)中的大小寫,返回應(yīng)該都是小寫字符并按字母順序排序(請(qǐng)忽略所有非 ACSII 字符)
下面示例是用來解釋,雙引號(hào)不需要考慮:
(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"
?
44 可變類型和不可變類型
1,可變類型有l(wèi)ist,dict.不可變類型有string,number,tuple.
2,當(dāng)進(jìn)行修改操作時(shí),可變類型傳遞的是內(nèi)存中的地址,也就是說,直接修改內(nèi)存中的值,并沒有開辟新的內(nèi)存。
3,不可變類型被改變時(shí),并沒有改變?cè)瓋?nèi)存地址中的值,而是開辟一塊新的內(nèi)存,將原地址中的值復(fù)制過去,對(duì)這塊新開辟的內(nèi)存中的值進(jìn)行操作。
45 is和==有什么區(qū)別?
is:比較的是兩個(gè)對(duì)象的id值是否相等,也就是比較倆對(duì)象是否為同一個(gè)實(shí)例對(duì)象。是否指向同一個(gè)內(nèi)存地址
== : 比較的兩個(gè)對(duì)象的內(nèi)容/值是否相等,默認(rèn)會(huì)調(diào)用對(duì)象的eq()方法
46 求出列表所有奇數(shù)并構(gòu)造新列表
?
47 用一行python代碼寫出1+2+3+10248
?
48 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種,稱之為L(zhǎng)EGB,也正是按照這是順序來查找的
49 字符串 "123" 轉(zhuǎn)換成 123,不使用內(nèi)置api,例如 int()
方法一: 利用 str 函數(shù)
?
方法二: 利用 ord 函數(shù)
?
方法三: 利用 eval 函數(shù)
?
?
方法四: 結(jié)合方法二,使用 reduce,一行解決
?
50 Given an array of integers
給定一個(gè)整數(shù)數(shù)組和一個(gè)目標(biāo)值,找出數(shù)組中和為目標(biāo)值的兩個(gè)數(shù)。你可以假設(shè)每個(gè)輸入只對(duì)應(yīng)一種答案,且同樣的元素不能被重復(fù)利用。示例:給定nums = [2,7,11,15],target=9 因?yàn)?nums[0]+nums[1] = 2+7 =9,所以返回[0,1]
?
給列表中的字典排序:假設(shè)有如下list對(duì)象,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}]
?
51 python代碼實(shí)現(xiàn)刪除一個(gè)list里面的重復(fù)元素
52 統(tǒng)計(jì)一個(gè)文本中單詞頻次最高的10個(gè)單詞?
?
53 請(qǐng)寫出一個(gè)函數(shù)滿足以下條件
該函數(shù)的輸入是一個(gè)僅包含數(shù)字的list,輸出一個(gè)新的list,其中每一個(gè)元素要滿足以下條件:
1、該元素是偶數(shù)
2、該元素在原list中是在偶數(shù)的位置(index是偶數(shù))
54 使用單一的列表生成式來產(chǎn)生一個(gè)新的列表
該列表只包含滿足以下條件的值,元素為原始列表中偶數(shù)切片
?
55 用一行代碼生成[1,4,9,16,25,36,49,64,81,100]
?
56 輸入某年某月某日,判斷這一天是這一年的第幾天?
?
57 兩個(gè)有序列表,l1,l2,對(duì)這兩個(gè)列表進(jìn)行合并不可使用extend
?
58 給定一個(gè)任意長(zhǎng)度數(shù)組,實(shí)現(xiàn)一個(gè)函數(shù)
讓所有奇數(shù)都在偶數(shù)前面,而且奇數(shù)升序排列,偶數(shù)降序排序,如字符串'1982376455',變成'1355798642'
?
59 寫一個(gè)函數(shù)找出一個(gè)整數(shù)數(shù)組中,第二大的數(shù)
?
60 閱讀一下代碼他們的輸出結(jié)果是什么?
?
正確答案是[9,9,9,9],而不是[0,3,6,9]產(chǎn)生的原因是Python的閉包的后期綁定導(dǎo)致的,這意味著在閉包中的變量是在內(nèi)部函數(shù)被調(diào)用的時(shí)候被查找的,因?yàn)?#xff0c;最后函數(shù)被調(diào)用的時(shí)候,for循環(huán)已經(jīng)完成, i 的值最后是3,因此每一個(gè)返回值的i都是3,所以最后的結(jié)果是[9,9,9,9]
61 統(tǒng)計(jì)一段字符串中字符出現(xiàn)的次數(shù)
?
62 Python中類方法、類實(shí)例方法、靜態(tài)方法有何區(qū)別?
類方法: 是類對(duì)象的方法,在定義時(shí)需要在上方使用 @classmethod 進(jìn)行裝飾,形參為cls,表示類對(duì)象,類對(duì)象和實(shí)例對(duì)象都可調(diào)用
類實(shí)例方法: 是類實(shí)例化對(duì)象的方法,只有實(shí)例對(duì)象可以調(diào)用,形參為self,指代對(duì)象本身;
靜態(tài)方法: 是一個(gè)任意函數(shù),在其上方使用 @staticmethod 進(jìn)行裝飾,可以用對(duì)象直接調(diào)用,靜態(tài)方法實(shí)際上跟該類沒有太大關(guān)系
63 遍歷一個(gè)object的所有屬性,并print每一個(gè)屬性名?
?
64 寫一個(gè)類,并讓它盡可能多的支持操作符?
?
65 關(guān)于Python內(nèi)存管理,下列說法錯(cuò)誤的是 B
A,變量不必事先聲明 B,變量無須先創(chuàng)建和賦值而直接使用
C,變量無須指定類型 D,可以使用del釋放資源
66 Python的內(nèi)存管理機(jī)制及調(diào)優(yōu)手段?
內(nèi)存管理機(jī)制: 引用計(jì)數(shù)、垃圾回收、內(nèi)存池
引用計(jì)數(shù):引用計(jì)數(shù)是一種非常高效的內(nèi)存管理手段,當(dāng)一個(gè)Python對(duì)象被引用時(shí)其引用計(jì)數(shù)增加1,
當(dāng)其不再被一個(gè)變量引用時(shí)則計(jì)數(shù)減1,當(dāng)引用計(jì)數(shù)等于0時(shí)對(duì)象被刪除。弱引用不會(huì)增加引用計(jì)數(shù)
垃圾回收:
1.引用計(jì)數(shù)
引用計(jì)數(shù)也是一種垃圾收集機(jī)制,而且也是一種最直觀、最簡(jiǎn)單的垃圾收集技術(shù)。當(dāng)Python的某個(gè)對(duì)象的引用計(jì)數(shù)降為0時(shí),說明沒有任何引用指向該對(duì)象,該對(duì)象就成為要被回收的垃圾了。比如某個(gè)新建對(duì)象,它被分配給某個(gè)引用,對(duì)象的引用計(jì)數(shù)變?yōu)?,如果引用被刪除,對(duì)象的引用計(jì)數(shù)為0,那么該對(duì)象就可以被垃圾回收。不過如果出現(xiàn)循環(huán)引用的話,引用計(jì)數(shù)機(jī)制就不再起有效的作用了。
2.標(biāo)記清除
調(diào)優(yōu)手段
1.手動(dòng)垃圾回收
2.調(diào)高垃圾回收閾值
3.避免循環(huán)引用
67 內(nèi)存泄露是什么?如何避免?
內(nèi)存泄漏指由于疏忽或錯(cuò)誤造成程序未能釋放已經(jīng)不再使用的內(nèi)存。內(nèi)存泄漏并非指內(nèi)存在物理上的消失,而是應(yīng)用程序分配某段內(nèi)存后,由于設(shè)計(jì)錯(cuò)誤,導(dǎo)致在釋放該段內(nèi)存之前就失去了對(duì)該段內(nèi)存的控制,從而造成了內(nèi)存的浪費(fèi)。
有__del__()函數(shù)的對(duì)象間的循環(huán)引用是導(dǎo)致內(nèi)存泄露的主兇。不使用一個(gè)對(duì)象時(shí)使用: del object 來刪除一個(gè)對(duì)象的引用計(jì)數(shù)就可以有效防止內(nèi)存泄露問題。
通過Python擴(kuò)展模塊gc 來查看不能回收的對(duì)象的詳細(xì)信息。
可以通過 sys.getrefcount(obj) 來獲取對(duì)象的引用計(jì)數(shù),并根據(jù)返回值是否為0來判斷是否內(nèi)存泄露
68 python常見的列表推導(dǎo)式?
[表達(dá)式 for 變量 in 列表] 或者 [表達(dá)式 for 變量 in 列表 if 條件]
69 簡(jiǎn)述read、readline、readlines的區(qū)別?
read 讀取整個(gè)文件
readline 讀取下一行
readlines 讀取整個(gè)文件到一個(gè)迭代器以供我們遍歷
70 什么是Hash(散列函數(shù))?
散列函數(shù)(英語:Hash function)又稱散列算法、哈希函數(shù),是一種從任何一種數(shù)據(jù)中創(chuàng)建小的數(shù)字“指紋”的方法。散列函數(shù)把消息或數(shù)據(jù)壓縮成摘要,使得數(shù)據(jù)量變小,將數(shù)據(jù)的格式固定下來。該函數(shù)將數(shù)據(jù)打亂混合,重新創(chuàng)建一個(gè)叫做散列值(hash values,hash codes,hash sums,或hashes)的指紋。散列值通常用一個(gè)短的隨機(jī)字母和數(shù)字組成的字符串來代表
71 python函數(shù)重載機(jī)制?
函數(shù)重載主要是為了解決兩個(gè)問題。
1。可變參數(shù)類型。
2。可變參數(shù)個(gè)數(shù)。
另外,一個(gè)基本的設(shè)計(jì)原則是,僅僅當(dāng)兩個(gè)函數(shù)除了參數(shù)類型和參數(shù)個(gè)數(shù)不同以外,其功能是完全相同的,此時(shí)才使用函數(shù)重載,如果兩個(gè)函數(shù)的功能其實(shí)不同,那么不應(yīng)當(dāng)使用重載,而應(yīng)當(dāng)使用一個(gè)名字不同的函數(shù)。
好吧,那么對(duì)于情況 1 ,函數(shù)功能相同,但是參數(shù)類型不同,python 如何處理?答案是根本不需要處理,因?yàn)?python 可以接受任何類型的參數(shù),如果函數(shù)的功能相同,那么不同的參數(shù)類型在 python 中很可能是相同的代碼,沒有必要做成兩個(gè)不同函數(shù)。
那么對(duì)于情況 2 ,函數(shù)功能相同,但參數(shù)個(gè)數(shù)不同,python 如何處理?大家知道,答案就是缺省參數(shù)。對(duì)那些缺少的參數(shù)設(shè)定為缺省參數(shù)即可解決問題。因?yàn)槟慵僭O(shè)函數(shù)功能相同,那么那些缺少的參數(shù)終歸是需要用的。
好了,鑒于情況 1 跟 情況 2 都有了解決方案,python 自然就不需要函數(shù)重載了。
72 手寫一個(gè)判斷時(shí)間的裝飾器
?
73 使用Python內(nèi)置的filter()方法來過濾?
?
74 編寫函數(shù)的4個(gè)原則
1.函數(shù)設(shè)計(jì)要盡量短小
2.函數(shù)聲明要做到合理、簡(jiǎn)單、易于使用
3.函數(shù)參數(shù)設(shè)計(jì)應(yīng)該考慮向下兼容
4.一個(gè)函數(shù)只做一件事情,盡量保證函數(shù)語句粒度的一致性
75 函數(shù)調(diào)用參數(shù)的傳遞方式是值傳遞還是引用傳遞?
Python的參數(shù)傳遞有:位置參數(shù)、默認(rèn)參數(shù)、可變參數(shù)、關(guān)鍵字參數(shù)。
函數(shù)的傳值到底是值傳遞還是引用傳遞、要分情況:
不可變參數(shù)用值傳遞:像整數(shù)和字符串這樣的不可變對(duì)象,是通過拷貝進(jìn)行傳遞的,因?yàn)槟銦o論如何都不可能在原處改變不可變對(duì)象。
可變參數(shù)是引用傳遞:比如像列表,字典這樣的對(duì)象是通過引用傳遞、和C語言里面的用指針傳遞數(shù)組很相似,可變對(duì)象能在函數(shù)內(nèi)部改變。
76 如何在function里面設(shè)置一個(gè)全局變量
?
77 對(duì)缺省參數(shù)的理解 ?
缺省參數(shù)指在調(diào)用函數(shù)的時(shí)候沒有傳入?yún)?shù)的情況下,調(diào)用默認(rèn)的參數(shù),在調(diào)用函數(shù)的同時(shí)賦值時(shí),所傳入的參數(shù)會(huì)替代默認(rèn)參數(shù)。
*args是不定長(zhǎng)參數(shù),它可以表示輸入?yún)?shù)是不確定的,可以是任意多個(gè)。
**kwargs是關(guān)鍵字參數(shù),賦值的時(shí)候是以鍵值對(duì)的方式,參數(shù)可以是任意多對(duì)在定義函數(shù)的時(shí)候
不確定會(huì)有多少參數(shù)會(huì)傳入時(shí),就可以使用兩個(gè)參數(shù)
78 帶參數(shù)的裝飾器?
帶定長(zhǎng)參數(shù)的裝飾器
?
帶不定長(zhǎng)參數(shù)的裝飾器
?
79 為什么函數(shù)名字可以當(dāng)做參數(shù)用?
Python中一切皆對(duì)象,函數(shù)名是函數(shù)在內(nèi)存中的空間,也是一個(gè)對(duì)象
80 Python中pass語句的作用是什么?
在編寫代碼時(shí)只寫框架思路,具體實(shí)現(xiàn)還未編寫就可以用pass進(jìn)行占位,是程序不報(bào)錯(cuò),不會(huì)進(jìn)行任何操作。
81 有這樣一段代碼,print c會(huì)輸出什么,為什么?
?
答:10對(duì)于字符串,數(shù)字,傳遞是相應(yīng)的值
82 交換兩個(gè)變量的值?
?
83 map函數(shù)和reduce函數(shù)?
?
84 回調(diào)函數(shù),如何通信的?
回調(diào)函數(shù)是把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),將整個(gè)函數(shù)當(dāng)作一個(gè)對(duì)象,賦值給調(diào)用的函數(shù)。
85 Python主要的內(nèi)置數(shù)據(jù)類型都有哪些? print dir( ‘a(chǎn) ’) 的輸出?
內(nèi)建類型:布爾類型,數(shù)字,字符串,列表,元組,字典,集合
輸出字符串'a'的內(nèi)建方法
86 map(lambda x:xx,[y for y in range(3)])的輸出?
?
87 hasattr() getattr() setattr() 函數(shù)使用詳解?
hasattr(object,name)函數(shù):
判斷一個(gè)對(duì)象里面是否有name屬性或者name方法,返回bool值,有name屬性(方法)返回True,否則返回False。
?
getattr(object, name[,default])函數(shù):
獲取對(duì)象object的屬性或者方法,如果存在則打印出來,如果不存在,打印默認(rèn)值,默認(rèn)值可選。注意:如果返回的是對(duì)象的方法,則打印結(jié)果是:方法的內(nèi)存地址,如果需要運(yùn)行這個(gè)方法,可以在后面添加括號(hào)().
?
setattr(object, name, values)函數(shù):
給對(duì)象的屬性賦值,若屬性不存在,先創(chuàng)建再賦值
綜合使用
?
88 一句話解決階乘函數(shù)?
?
89 對(duì)設(shè)計(jì)模式的理解,簡(jiǎn)述你了解的設(shè)計(jì)模式?
設(shè)計(jì)模式是經(jīng)過總結(jié),優(yōu)化的,對(duì)我們經(jīng)常會(huì)碰到的一些編程問題的可重用解決方案。一個(gè)設(shè)計(jì)模式并不像一個(gè)類或一個(gè)庫那樣能夠直接作用于我們的代碼,反之,設(shè)計(jì)模式更為高級(jí),它是一種必須在特定情形下實(shí)現(xiàn)的一種方法模板。
常見的是工廠模式和單例模式
90 請(qǐng)手寫一個(gè)單例
?
91 單例模式的應(yīng)用場(chǎng)景有那些?
單例模式應(yīng)用的場(chǎng)景一般發(fā)現(xiàn)在以下條件下:
資源共享的情況下,避免由于資源操作時(shí)導(dǎo)致的性能或損耗等,如日志文件,應(yīng)用配置。
控制資源的情況下,方便資源之間的互相通信。如線程池等,1,網(wǎng)站的計(jì)數(shù)器 2,應(yīng)用配置 3.多線程池 4數(shù)據(jù)庫配置 數(shù)據(jù)庫連接池 5.應(yīng)用程序的日志應(yīng)用...
92 用一行代碼生成[1,4,9,16,25,36,49,64,81,100]
?
93 對(duì)裝飾器的理解,并寫出一個(gè)計(jì)時(shí)器記錄方法執(zhí)行性能的裝飾器?
裝飾器本質(zhì)上是一個(gè)callable object ,它可以讓其他函數(shù)在不需要做任何代碼變動(dòng)的前提下增加額外功能,裝飾器的返回值也是一個(gè)函數(shù)對(duì)象。
?
94 解釋以下什么是閉包?
在函數(shù)內(nèi)部再定義一個(gè)函數(shù),并且這個(gè)函數(shù)用到了外邊函數(shù)的變量,那么將這個(gè)函數(shù)以及用到的一些變量稱之為閉包。
95 函數(shù)裝飾器有什么作用?
裝飾器本質(zhì)上是一個(gè)callable object,它可以在讓其他函數(shù)在不需要做任何代碼的變動(dòng)的前提下增加額外的功能。裝飾器的返回值也是一個(gè)函數(shù)的對(duì)象,它經(jīng)常用于有切面需求的場(chǎng)景。比如:插入日志,性能測(cè)試,事務(wù)處理,緩存。權(quán)限的校驗(yàn)等場(chǎng)景,有了裝飾器就可以抽離出大量的與函數(shù)功能本身無關(guān)的雷同代碼并發(fā)并繼續(xù)使用。
詳細(xì)參考:https://manjusaka.itscoder.com/2018/02/23/something-about-decorator/
96 生成器,迭代器的區(qū)別?
迭代器是遵循迭代協(xié)議的對(duì)象。用戶可以使用 iter() 以從任何序列得到迭代器(如 list, tuple, dictionary, set 等)。另一個(gè)方法則是創(chuàng)建一個(gè)另一種形式的迭代器 —— generator 。要獲取下一個(gè)元素,則使用成員函數(shù) next()(Python 2)或函數(shù) next() function (Python 3) 。當(dāng)沒有元素時(shí),則引發(fā) StopIteration 此例外。若要實(shí)現(xiàn)自己的迭代器,則只要實(shí)現(xiàn) next()(Python 2)或 __next__()( Python 3)
生成器(Generator),只是在需要返回?cái)?shù)據(jù)的時(shí)候使用yield語句。每次next()被調(diào)用時(shí),生成器會(huì)返回它脫離的位置(它記憶語句最后一次執(zhí)行的位置和所有的數(shù)據(jù)值)
區(qū)別: 生成器能做到迭代器能做的所有事,而且因?yàn)樽詣?dòng)創(chuàng)建iter()和next()方法,生成器顯得特別簡(jiǎn)潔,而且生成器也是高效的,使用生成器表達(dá)式取代列表解析可以同時(shí)節(jié)省內(nèi)存。除了創(chuàng)建和保存程序狀態(tài)的自動(dòng)方法,當(dāng)發(fā)生器終結(jié)時(shí),還會(huì)自動(dòng)拋出StopIteration異常。
97 X是什么類型?
X= (i for i in range(10))
X是 generator類型
98 請(qǐng)用一行代碼 實(shí)現(xiàn)將1-N 的整數(shù)列表以3為單位分組
99 Python中yield的用法?
yield就是保存當(dāng)前程序執(zhí)行狀態(tài)。你用for循環(huán)的時(shí)候,每次取一個(gè)元素的時(shí)候就會(huì)計(jì)算一次。用yield的函數(shù)叫g(shù)enerator,和iterator一樣,它的好處是不用一次計(jì)算所有元素,而是用一次算一次,可以節(jié)省很多空間,generator每次計(jì)算需要上一次計(jì)算結(jié)果,所以用yield,否則一return,上次計(jì)算結(jié)果就沒了
總結(jié)
以上是生活随笔為你收集整理的2019年 阿里巴巴Python 面试必备 !100 问的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络安全乱流,超级保护才是根本
- 下一篇: python 滚动字幕_python 实