1、python中is和==的區別
A.Python中對象包含的三個基本要素,分別是:id(身份標識) 、type(數據類型)和value(值)。
B.‘==’比較的是value值
C.‘is’比較的是id
2、簡述read、readline、readlines的區別
read讀取整個文件
readline讀取下一行數據
readlines讀取整個文件到一個迭代器以供我們遍歷(讀取 到一個list中,以供使用,比較方便)
3、舉例說明創建字典的至少兩種方法
# 1
dict1 = {key1:v1,key2:v2}
# 2
dict2 = {}
dict2[key1] = v1
dict2[key2] = v2
# 3
dict3 = dict(key1=v1,key2=v2)
4、*args,**kwargs的作用是什么?如何使用?
*args和**kwargs通常使用在函數定義里,*args允許函數傳入不定量個數的非關鍵字參數,**kwargs允許函數傳入不定量個數的關鍵字參數
5、python中match()和search()的區別?
match()函數只檢測RE是不是在string的開始位置匹配, search()會掃描整個string查找匹配, 也就是說match()只有在0位置匹配成功的話才有返回,如果不是開始位置匹配成功的話,match()就返回none
6、一個函數接收文件夾的名稱作為參數,返回該文件中所有文件的全路徑,請補全缺失的代碼。
def print_directry_contents(spath):
import os
files_list = os.listdir(spath)
for file in files_list:
print(os.path.realpath(file))
7、閱讀下面的代碼,寫出A0,A1至An的最終值
A0 = dict(zip(('a','b','c','d','e'),(1,2,3,4,5)))
A0 = {'a':1,'b':2,'c':3,'d':4,'e':5}
A1 = range(10)
A1 = [0,1,2,3,4,5,6,7,8,9]
A2 = [i for i in A1 if i in A0]
A2 = [] # 當對字典進行in判斷是,判斷的是key
A3 = [A0[s] for s in A0]
A3 = [1,2,3,4,5]
A4 = [i for i in A1 if i in A3]
A4 = [1,2,3,4,5]
8、請寫一段代碼實現Python中list去重。
# 方法1
list1 = [1,1,2,3,3,4]
set1 = set(list1)
list1 = list(set1)
# 方法2
list2 = []
for i in list1:
if i not in list2:
list2.append(i)
9、創建一個裝飾器將下面函數輸入的字符串首字母大寫。
def greetins(word='hi there'):
return word.lower()
from functools import wraps
def start_word_upper(func):
@wraps(func)
def inner(*args,**kwargs):
word = func(*args,**kwargs)
return word.capitalize()
return inner
# 裝飾器可以在:
# 1.函數調用之前對函數參數進行操作,直接返回被裝飾函數的返回值
# 2.對返回值進行‘裝飾’並返回(本題案例)
10、描述yield作用。
保存當前運行狀態(斷點),然后暫停執行,即將函數掛起
將yeild關鍵字后面表達式的值作為返回值返回,此時可以理解為起到了return的作用,當使用next()、send()函數讓函數從斷點處繼續執行,即喚醒函數。
11、裝飾器。
裝飾器本質上是一個Python函數,它可以讓其他函數在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個函數對象。
功能:1.引入日志;2.函數執行時間統計;3.執行函數前預備處理;4.執行函數后清理功能;5.權限校驗;6.緩存
12、你對多線程和多進程的理解。
進程是系統進行資源分配和調度的一個獨立單位,線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源;
一個程序至少有一個進程,一個進程至少有一個線程;
線程的划分尺度小於進程(資源比進程少),使得多線程程序的並發性高;
進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率 ;
線線程不能夠獨立執行,必須依存在進程中;
優缺點:線程和進程在使用上各有優缺點:線程執行開銷小,但不利於資源的管理和保護;而進程正相反。
13、線程中start方法和run方法的區別?
若調用start,則先執行主進程,后執行子進程;
若調用run,相當於正常的函數調用,將按照程序的順序執行
14、linux命令 grep awk sed是怎么用的?
grep:Global Regular Expression Print
15、python是怎么進行內存管理的?
引用計數:python內部使用引用計數,來保持追蹤內存中的對象,Python內部記錄了對象有多少個引用,即引用計數,當對象被創建時就創建了一個引用計數,當對象不再需要時,這個對象的引用計數為0時,它被垃圾回收。
引用計數加1的情況:
對象被創建:x=4
另外的別人被創建:y=x
被作為參數傳遞給函數:foo(x)
作為容器對象的一個元素:a=[1,x,'33']
引用計數減少情況
一個本地引用離開了它的作用域。比如上面的foo(x)函數結束時,x指向的對象引用減1。
對象的別名被顯式的銷毀:del x ;或者del y
對象的一個別名被賦值給其他對象:x=789
對象從一個窗口對象中移除:myList.remove(x)
窗口對象本身被銷毀:del myList,或者窗口對象本身離開了作用域
垃圾回收
當內存中有不再使用的部分時,垃圾收集器就會把他們清理掉。它會去檢查那些引用計數為0的對象,然后清除其在內存的空間。當然除了引用計數為0的會被清除,還有一種情況也會被垃圾收集器清掉:當兩個對象相互引用時,他們本身其他的引用已經為0了。
垃圾回收機制還有一個循環垃圾回收器, 確保釋放循環引用對象(a引用b, b引用a, 導致其引用計數永遠不為0)。
內存池機制:在Python中,許多時候申請的內存都是小塊的內存,這些小塊內存在申請后,很快又會被釋放,由於這些內存的申請並不是為了創建對象,所以並沒有對象一級的內存池機制。這就意味着Python在運行期間會大量地執行malloc和free的操作,頻繁地在用戶態和核心態之間進行切換,這將嚴重影響Python的執行效率。為了加速Python的執行效率,Python引入了一個內存池機制,用於管理對小塊內存的申請和釋放。
Python提供了對內存的垃圾收集機制,但是它將不用的內存放到內存池而不是返回給操作系統。
Python中所有小於256個字節的對象都使用pymalloc實現的分配器,而大的對象則使用系統的 malloc。另外Python對象,如整數,浮點數和List,都有其獨立的私有內存池,對象間不共享他們的內存池。也就是說如果你分配又釋放了大量的整數,用於緩存這些整數的內存就不能再分配給浮點數。
16、什么是lambda函數?他有什么好處? lambda函數是匿名函數;使用lambda函數能夠創建小型匿名函數。這種函數得名於省略了用def聲明函數的標准步驟; 例:
f = lambda x,y:x+y # 求兩個函數的和。 x,y是參數,x+y是函數返回值
17、python中tuple和list的轉換
# tuple ---> list
tuple1 = (1,2,3)
list1 = list(tuple1)
# list ---> tuple
list2 = [1,2,3]
tuple2 = tuple(list2)
18、python中如何拷貝一個對象?(賦值,淺拷貝,深拷貝的區別)
答:賦值(=),就是創建了對象的一個新的引用,修改其中任意一個變量都會影響到另一個。
淺拷貝:創建一個新的對象,但它包含的是對原始對象中包含項的引用(如果用引用的方式修改其中一個對象,另外一個也會修改改變){1,完全切片方法;2,工廠函數,如list();3,copy模塊的copy()函數}
深拷貝:創建一個新的對象,並且遞歸的復制它所包含的對象(修改其中一個,另外一個不會改變){copy模塊的deep.deepcopy()函數}
19、介紹一下except的用法和作用?
try:
pass
except Exception as e:
print(e)
finally:
pass
捕獲try except中間代碼發生的異常,如果發生異常執行except的代碼,不管是否發生異常都執行finally中的代碼
except可以有0個或多個,如果有多個從上到下依次根據異常類型匹配,匹配某個Exception這執行對應的except中代碼
20、用python匹配HTML tag的時候,<.*>和<.*?>有什么區別?
<.*>匹配結果是:HTML tag;
<.*?>匹配到的結果是:""。 ? 表示非貪婪,搜到符合的結果既返回
21、有沒有一個工具可以幫助查找Python的bug和進行靜態的代碼分析?
PyChecker是一個python代碼的靜態分析工具,它可以幫助查找python代碼的bug, 會對代碼的復雜度和格式提出警告
Pylint是另外一個工具可以進行codingstandard檢查
22、請寫一段腳本,查找/data/test 目錄下3天前的文件,從中挑選出大小超過10M的刪除掉。
#!/bin/sh
find "/data/test" -mtime +3 -size +10M -exec rm {} \
23、請寫一段python代碼,替換掉目標字符串中的[北京市,技術,有限,公司]等字符,比如:目標字符串:北京市麥達技術數字有限公司,要求替換輸出 麥達數字。
str1 = "北京市麥達技術數字有限公司"
str2 = str1.replace("北京市","").replace("技術","").replace("有限","").replace("公司","")
24、有三張表分別存放省市(province),地市(city)和縣區(area)的名稱和編碼,表名如下表格:
省份表 Province 地市表 City 縣表 Area
province_id 省編號 city_id 市編號 area_id 縣區編號
province 省 city 城市名 area 區縣名稱
province_id 省編號 city_id 市編號
請寫出一段sql語句,挑選出江蘇省的地市和區縣。
輸出這樣:
南京市 秦淮區
南京市 玄武區
···
徐州市 鼓樓區
徐州市 沛縣
select City.city,Area.area from City inner Area on City.city_id = Area.city_id where
City.province_id = (select province_id from Province where province = "江蘇省")
25、有一個純字符串,編寫一段代碼,列出其所有字符的大小寫組合
如 :字符串“ji”,字母組合['ji','jI','Ji','JI']
即每個字符的大小寫組合
def word_group(word):
word = word.lower()
dict = {}
list = []
for letter in word:
if not dict:
list.append(letter)
list.append(letter.upper())
dict[word.index(letter)] = list
else:
list = []
for i in dict[word.index(letter)-1] :
list.append(i + letter)
list.append(i+ letter.upper())
dict[word.index(letter)] = list
print(dict[len(word)-1])
26、簡述一下你熟悉的NOSQL,它有什么優點和缺點?
redis:
優點:
- 讀寫性能優異;
- 支持數據持久化,支持AOF和RDB兩種持久化方式;
- 支持主從復制,主機會自動將數據同步到從機,可以進行讀寫分離;
- 數據結構豐富:除了支持string類型的value外還支持string、hash、set、sortedset、list等數據結構。
缺點:
- Redis不具備自動容錯和恢復功能,主機從機的宕機都會導致前端部分讀寫請求失敗,需要等待機器重啟或者手動切換前端的IP才能恢復;
- 主機宕機,宕機前有部分數據未能及時同步到從機,切換IP后還會引入數據不一致的問題,降低了系統的可用性;
- Redis的主從復制采用全量復制,復制過程中主機會fork出一個子進程對內存做一份快照,並將子進程的內存快照保存為文件發送給從機,這一過程需要確保主機有足夠多的空余內存。若快照文件較大,對集群的服務能力會產生較大的影響,而且復制過程是在從機新加入集群或者從機和主機網絡斷開重連時都會進行,也就是網絡波動都會造成主機和從機間的一次全量的數據復制,這對實際的系統運營造成了不小的麻煩;
- Redis較難支持在線擴容,在集群容量達到上限時在線擴容會變得很復雜。為避免這一問題,運維人員在系統上線時必須確保有足夠的空間,這對資源造成了很大的浪費。
27、使用一個正則表達式設計一個程序,將字符串"<a href=www.baidu.com>正則表達式題庫</a><a href=www.cdtest.cn></a>"的www.baidu.com和www.cdtest.cn同時匹配出來。
import re
str = "\<a href=www.baidu.com\>正則表達式題庫\</a>\<a href=www.cdtest.cn\>\</a>"
regex = r"href=(.*?)>"
ret_list = re.findall(regex,str)
28、設計一個程序,求出1+3!+5!+7!+9!+50!的和。
# 求1+3!+5!+7!+9!
m = 0
for i in range(1,6):
n = 1
for j in range(1,2*i):
n = n*j
m += n
# 求50!
l = 1
for x in range(1,51):
l = l*x
# 和
sum = m+l
print(sum)
29、把字符串“HELLO PYTHON”從大寫字母全部轉換成小寫字母並換行顯示,然后輸出到計算機c盤的hello.txt文件中保存。
str = 'HELLO PYTHON'
with open(r'C:/hello.txt','a') as f:
for letter in str:
letter = letter.lower()
f.write(letter)
f.write('\n')
30、設計一個小程序,采用任意數據結構方法,輸入年、月、日后能判定當前日期在本年是第幾天。
def judge_dayth(y=None,m=None,d=None):
# 判斷是否是潤年
if y%4==0 and y%100!=0 or y%400==0:
m_list = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
else:
m_list = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
if m == 1:
dayth = d
else:
m_days = 0
for i in range(m-1):
m_days += m_list[i]
dayth = m_days + d
print(dayth)
31、給定一個值為整數的數組int_array,找出int_array中第二大的整數。
說明:如果最大的整數在int_array中出現不止一次,則最大整數為第二大整數。
例:
輸入:[1,2,3,4,5]
輸出:4
輸入:[5,5,4,4,3]
輸出:5
import json
def find_max(int_array):
max_int = 0
for i in int_array:
if i > max_int:
max_int = i
return max_int
int_array = json.loads(input()) # 將字符串轉化為列表
max_int = find_max(int_array)
int_array.remove(max_int)
max_int = find_max(int_array)
print(max_int)
32、使用python將字符串“1.2.3.4.5”轉換為字符串“5|4|3|2|1”
str = "1.2.3.4.5"
li = str.split(".") # li = [1,2,3,4,5]
# 列表倒序
li = li[::-1] # li = list(reversed(li)) 或者 li = sorted(li,reverse=True)
# 字符串拼接
str = "|".join(li)
33、請分別描述python2.x和python3.x中import包時的路徑搜索順序
import sys
sys.path # 查看搜索路徑
34、用Python的正則表達式匹配時間信息。
import re
data_info = "現在的時間是:2018-3-10 11:52"
regex = r"\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{2}"
ret = re.search(regex,data_info).group
print(ret)
35、使用python編寫一個裝飾器,打印被裝飾函數的輸入與輸出。
from functools import wraps
def print_io(func):
@wraps(func)
def inner(*args,**kwargs):
print("函數的輸入:{}".format(*args,**kwargs))
ret = func(*args,**kwargs)
print("函數的輸出:{}".format(ret))
return ret
return inner
36、闡述range和xrange的區別,並且用Python仿寫xrange函數。Python 2.x 中:
range 函數說明:range([start,] stop[, step]),根據start與stop指定的范圍以及step設定的步長,生成一個序列。
xrange 函數說明:用法與range完全相同,所不同的是生成的不是一個數組,而是一個生成器。 python 3.x中:
已經將xrange函數刪除,range函數同Python2.x 中的xrange函數用法相同
def xrange(*args,**kwargs):
for i in range(*args,**kwargs):
yield i
37、列舉幾種你曾經常用的python包並且解釋其功能及用法
os模塊:os模塊包裝了不同操作系統的通用接口,使用戶在不同操作系統下,可以使用相同的函數接口,返回相同結構的結果。
sys模塊:給命令行傳參
time、re、requests...
# 我覺得這個題的根據要應聘的崗位填一些對應的模塊,比方說爬蟲方向就寫requests,lxml,selenium...
38、合並列表a=[1,2,3,4]和b=[5,6,7,8]
a.extend(b)
39、列表a,請寫出實現正序排列,倒序排列,逆序排列的內置方法。
# 正序
a.sort()
# 倒序
a.sort(reverse=Ture)
# 逆序
a.reverse()
40、字典d={"k":1,"v":2},請寫出d.items()的結果。
dict_items([("k",1),("v",2)])
41、復雜列表[{"k":1,"v":2},{"k":12,"v":22},{"k":13,"v":32}],請用內置方法寫出k的倒序排列的代碼。
li = [{"k":1,"v":2},{"k":12,"v":22},{"k":13,"v":32}]
li.sort(key=lambda dict:dict["k"],reverse=True)
print(li)
42、集合s = set([1,2,3,4]),d = set([2,4,9,0,3]),請用內置方法寫出它們的並集,交集,對稱公差。
# 交集
s|d # {2, 3, 4}
# 並集
s&d # {0, 1, 2, 3, 4, 9}
# 對稱差集
s^d # {0, 1, 9}
43、請隨機輸出一個大於0小於1的數;請隨機輸出一個100以內的整數。
import random
print(random.random()) # 0<1
print(random.randint(1,100)) # 100以內整數
44、長度未知的元組a=(1,3,4,5,6,...),請隨機輸出n項
import random
a=(1,3,4,5,6,...)
a = list(a)
for i in range(n):
b = a[random.randint(0,len(a))-1]
print(b)
a.remove(b)。
45、代碼a=[{i:j} for i,j in enumerate(range(5))],請寫出a的最終結果。
a = [{0:0},{1:1},{2:2},{3:3},{4:4}]
# enumerate()函數:枚舉、列舉,返回一個可迭代對象的索引和索引對應的值
46、分別說說cmp,map,filter的作用?
# cmp:compare比較
cmp(a,b) # a<b 返回-1 a>b 返回1 a=b返回0
# map:映射
map(function, iterable) # 將function作用於iterable,每個元素,將對應輸出結果保存為一個list
# 例:
def plus_one(x):
return x+1
map(plus_one,[1,2,3,4]) ===>[2,3,4,5]
# filter:過濾器
filter(function, iterable) # 將 function依次作用於iterable的每個元素,如果返回值為true, 保留元素,否則從iterable里面刪除
# 例:
def bigger_than_three(x):
return (x>3)
filter(bigger_than_three,[1,2,3,4,5]) ===>[4,5]
47、請闡述__new__和__init__的區別?
__new__:創建對象時調用,會返回當前對象的一個實例
__init__:創建完對象后調用,對當前對象的一些實例初始化,無返回值
調用順序:先調用__new__生成一個實例再調用__init__方法對實例進行初始化,比如添加屬性。
48、寫一段代碼實現單例模式。
class Singleton(object):
def __new__(cls):
# 關鍵在於這,每一次實例化的時候,我們都只會返回這同一個instance對象
if not hasattr(cls, 'instance'):
cls.instance = super(Singleton, cls).__new__(cls)
return cls.instance
49、用yield寫出一個生成器。
def generator():
for i in range(5):
yield i
50、說明os、sys模塊不同,並列舉常用的模塊方法。https://www.cnblogs.com/mako/p/4890676.html
51、@classmethod、@staticmethod、@property都是啥意思?
@classmethod:類方法,類方法是給類用的,類在使用時會將類本身當做參數傳給類方法的第一個參數,python為我們內置了函數classmethod來把類中的函數定義成類方法。
@staticmethod:靜態方法
@property:將一個實例方法提升為屬性,便於訪問
52、請解釋一下Gevent和threading/multiprocessing的關系。
53、請解釋一下cookie和session的關系,以及csrf的攻擊和防范方法。
cookie保存在瀏覽器端,session保存在服務器端,但是為了區分不同的客戶端,服務器會在瀏覽器中發送一個對應的sessionid保存到cookies中,下次瀏覽器請求服務器的時候會將sessionid一並發送給服務器。所以session機制依賴於cookie機制。
csrf攻擊:cross site request forgery 跨站請求偽造
原理:
1.User(C)訪問信任網站Web(A),Web(A)會在User(C)處設置A的cookie;
2.User(C) 在沒有登錄A的情況下,訪問危險網站Web(B),B要求User(C)訪問Web(A);
3.User(C)在Web(B)的要求下,帶着Web(A)的cookie訪問Web(A),這樣Web(B)就達到了模擬用戶操作的目的
防御:
1.通過 referer、token 或者 驗證碼 來檢測用戶提交。
2.盡量不要在頁面的鏈接中暴露用戶隱私信息。
3.對於用戶修改刪除等操作最好都使用post 操作 。
4.避免全站通用的cookie,嚴格設置cookie的域。
54、描述對super,pass,yield,lambda關鍵字修飾的理解。
- super:在繼承中充當父類的代理對象,在多繼承中,super的調用順序是MRO的順序。
- pass:空語句,什么也不做,在特別的時候用來保證格式或是語義的完整性。
- yield:
- 1.保存當前運行狀態(斷點),然后暫停執行,即將函數掛起
- 2.將yeild關鍵字后面表達式的值作為返回值返回,此時可以理解為起到了return的作用,當使用next()、send()函數讓函數從斷點處繼續執行,即喚醒函數。
- lambda:定義匿名函數