1. 程式人生 > >python 面試題(基礎篇) 一 +手打答案整理---------玉米都督

python 面試題(基礎篇) 一 +手打答案整理---------玉米都督

 為什麼學習Python?

1.python是一門程式語言,它的語法簡單,優雅,編寫程式容易閱讀

2.跨平臺,可以在window、Linux、以及MacOs上執行

3.易於學習,站在非專業的角度上來講,如果把程式語言做解決問題的工具,python相較於C++、Java等語言來說易於學習和掌握。

4.極為強大而豐富的標準庫和第三方庫,比如:電子郵件、GUI介面等

5.python主要是以面向物件程式設計的語言。

什麼是面向物件?記得刷知乎時看到有人舉了一個簡單粗暴的例子:

狗.吃屎()  這樣型別就是面向物件。  後面的python日記中會覆蓋有面向物件的例子。



Python的缺點:

相較於C、C++、Java執行效率較慢

因為python屬於解釋型語言(相對編譯語言)

解釋型語言可以理解為執行就需要編譯。

簡述解釋型和編譯型程式語言

解釋型語言編寫的程式不需要編譯,在執行的時候,專門有一個直譯器能夠將VB語言翻譯成機器語言,每個語句都是執行的時候才翻譯。這樣解釋型語言每執行一次就要翻譯一次,效率比較低。


用編譯型語言寫的程式執行之前,需要一個專門的編譯過程,通過編譯系統,把源高階程式編譯成為機器語言檔案,翻譯只做了一次,執行時不需要翻譯,所以編譯型語言的程式執行效率高,但也不能一概而論,

部分解釋型語言的直譯器通過在執行時動態優化程式碼,甚至能夠使解釋型語言的效能超過編譯型語言。

Python直譯器種類以及特點

CPython

當 從Python官方網站下載並安裝好Python2.7後,就直接獲得了一個官方版本的直譯器:Cpython,這個直譯器是用C語言開發的,所以叫 CPython,在命名行下執行python,就是啟動CPython直譯器,CPython是使用最廣的Python直譯器。

IPython

IPython是基於CPython之上的一個互動式直譯器,也就是說,IPython只是在互動方式上有所增強,但是執行Python程式碼的功能和CPython是完全一樣的,好比很多國產瀏覽器雖然外觀不同,但核心其實是呼叫了IE。

PyPy

PyPy是另一個Python直譯器,它的目標是執行速度,PyPy採用JIT技術,對Python程式碼進行動態編譯,所以可以顯著提高Python程式碼的執行速度。

Jython

Jython是執行在Java平臺上的Python直譯器,可以直接把Python程式碼編譯成Java位元組碼執行。

IronPython

IronPython和Jython類似,只不過IronPython是執行在微軟.Net平臺上的Python直譯器,可以直接把Python程式碼編譯成.Net的位元組碼。

在Python的直譯器中,使用廣泛的是CPython,對於Python的編譯,除了可以採用以上直譯器進行編譯外,技術高超的開發者還可以按照自己的需求自行編寫Python直譯器來執行Python程式碼,十分的方便!

請至少列舉5個 PEP8 規範

一 程式碼編排
1 縮排。4個空格的縮排(編輯器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格。
2 每行最大長度79,換行可以使用反斜槓,最好使用圓括號。換行點要在操作符的後邊敲回車。
3 類和top-level函式定義之間空兩行;類中的方法定義之間空一行;函式內邏輯無關段落之間空一行;其他地方儘量不要再空行。

二 文件編排
1 模組內容的順序:模組說明和docstring—import—globals&constants—其他定義。其中import部分,又按標準、三方和自己編寫順序依次排放,之間空一行。
2 不要在一句import中多個庫,比如import os, sys不推薦。
3 如果採用from XX import XX引用庫,可以省略‘module.’,都是可能出現命名衝突,這時就要採用import XX。

三 空格的使用
        總體原則,避免不必要的空格。
1 各種右括號前不要加空格。
2 逗號、冒號、分號前不要加空格。
3 函式的左括號前不要加空格。如Func(1)。
4 序列的左括號前不要加空格。如list[2]。
5 操作符左右各加一個空格,不要為了對齊增加空格。
6 函式預設引數使用的賦值符左右省略空格。
7 不要將多句語句寫在同一行,儘管使用‘;’允許。
8 if/for/while語句中,即使執行語句只有一句,也必須另起一行。

四 註釋
        總體原則,錯誤的註釋不如沒有註釋。所以當一段程式碼發生變化時,第一件事就是要修改註釋!
        註釋必須使用英文,最好是完整的句子,首字母大寫,句後要有結束符,結束符後跟兩個空格,開始下一句。如果是短語,可以省略結束符。
1 塊註釋,在一段程式碼前增加的註釋。在‘#’後加一空格。段落之間以只有‘#’的行間隔。比如:
# Description : Module config.
# 
# Input : None
#
# Output : None
2 行註釋,在一句程式碼後加註釋。比如:x = x + 1	# Increment x
但是這種方式儘量少使用。
3 避免無謂的註釋。

五 文件描述
1 為所有的共有模組、函式、類、方法寫docstrings;非共有的沒有必要,但是可以寫註釋(在def的下一行)。
2 如果docstring要換行,參考如下例子,詳見PEP 257
"""Return a foobang

Optional plotz says to frobnicate the bizbaz first.

"""

六 命名規範
        總體原則,新編程式碼必須按下面命名風格進行,現有庫的編碼儘量保持風格。
1 儘量單獨使用小寫字母‘l’,大寫字母‘O’等容易混淆的字母。
2 模組命名儘量短小,使用全部小寫的方式,可以使用下劃線。
3 包命名儘量短小,使用全部小寫的方式,不可以使用下劃線。
4 類的命名使用CapWords的方式,模組內部使用的類採用_CapWords的方式。
5 異常命名使用CapWords+Error字尾的方式。
6 全域性變數儘量只在模組內有效,類似C語言中的static。實現方法有兩種,一是__all__機制;二是字首一個下劃線。
7 函式命名使用全部小寫的方式,可以使用下劃線。
8 常量命名使用全部大寫的方式,可以使用下劃線。
9 類的屬性(方法和變數)命名使用全部小寫的方式,可以使用下劃線。
9 類的屬性有3種作用域public、non-public和subclass API,可以理解成C++中的public、private、protected,non-public屬性前,字首一條下劃線。
11 類的屬性若與關鍵字名字衝突,字尾一下劃線,儘量不要使用縮略等其他方式。
12 為避免與子類屬性命名衝突,在類的一些屬性前,字首兩條下劃線。比如:類Foo中宣告__a,訪問時,只能通過Foo._Foo__a,避免歧義。如果子類也叫Foo,那就無能為力了。
13 類的方法第一個引數必須是self,而靜態方法第一個引數必須是cls。

七 編碼建議
1 編碼中考慮到其他python實現的效率等問題,比如運算子‘+’在CPython(Python)中效率很高,都是Jython中卻非常低,所以應該採用.join()的方式。
2 儘可能使用‘is’‘is not’取代‘==’,比如if x is not None 要優於if x。
3 使用基於類的異常,每個模組或包都有自己的異常類,此異常類繼承自Exception。
4 異常中不要使用裸露的except,except後跟具體的exceptions。
5 異常中try的程式碼儘可能少。比如:
try:
value = collection[key]
except KeyError:
return key_not_found(key)
else:
return handle_value(value)
要優於
try:
# Too broad!
return handle_value(collection[key])
except KeyError:
# Will also catch KeyError raised by handle_value()
return key_not_found(key)
6 使用startswith() and endswith()代替切片進行序列字首或字尾的檢查。比如:
Yes: if foo.startswith('bar'):優於
No: if foo[:3] == 'bar':
7 使用isinstance()比較物件的型別。比如
Yes: if isinstance(obj, int): 優於
No: if type(obj) is type(1):
8 判斷序列空或不空,有如下規則
Yes: if not seq:
if seq:
優於
No: if len(seq)
if not len(seq)
9 字串不要以空格收尾。
10 二進位制資料判斷使用 if boolvalue的方式。

通過程式碼實現如下轉換:

二進位制轉換成十進位制:v = “0b1111011”

十進位制轉換成二進位制:v = 18
 
八進位制轉換成十進位制:v = “011”
 
十進位制轉換成八進位制:v = 30
 
十六進位制轉換成十進位制:v = “0x12”
 
十進位制轉換成十六進位制:v = 87

v = '0b1111011'
v = int(v,2)
#int  第一個引數接收變數,第二個引數接收 進位制數,


v = 18
v = bin(v)
#bin()  十進位制轉換二進位制 

ascii、unicode、utf-8、gbk 區別

ascii 是最早美國用的標準資訊交換碼,把所有的字母的大小寫,各種符號用 二進位制來表示,共有256中,加入些拉丁文等字元,1bytes代表一個字元,

Unicode是為了統一世界各國語言的不用,統一用2個bytes代表一個字元,可以表達2**16=65556個,稱為萬國語言,特點:速度快,但浪費空間,

可以用在記憶體處理中,相容了utf-8,gbk,ASCII,

utf-8 為了改變Unicode的這種缺點,規定1個英文字元用1個位元組表示,1箇中文字元用3個位元組表示,特點;節省空間,速度慢,用在硬碟資料傳輸,網路資料傳輸,相比硬碟和網路速度,體現不出來的,

gbk  是中文的字元編碼,用2個位元組代表一個字元,

列舉 Python2和Python3的區別

內容太多,貼連結  https://www.cnblogs.com/meng-wei-zhi/articles/8194849.html

 

 

用一行程式碼實現數值交換:
     
 a = 1
 
     b = 2

a,b = b,a

 

xrange和range的區別

range 前面小節已經說明了,range([start,] stop[, step]),根據start與stop指定的範圍以及step設定的步長,生成一個序列。

比如:


>>> range(5)

[0, 1, 2, 3, 4]

>>> range(1,5)

[1, 2, 3, 4]

>>> range(0,6,2)
[0, 2, 4]
xrange 用法與 range 完全相同,所不同的是生成的不是一個list物件,而是一個生成器。


>>> xrange(5)

xrange(5)

>>> list(xrange(5))

[0, 1, 2, 3, 4]

>>> xrange(1,5)

xrange(1, 5)

>>> list(xrange(1,5))

[1, 2, 3, 4]

>>> xrange(0,6,2)

xrange(0, 6, 2)

>>> list(xrange(0,6,2))

[0, 2, 4]
由上面的示例可以知道:要生成很大的數字序列的時候,用xrange會比range效能優很多,因為不需要一上來就開闢一塊很大的記憶體空間。

xrange 和 range 這兩個基本上都是在迴圈的時候用。


for i in range(0, 100):

    print i

 

for i in xrange(0, 100):

    print i
這兩個輸出的結果都是一樣的,實際上有很多不同,range會直接生成一個list物件:


a = range(0,100)

print type(a)

print a

print a[0], a[1]
輸出結果:


<type 'list'>

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
3

而xrange則不會直接生成一個list,而是每次呼叫返回其中的一個值:


a = xrange(0,100)

print type(a)

print a

print a[0], a[1]
輸出結果:


<type 'xrange'>

xrange(100)
0 1

字串、列表、元組、字典每個常用的5個方法

內容太多  https://blog.csdn.net/qq_39443687/article/details/81940264

 

lambda表示式格式以及應用場景

#普通函式
def func(a):
    return a+1
print 'test1_func0:',func(1000)

#lambda表示式 
func0 = lambda a:a+1
print 'test2_func0:',func0(1000)
複製程式碼
上面這種方法,都實現了將1000+1的結果打印出來這個功能,但是用下面

lambda存在意義就是對簡單函式的簡潔表示。

說道lambda,這裡再贈送一些可以給lambda加buff小夥伴:

1.map函式,我們使用map函式將會對列表中的所有元素進行操作。map有兩個引數(函式,列表),它會在內部遍歷列表中的每一個元素,執行傳遞過來的函式引數。在輸出到新列表中。

li = [11, 22, 33]
new_list = map(lambda a: a + 100, li)
輸出:[111, 122, 133]
當然,map還可以完成多個數組的相加:

li = [11, 22, 33]
sl = [1, 2, 3]
new_list = map(lambda a, b: a + b, li, sl)
print new_list
輸出:[12, 24, 36]
2.reduce函式,對於序列內所有元素進行累計操作:

lst = [11,22,33]
func2 = reduce(lambda arg1,arg2:arg1+arg2,lst)
print 'func2:',func2
輸出:func2: 66
3.filter函式,他可以根據條件對資料進行過濾:

li = [11, 22, 33]
new_list = filter(lambda arg: arg > 22, li)
print new_list
輸出:[33]