今天繼續分享 Python 相關的面試題,在學習的路上,與君共勉,個人文采好棒哦!html
基礎篇(二) 第一部分能夠在這裏查看(我是超連接)python
print("This is for %s" % "Python")
print("This is for %s, and %s" %("Python", "You"))
複製代碼
outputweb
This is for Python
This is for Python, and You
複製代碼
在 Python3 中,引入了這個新的字符串格式化方法。面試
print("This is my {}".format("chat"))
print("This is {name}, hope you can {do}".format(name="zhouluob", do="like"))
複製代碼
output正則表達式
This is my chat
This is zhouluob, hope you can like
複製代碼
在 Python3-6 中,引入了這個新的字符串格式化方法。數據庫
name = "luobodazahui"
print(f"hello {name}")
複製代碼
output編程
hello luobodazahui
複製代碼
一個複雜些的例子:json
def mytest(name, age):
return f"hello {name}, you are {age} years old!"
people = mytest("luobo", 20)
print(people)
複製代碼
outputflask
hello luobo, you are 20 years old!
複製代碼
str1 = "hello world"
print(str1.title())
" ".join(list(map(lambda x: x.capitalize(), str1.split(" "))))
複製代碼
outputapi
Hello World
'Hello World'
複製代碼
如:[1, 2, 3] -> ["1", "2", "3"]
list1 = [1, 2, 3]
list(map(lambda x: str(x), list1))
複製代碼
output
['1', '2', '3']
複製代碼
如:("zhangfei", "guanyu"),(66, 80) -> {'zhangfei': 66, 'guanyu': 80}
a = ("zhangfei", "guanyu")
b = (66, 80)
dict(zip(a,b))
複製代碼
output
{'zhangfei': 66, 'guanyu': 80}
複製代碼
例子1:
a = (1,2,3,[4,5,6,7],8)
a[3] = 2
複製代碼
output
TypeError Traceback (most recent call last)
<ipython-input-35-59469d550eb0> in <module>
1 a = (1,2,3,[4,5,6,7],8)
----> 2 a[3] = 2
3 #a
TypeError: 'tuple' object does not support item assignment
複製代碼
例子2:
a = (1,2,3,[4,5,6,7],8)
a[3][2] = 2
a
複製代碼
output
(1, 2, 3, [4, 5, 2, 7], 8)
複製代碼
從例子1的報錯中也能夠看出,tuple 是不可變類型,不能改變 tuple 裏的元素,例子2中,list 是可變類型,改變其元素是容許的。
反射就是經過字符串的形式,導入模塊;經過字符串的形式,去模塊尋找指定函數,並執行。利用字符串的形式去對象(模塊)中操做(查找/獲取/刪除/添加)成員,一種基於字符串的事件驅動!
簡單理解就是用來判斷某個字符串是什麼,是變量仍是方法
class NewClass(object):
def __init__(self, name, male):
self.name = name
self.male = male
def myname(self):
print(f'My name is {self.name}')
def mymale(self):
print(f'I am a {self.male}')
people = NewClass('luobo', 'boy')
print(hasattr(people, 'name'))
print(getattr(people, 'name'))
setattr(people, 'male', 'girl')
print(getattr(people, 'male'))
複製代碼
output
True
luobo
girl
複製代碼
getattr,hasattr,setattr,delattr 對模塊的修改都在內存中進行,並不會影響文件中真實內容。
使用 flask 構造 web 服務器
from flask import Flask, request
app = Flask(__name__)
@app.route('/', methods=['POST'])
def simple_api():
result = request.get_json()
return result
if __name__ == "__main__":
app.run()
複製代碼
類與實例: 首先定義類之後,就能夠根據這個類建立出實例,因此:先定義類,而後建立實例。 類與元類: 先定義元類, 根據 metaclass 建立出類,因此:先定義 metaclass,而後建立類。
class MyMetaclass(type):
def __new__(cls, class_name, class_parents, class_attr):
class_attr['print'] = "this is my metaclass's subclass %s" %class_name
return type.__new__(cls, class_name, class_parents, class_attr)
class MyNewclass(object, metaclass=MyMetaclass):
pass
myinstance = MyNewclass()
myinstance.print
複製代碼
output
"this is my metaclass's subclass MyNewclass"
複製代碼
sort() 是可變對象列表(list)的方法,無參數,無返回值,sort() 會改變可變對象.
dict1 = {'test1':1, 'test2':2}
list1 = [2, 1, 3]
print(list1.sort())
list1
複製代碼
output
None
[1, 2, 3]
複製代碼
sorted() 是產生一個新的對象。sorted(L) 返回一個排序後的L,不改變原始的L。sorted() 適用於任何可迭代容器。
dict1 = {'test1':1, 'test2':2}
list1 = [2, 1, 3]
print(sorted(dict1))
print(sorted(list1))
複製代碼
output
['test1', 'test2']
[1, 2, 3]
複製代碼
GIL 是 Python 的全局解釋器鎖,同一進程中假若有多個線程運行,一個線程在運行 Python 程序的時候會佔用 Python 解釋器(加了一把鎖即 GIL),使該進程內的其餘線程沒法運行,等該線程運行完後其餘線程才能運行。若是線程運行過程當中遇到耗時操做,則解釋器鎖解開,使其餘線程運行。因此在多線程中,線程的運行還是有前後順序的,並非同時進行。
import random
"".join(random.choice(string.printable[:-7]) for i in range(8))
複製代碼
output
'd5^NdNJp'
複製代碼
print('hello\nworld')
print(b'hello\nworld')
print(r'hello\nworld')
複製代碼
output
hello
world
b'hello\nworld'
hello\nworld
複製代碼
list1 = [{'name': 'guanyu', 'age':29},
{'name': 'zhangfei', 'age': 28},
{'name': 'liubei', 'age':31}]
sorted(list1, key=lambda x:x['age'])
複製代碼
output
[{'name': 'zhangfei', 'age': 28},
{'name': 'guanyu', 'age': 29},
{'name': 'liubei', 'age': 31}]
複製代碼
all 若是存在 0 Null False 返回 False,不然返回 True;
any 若是都是 0,None,False,Null 時,返回 True。
print(all([1, 2, 3, 0]))
print(all([1, 2, 3]))
print(any([1, 2, 3, 0]))
print(any([0, None, False]))
複製代碼
output
False
True
True
False
複製代碼
def reverse_int(x):
if not isinstance(x, int):
return False
if -10 < x < 10:
return x
tmp = str(x)
if tmp[0] != '-':
tmp = tmp[::-1]
return int(tmp)
else:
tmp = tmp[1:][::-1]
x = int(tmp)
return -x
reverse_int(-23837)
複製代碼
output
-73832
複製代碼
首先判斷是不是整數,再判斷是不是一位數字,最後再判斷是否是負數
函數式編程是一種抽象程度很高的編程範式,純粹的函數式編程語言編寫的函數沒有變量,所以,任意一個函數,只要輸入是肯定的,輸出就是肯定的,這種純函數稱之爲沒有反作用。而容許使用變量的程序設計語言,因爲函數內部的變量狀態不肯定,一樣的輸入,可能獲得不一樣的輸出,所以,這種函數是有反作用的。因爲 Python 容許使用變量,所以,Python 不是純函數式編程語言。
函數式編程的一個特色就是,容許把函數自己做爲參數傳入另外一個函數,還容許返回一個函數!
函數做爲返回值例子:
def sum(*args):
def inner_sum():
tmp = 0
for i in args:
tmp += i
return tmp
return inner_sum
mysum = sum(2, 4, 6)
print(type(mysum))
mysum()
複製代碼
output
<class 'function'>
12
複製代碼
若是在一個內部函數裏,對在外部做用域(但不是在全局做用域)的變量進行引用,那麼內部函數就被認爲是閉包(closure)。
附上函數做用域圖片
閉包特色 1.必須有一個內嵌函數 2.內嵌函數必須引用外部函數中的變量 3.外部函數的返回值必須是內嵌函數
裝飾器是一種特殊的閉包,就是在閉包的基礎上傳遞了一個函數,而後覆蓋原來函數的執行入口,之後調用這個函數的時候,就能夠額外實現一些功能了。 一個打印 log 的例子:
import time
def log(func):
def inner_log(*args, **kw):
print("Call: {}".format(func.__name__))
return func(*args, **kw)
return inner_log
@log
def timer():
print(time.time())
timer()
複製代碼
output
Call: timer
1560171403.5128365
複製代碼
本質上,decorator就是一個返回函數的高階函數
子程序切換不是線程切換,而是由程序自身控制 沒有線程切換的開銷,和多線程比,線程數量越多,協程的性能優點就越明顯 不須要多線程的鎖機制,由於只有一個線程,也不存在同時寫變量衝突,在協程中控制共享資源不加鎖
斐波那契數列: 又稱黃金分割數列,指的是這樣一個數列:一、一、二、三、五、八、1三、2一、3四、……在數學上,斐波納契數列以以下被以遞歸的方法定義:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)
生成器法:
def fib(n):
if n == 0:
return False
if not isinstance(n, int) or (abs(n) != n): # 判斷是正整數
return False
a, b = 0, 1
while n:
a, b = b, a+b
n -= 1
yield a
[i for i in fib(10)]
複製代碼
output
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
複製代碼
遞歸法:
def fib(n):
if n == 0:
return False
if not isinstance(n, int) or (abs(n) != n):
return False
if n <= 1:
return n
return fib(n-1)+ fib(n-2)
[fib(i) for i in range(1, 11)]
複製代碼
output
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
複製代碼
import re
str1 = 'hello world:luobo dazahui'
result = re.split(r":| ", str1)
print(result)
複製代碼
output
['hello', 'world', 'luobo', 'dazahui']
複製代碼
yield 是用來生成迭代器的語法,在函數中,若是包含了 yield,那麼這個函數就是一個迭代器。當代碼執行至 yield 時,就會中斷代碼執行,直到程序調用 next() 函數時,纔會在上次 yield 的地方繼續執行
def foryield():
print("start test yield")
while True:
result = yield 5
print("result:", result)
g = foryield()
print(next(g))
print("*"*20)
print(next(g))
複製代碼
output
start test yield
5
********************
result: None
5
複製代碼
能夠看到,第一個調用 next() 函數,程序只執行到了 "result = yield 5" 這裏,同時因爲 yield 中斷了程序,因此 result 也沒有被賦值,因此第二次執行 next() 時,result 是 None。
list1 = [2, 5, 8, 9, 3, 11]
def paixu(data, reverse=False):
if not reverse:
for i in range(len(data) - 1):
for j in range(len(data) - 1 - i):
if data[j] > data[j+1]:
data[j], data[j+1] = data[j+1], data[j]
return data
else:
for i in range(len(data) - 1):
for j in range(len(data) - 1 - i):
if data[j] < data[j+1]:
data[j], data[j+1] = data[j+1], data[j]
return data
print(paixu(list1, reverse=True))
複製代碼
output
[11, 9, 8, 5, 3, 2]
複製代碼
快排的思想:首先任意選取一個數據(一般選用數組的第一個數)做爲關鍵數據,而後將全部比它小的數都放到它前面,全部比它大的數都放到它後面,這個過程稱爲一趟快速排序,以後再遞歸排序兩邊的數據。
挑選基準值:從數列中挑出一個元素,稱爲"基準"(pivot); 分割:從新排序數列,全部比基準值小的元素擺放在基準前面,全部比基準值大的元素擺在基準後面(與基準值相等的數能夠到任何一邊)。在這個分割結束以後,對基準值的排序就已經完成; 遞歸排序子序列:遞歸地將小於基準值元素的子序列和大於基準值元素的子序列排序。
list1 = [8, 5, 1, 3, 2, 10, 11, 4, 12, 20]
def partition(arr,low,high):
i = ( low-1 ) # 最小元素索引
pivot = arr[high]
for j in range(low , high):
# 當前元素小於或等於 pivot
if arr[j] <= pivot:
i = i+1
arr[i],arr[j] = arr[j],arr[i]
arr[i+1],arr[high] = arr[high],arr[i+1]
return ( i+1 )
def quicksort(arr,low,high):
if low < high:
pi = partition(arr,low,high)
quicksort(arr, low, pi-1)
quicksort(arr, pi+1, high)
quicksort(list1, 0, len(list1)-1)
print(list1)
複製代碼
output
[1, 2, 3, 4, 5, 8, 10, 11, 12, 20]
複製代碼
一個更加簡單的快排寫法
def quick_sort(arr):
if arr == []:
return []
else:
first = arr[0]
left = quick_sort([l for l in arr[1:] if l < first])
right = quick_sort([r for r in arr[1:] if r >= first])
return left + [first] + right
arr = [1, 4, 5, 2, 0, 8, 11, 6]
result = quick_sort(arr)
print(result)
複製代碼
output
[0, 1, 2, 4, 5, 6, 8, 11]
複製代碼
該庫是發起 HTTP 請求的強大類庫,調用簡單,功能強大。
import requests
url = "http://www.luobodazahui.top"
response = requests.get(url) # 得到請求
response.encoding = "utf-8" # 改變其編碼
html = response.text # 得到網頁內容
binary__content = response.content # 得到二進制數據
raw = requests.get(url, stream=True) # 得到原始響應內容
headers = {'user-agent': 'my-test/0.1.1'} # 定製請求頭
r = requests.get(url, headers=headers)
cookies = {"cookie": "# your cookie"} # cookie的使用
r = requests.get(url, cookies=cookies)
複製代碼
dict1 = {"zhangfei": 12, "guanyu": 13, "liubei": 18}
dict2 = {"zhangfei": 12, "guanyu": 13, "liubei": 18}
def compare_dict(dict1, dict2):
issame = []
for k in dict1.keys():
if k in dict2:
if dict1[k] == dict2[k]:
issame.append(1)
else:
issame.append(2)
else:
issame.append(3)
print(issame)
sum_except = len(issame)
sum_actually = sum(issame)
if sum_except == sum_actually:
print("this two dict are same!")
return True
else:
print("this two dict are not same!")
return False
test = compare_dict(dict1, dict2)
複製代碼
output
[1, 1, 1]
this two dict are same!
複製代碼
input() 函數
def forinput():
input_text = input()
print("your input text is: ", input_text)
forinput()
複製代碼
output
hello
your input text is: hello
複製代碼
enumerate() 函數用於將一個可遍歷的數據對象(如列表、元組或字符串)組合爲一個索引序列,同時列出數據和數據下標,通常用在 for 循環當中。
data1 = ['one', 'two', 'three', 'four']
for i, enu in enumerate(data1):
print(i, enu)
複製代碼
output
0 one
1 two
2 three
3 four
複製代碼
pass 是空語句,是爲了保持程序結構的完整性。pass 不作任何事情,通常用作佔位語句。
def forpass(n):
if n == 1:
pass
else:
print('not 1')
forpass(1)
複製代碼
import re
email_list= ["test01@163.com","test02@163.123", ".test03g@qq.com", "test04@gmail.com" ]
for email in email_list:
ret = re.match("[\w]{4,20}@(.*)\.com$",email)
if ret:
print("%s 是符合規定的郵件地址,匹配後結果是:%s" % (email,ret.group()))
else:
print("%s 不符合要求" % email)
複製代碼
output
test01@163.com 是符合規定的郵件地址,匹配後結果是:test01@163.com
test02@163.123 不符合要求
.test03g@qq.com 不符合要求
test04@gmail.com 是符合規定的郵件地址,匹配後結果是:test04@gmail.com
複製代碼
str2 = 'werrQWSDdiWuW'
counter = 0
for i in str2:
if i.isupper():
counter += 1
print(counter)
複製代碼
output
6
複製代碼
普通序列化:
import json
dict1 = {'name': '蘿蔔', 'age': 18}
dict1_new = json.dumps(dict1)
print(dict1_new)
複製代碼
output
{"name": "\u841d\u535c", "age": 18}
複製代碼
保留中文
import json
dict1 = {'name': '蘿蔔', 'age': 18}
dict1_new = json.dumps(dict1, ensure_ascii=False)
print(dict1_new)
複製代碼
output
{"name": "蘿蔔", "age": 18}
複製代碼
一個類繼承自另外一個類,也能夠說是一個孩子類/派生類/子類,繼承自父類/基類/超類,同時獲取全部的類成員(屬性和方法)。
繼承使咱們能夠重用代碼,而且還能夠更方便地建立和維護代碼。
Python 支持如下類型的繼承:
單繼承- 一個子類類繼承自單個基類
多重繼承- 一個子類繼承自多個基類
多級繼承- 一個子類繼承自一個基類,而基類繼承自另外一個基類
分層繼承- 多個子類繼承自同一個基類
混合繼承- 兩種或兩種以上繼承類型的組合
猴子補丁是指在運行時動態修改類和模塊。 猴子補丁主要有如下幾個用處:
help() 函數返回幫助文檔和參數說明:
help(dict)
複製代碼
output
Help on class dict in module builtins:
class dict(object)
| dict() -> new empty dictionary
| dict(mapping) -> new dictionary initialized from a mapping object's | (key, value) pairs | dict(iterable) -> new dictionary initialized as if via: | d = {} | for k, v in iterable: | d[k] = v | dict(**kwargs) -> new dictionary initialized with the name=value pairs | in the keyword argument list. For example: dict(one=1, two=2) ...... 複製代碼
dir() 函數返回對象中的全部成員 (任何類型)
dir(dict)
複製代碼
output
['__class__',
'__contains__',
'__delattr__',
'__delitem__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
......
複製代碼
// 運算符執行地板除法,返回結果的整數部分 (向下取整)
% 是取模符號,返回除法後的餘數
** 符號表示取冪. a**b 返回 a 的 b 次方
print(5//3)
print(5/3)
print(5%3)
print(5**3)
複製代碼
output
1
1.6666666666666667
2
125
複製代碼
使用 raise
def test_raise(n):
if not isinstance(n, int):
raise Exception('not a int type')
else:
print('good')
test_raise(8.9)
複製代碼
output
Exception Traceback (most recent call last)
<ipython-input-262-b45324f5484e> in <module>
4 else:
5 print('good')
----> 6 test_raise(8.9)
<ipython-input-262-b45324f5484e> in test_raise(n)
1 def test_raise(n):
2 if not isinstance(n, int):
----> 3 raise Exception('not a int type')
4 else:
5 print('good')
Exception: not a int type
複製代碼
tuple1 = (1, 2, 3, 4)
list1 = list(tuple1)
print(list1)
tuple2 = tuple(list1)
print(tuple2)
複製代碼
output
[1, 2, 3, 4]
(1, 2, 3, 4)
複製代碼
Python 的斷言就是檢測一個條件,若是條件爲真,它什麼都不作;反之它觸發一個帶可選錯誤信息的 AssertionError。
def testassert(n):
assert n == 2, "n is not 2"
print('n is 2')
testassert(1)
複製代碼
output
AssertionError Traceback (most recent call last)
<ipython-input-268-a9dfd6c79e73> in <module>
2 assert n == 2, "n is not 2"
3 print('n is 2')
----> 4 testassert(1)
<ipython-input-268-a9dfd6c79e73> in testassert(n)
1 def testassert(n):
----> 2 assert n == 2, "n is not 2"
3 print('n is 2')
4 testassert(1)
AssertionError: n is not 2
複製代碼
同步異步指的是調用者與被調用者之間的關係。
所謂同步,就是在發出一個功能調用時,在沒有獲得結果以前,該調用就不會返回,一旦調用返回,就獲得了返回值。
異步的概念和同步相對。調用在發出以後,這個調用就直接返回了,因此沒有返回結果。當該異步功能完成後,被調用者能夠經過狀態、通知或回調來通知調用者。
阻塞非阻塞是線程或進程之間的關係。
阻塞調用是指調用結果返回以前,當前線程會被掛起(如遇到io操做)。調用線程只有在獲得結果以後纔會返回。函數只有在獲得結果以後纔會將阻塞的線程激活。
非阻塞和阻塞的概念相對應,非阻塞調用指在不能馬上獲得結果以前也會馬上返回,同時該函數不會阻塞當前線程。
Python 中的序列是有索引的,它由正數和負數組成。正的數字使用'0'做爲第一個索引,'1'做爲第二個索引,以此類推。
負數的索引從'-1'開始,表示序列中的最後一個索引,' - 2'做爲倒數第二個索引,依次類推。
不是的,那些具備對象循環引用或者全局命名空間引用的變量,在 Python 退出時每每不會被釋放。 另外不會釋放 C 庫保留的部份內容。
Flask 是 「microframework」,主要用來編寫小型應用程序,不過隨着 Python 的普及,不少大型程序也在使用 Flask。同時,在 Flask 中,咱們必須使用外部庫。
Django 適用於大型應用程序。它提供了靈活性,以及完整的程序框架和快速的項目生成方法。能夠選擇不一樣的數據庫,URL結構,模板樣式等。
import os
f = open('test.txt', 'w')
f.close()
os.listdir()
os.remove('test.txt')
複製代碼
logging 模塊是 Python 內置的標準模塊,主要用於輸出運行日誌,能夠設置輸出日誌的等級、日誌保存路徑、日誌文件回滾等;相比 print,具有以下優勢:
import logging
logging.debug("debug log")
logging.info("info log")
logging.warning("warning log")
logging.error("error log")
logging.critical("critica log")
複製代碼
output
WARNING:root:warning log
ERROR:root:error log
CRITICAL:root:critica log
複製代碼
默認狀況下,只顯示了大於等於WARNING級別的日誌。logging.basicConfig()函數調整日誌級別、輸出格式等。
from collections import Counter
str1 = "nihsasehndciswemeotpxc"
print(Counter(str1))
複製代碼
output
Counter({'s': 3, 'e': 3, 'n': 2, 'i': 2, 'h': 2, 'c': 2, 'a': 1, 'd': 1, 'w': 1, 'm': 1, 'o': 1, 't': 1, 'p': 1, 'x': 1})
複製代碼
re.compile 是將正則表達式編譯成一個對象,加快速度,並重復使用。
try..except..else 沒有捕獲到異常,執行 else 語句 try..except..finally 不論是否捕獲到異常,都執行 finally 語句
使用 re 正則替換
import re
str1 = '我是周蘿蔔,今年18歲'
result = re.sub(r"\d+","20",str1)
print(result)
複製代碼
output
我是周蘿蔔,今年20歲
複製代碼
面試題系列第二部分就到這裏了,咱們下次見!
歡迎關注個人微信公衆號--蘿蔔大雜燴,或者掃描下方的二維碼,你們一塊兒交流,學習和進步!