面試題-python基礎

1、Python基礎python

一、什麼是python?使用python有什麼好處?mysql

python是一種編程語言,它有對象、模塊、線程、異常處理和自動內存管理。它簡潔,簡單、方便、容易擴展、有許多自帶的數據結果,並且它開源linux

Python是一種解釋性語言,它的源代碼能夠直接運行,Python解釋器會將源代碼轉換成中間語言,以後再翻譯成機器碼再執行redis

二、可變類型與不可變類型算法

可變類型:list、dict、可變集合setsql

不可變類型:數字,str,tuple元組,frozenset數據庫

內存中的那塊內容(value)是否可變編程

可直接在原來的地址,修改設計模式

不可變的類型均可以被hash哈希數組

三、深淺copy

對不可變類型進行copy的話,都是深copy

對於可變類型進行copy的話,通常都是淺copy

淺拷貝只是增長了一個指針指向所複製的對象,共用一塊內存

深拷貝是增長一個指針而且開闢了新的內存,這個增長的指針指向這個新的內存,

In [42]: li = [1,2,3,[4,5]]
In [43]: li2 = copy.copy(li)
In [44]: li3 = copy.deepcopy(li)


In [45]: li[-1][-1] = "222"
    
In [46]: li
Out[46]: [1, 2, 3, [4, '222']]

In [47]: li2
Out[47]: [1, 2, 3, [4, '222']]

In [48]: li3
Out[48]: [1, 2, 3, [4, 5]]

簡單來講,若是有嵌套的話,淺copy只複製第一層,深copy會複製全部的

四、range-and-xrange

py2:
        range() 生成的是列表
        xrange() 生成的是一個生成器 
    py3:
        range() 就是一個生成器
        xrange() 沒了

五、閉包

def func():
    
    def inner():
        print('aaaa')  
        
    return inner

func()()  # aaaa

內部函數對外部函數做用域裏變量的引用(非全局變量),則稱內部函數爲閉包。

閉包的意義:返回函數對象+一層做用域,這使得,該函數不管在何處調用,優先使用本身外層包裹的做用域

六、裝飾器

調用裝飾器實際上是一個閉包函數,

不修改函數的代碼與修飾方式,爲其餘函數添加附加功能

好比:插入日誌、性能測試、事物處理、緩存、權限驗證等

# 裝飾器
import time
def login(func):
    def inner():
        start_time = time.time()
        func()
        end_time = time.time()
        print("fun 執行時間",end_time-start_time)
    return inner

@login
def test():
    for i in range(10000):
        for j in range(10000):
            pass
    print('test函數執行')

test()
# test函數執行
# fun 執行時間 2.0163347721099854

七、生成器

延遲操做,須要的時候才產生結果,而不是當即產生結果

在每次調用next()的時候執行,遇到yield語句返回

建立生成器的兩種方式:

li = [i for i in range(100)]、yield方法

八、迭代器

for循環的數據類型:集合數據類型+生成器

list,tuple,dict,set,str + generator

不是一次性把數據加載到內存,而是被next()函數調用,不斷返回下一個數據

九、*args與**kwargs

*args:位置參數 ('alex',18)

**kwargs:關鍵字參數 {'name'='alex','age'=18} 關鍵字參數必定要放在最後面

2、面向對象

一、經典類、新式類

經典類:深度優先,python2中

新式類:廣度優先,Python3中

二、繼承、多態、封裝

(1)繼承:類與類之間關係,Cat類是動物類,解決代碼重用問題

重用 父類的屬性與方法

def __init__(self, name, life_value, aggresivity, weapon):
        super().__init__(name, life_value, aggresivity,)        # python3格式
        self.weapon = weapon

 def attack(self, enemy):
       super().attack(enemy)

(2)多態:同一類事物多種形態

一個接口,多種形態

不該關注對象的類型自己,而是它如何使用的

鴨子類型:若是看起來像、叫聲像並且走起路來像鴨子,那麼它就是鴨子’

(3)封裝

私有化的屬性,私有化的方法,封裝起來,外部沒法調用 雙下劃線__foo

三、classmethod,staticmethod,property

(1)property:特性 (統一訪問 原則)

@property
    def bmi(self):
        return self.weight / (self.height ** 2)

把類的方法轉換爲屬性,直接 alex.bmi 調用

(2)staticmethod 靜態方法 (普通函數 ) 綁定到對象上

類內的函數實例化---> 普通函數 。 (類和對象均可以使用)

@classmethod
    def from_conf(cls):
        obj = settings.name,
        return obj

(3)classmethod 類方法 (def foo(cls)) 綁定到類上

將cls 類自己當作參數傳入,直接用類來調用函數,而不用藉助類實例

優雅地實現某個類的實例的構造

四、 new.init區別,如何實現單例模式

建立一個新實例時調用new new()在 init()以前被調用

初始化一個實例時調用init

單例模式設計的類只能實例化1個對象

# 方式1 python模板自帶單例模式
# admin.py

class Admin(object):
    def register(self):
        pass

site = Admin()

# test.py
from admin import site
site.register()

# 方式2  __new__  _instance
class Single(object):
    _instance = None
    def __new__(cls,*args,**kwargs):
        if not cls._instance:
            cls._instance = super(Single,cls).__new__(cls,*args,**kwargs)
            
        return cls._instance

五、反射

「字符串」形式,操做對象的相關屬性或方法。

hasattr, getattr, setattr, delattr

ret = getattr(obj,'get_file')()       # 反射  obj是實例對象,name是方法

3、併發

一、線程、進程的區別

(1)進程:程序的運行過程, os 資源調度、分配的基本單位 os的併發

(2)線程:進程的實體, cpu 調度、分派的基本單位 進程內部的併發

區別

一、進程有獨立的內存空間, 線程 共享 本進程 的內存空間

二、進程有獨立的系統資源 ,線程只有(程序計數器,一組寄存器,棧) 共享本進程的資源(內存,I/O,cpu)

三、獨立性:進程崩潰,不會影響其餘的(健壯) 線程崩潰,本進程的所有線程死掉

四、開銷:進程切換與建立 開銷大於 線程的

五、線程不能獨立執行 進程能夠

聯繫

均可併發、一個進程由1or多個線程 組成、一個進程中的全部線程共享該進程所有資源

二、協程、GIL

GIL:全局解釋器鎖(cpython解釋器), 同一時刻,在cpu只能有一個線程執行

協程:輕量級的線程,用戶控制調度的

單線程下(的併發), 遇到I/O阻塞,多個任務,自動切換

三、進程同步方式

一、Event事件 。 通知操做

二、互斥量。 加鎖

三、信號量。 生產者消費者模型 阻塞隊列Queue

四、臨界區 。保護區域

同步問題:生產者消費者模型,做者讀者問題,哲學家進餐問題

四、通訊方式

管道,系統IPC(消息隊列,信號量,信號,共享內存),套接字,遠程過程調用rpc

五、死鎖

多個進程運行,爭奪資源,一種僵局;沒有外力,進程,沒法繼續執行

致使死鎖的緣由:循環等待、不可搶佔、佔有且等待、互斥

死鎖處理:

一、預防 :破壞4個條件

二、避免:銀行家算法

三、檢測:算法檢測,清除死鎖

四、解除: 檢測到,撤銷進程or剝奪資源

六、select、poll和epoll (I/O多路複用)

能夠監視多個描述符

一個描述符就緒,通知應用程序,執行讀or寫操做

(1)select :

把文件描述符 fd 集合maxSize=1024,用戶態copy到內核態 開銷大,在內核,遍歷全部fd

(2)poll:

改善了鏈接數,不斷輪詢,fd集合 每次都copy到內核態

(3)epoll:

linux下的多路複用I/O接口, 只copy一次,只告知 ,剛變爲就緒狀態的fd

4、mysql數據庫

一、索引

B+數:二叉樹-->平衡二叉樹-->B數

一個排序好,數據結構 (協助快速查詢data) 範圍查詢

create index ix_age on t1(age);
create index 索引名1,索引名2 on 表名('字段1','字段2')

(1)何時用?

常常 select查詢、表記錄超多

常常須要搜索的列、主鍵列、鏈接的列(外鍵)、範圍查找 age in [20,40]、排序的列 salary、where上的列

(2)何時不用?

常常update,delete,insert 表記錄少

不常用的列 addr,數據值不多的列 blog,文本,image,bit 修改>查詢的

二、存儲過程

至關於 函數,封裝了,一系列,可執行的sql語句,存放在mysql中

直接調用它的名稱

create procedure p1()
BEGIN
    select * from blog;
    INSERT into blog(name,sub_time) values("xxx",now());
END

優勢:網絡傳輸量小,程序與slq解耦

缺點:程序猿拓展功能不方便

三、數據庫引擎

INNODB 支持事務,外鍵,行鎖, 查表總行數,全表掃描

MYISAM不支持事務,不支持外鍵,表鎖(插入data,鎖定這個表),查表總行數,不須要全表掃描

四、redis

key-value數據庫 ,常常用的data放在redis

性能極高,支持多種數據類型 ,放在內存中 (必要時能夠寫入硬盤)

5、網絡

一、http經常使用的狀態碼

200:請求成功 OK

202:服務器接受請求,還沒有處理

302:重定向

304  :上次的文檔,已被緩存, 還可繼續使用

400:客戶端請求語法or參數錯誤

403:服務器收到請求,拒絕提供服務,找不到cookie

404:客戶端請求的資源url不存在

500: 服務器的程序出現錯誤

503:服務器當前時間不能處理客戶端的請求,一段時間後恢復

二、HTTP請求方式

HTTP1.0 GET/HEAD/POST

HTTP1.1 PUT/DELETE/CONNECT/OPTIONS/TRACE

3.GET/POST區別

(1)get提交的數據放在url後 /?name=alex&age=18 http請求頭

post的數據放在http報請求體

(2)GET的數據大小有限制,POST沒有限制

(3)GET方式會帶來安全問題,在url出現信息,可能得到username password

(4)在服務端 獲取請求數據方式不一樣

四、http請求頭,請求體

協議版本,狀態碼,狀態碼緣由 HTTP /1.1 200 OK

Cookie:

Content-Language

Content-Type 文本類型

Content-Length 請求體長度

User-Agent: 瀏覽器的身份標識,類型,手機端or電腦端

Date:時間

請求體

五、TCP/UDP區別 (運輸層)

一、TCP 傳輸控制協議,面向鏈接的,可靠的,數據流傳輸 ,注重data安全性,傳輸慢,面向字節流

二、UDP用戶數據報文協議,非面向鏈接的,不可靠,數據流傳輸, data傳輸快,安全性通常,面向報文

python部分

四、深淺拷貝

淺拷貝只是增長了一個指針指向一個存在的地址,
深拷貝是增長一個指針而且開闢了新的內存,這個增長的指針指向這個新的內存,
簡單地說,淺拷貝只拷貝一層(若是有嵌套),深拷貝拷貝全部層。

In [42]: li = [1,2,3,[4,5]]
In [43]: li2 = copy.copy(li)
In [44]: li3 = copy.deepcopy(li)


In [45]: li[-1][-1] = "222"
    
In [46]: li
Out[46]: [1, 2, 3, [4, '222']]

In [47]: li2
Out[47]: [1, 2, 3, [4, '222']]

In [48]: li3
Out[48]: [1, 2, 3, [4, 5]]
七、閉包
內部函數對外部函數做用域裏變量的引用(非全局變量),則稱內部函數爲閉包。

閉包的意義:返回的函數對象,不只僅是一個函數對象,在該函數外還包裹了一層做用域,這使得,該函數不管在何處調用,優先使用本身外層包裹的做用域

def func():
    
    def inner():
        print('aaaa')  
        
    return inner

func()()  # aaaa
六、裝飾器

調用裝飾器實際上是一個閉包函數,爲其餘函數添加附加功能,不修改被修改的源代碼和不修改被修飾的方式,裝飾器的返回值也是一個函數對象。
好比:插入日誌、性能測試、事物處理、緩存、權限驗證等,有了裝飾器,就能夠抽離出大量與函數功能自己無關的雷同代碼並繼續重用。

# 裝飾器
import time
def login(func):
    def inner():
        start_time = time.time()
        func()
        end_time = time.time()
        print("fun 執行時間",end_time-start_time)
    return inner

@login
def test():
    for i in range(10000):
        for j in range(10000):
            pass
    print('test函數執行')

test()
# test函數執行
# fun 執行時間 2.0163347721099854
一、什麼是python?使用python有什麼好處?

python是一種編程語言,它有對象、模塊、線程、異常處理和自動內存管理。它簡潔,簡單、方便、容易擴展、有許多自帶的數據結果,並且它開源
Python是一種解釋性語言,它的源代碼能夠直接運行,Python解釋器會將源代碼轉換成中間語言,以後再翻譯成機器碼再執行

三、數組和元祖之間的區別是什麼?

數組和元祖之間的區別:數組內容能夠被修改,而元祖內容是隻讀的,不可被修改的,另外元祖能夠被哈希,好比做爲字典的key

五、os與sys區別:

os是模塊負責程序與操做系統的交互,提供了訪問操做系統底層的接口
sys模塊是負責程序與python解釋器的交互,提供了一系列的函數和變量,用於操控Python時運行的環境

1五、range-and-xrange
py2:
        range() 生成的是列表
        xrange() 生成的是一個生成器 
    py3:
        range() 就是一個生成器
        xrange() 沒了
2一、什麼是pickling和unpickling?

Pickle模塊讀入任何python對象,將它們轉換成字符串,而後使用dump函數將其轉儲到一個文件中——這個過程叫作pickling
反之從存儲的字符串文件中提取原始python對象的過程,叫作unpickling

八、迭代器與生成器

生成器:Python使用生成器對延遲操做提供了支持。所謂延遲操做,是指在須要的時候才產生結果,而不是當即產生結果。這也是生成器的主要好處。

這裏,最難理解的就是generator和函數的執行流程不同。
函數是順序執行,遇到return語句或者最後一行函數語句就返回。generator的函數,在每次調用next()的時候執行,遇到yield語句返回,再次被next()調用時從上次返回的yield語句處繼續執行。

迭代器

能夠直接做用於for循環的數據類型:

  • 一類是集合數據類型,如listtupledictsetstr等;
  • 一類是generator,包括生成器和帶yield的 generator function。
    不是一次性把數據加載到內存,而是被next()函數調用,不斷返回下一個數據

    九、classmethod,staticmethod,property

    類方法:將類的函數轉換成類方法,函數上裝飾@classmethod會將函數的自動傳值參數改爲cls
    靜態方法:此方法至關於給類擴展一個功能,將類內的函數實例化,給類或對象使用,此時類內的函數就是普通函數,無論是類仍是實例化的對象均可以使用
    實例化:類的實例化就會產生一個實例(對象),能夠理解爲類()把虛擬的東西實例化,獲得具體存在的值

    十、 new.init區別,如何實現單例模式,有什麼優勢
    __new__是一個靜態方法,__init__是一個實例方法
    __new__返回一個建立的實例,__init__什麼都不返回
    __new__返回一個cls的實例時後面的__init__才能被調用
    當建立一個新實例時調用new,初始化一個實例時調用init
_new_()在 _init_()以前被調用,用於生成實例對象。利用這個方法和類的屬性的特色能夠實現設計模式的單例模式。
 單例模式是指建立惟一對象,單例模式設計的類只能實例,實例化1個對象
class Singleton(object):
                        __instance=None
                        def __init__(self):
                            pass
                        def __new__(cls, *args, **kwargs):
                            if Singleton.__instance is None:
                                Singleton.__instance=object.__new__(cls,*args,**kwargs)
                            return Singleton.__instance
2. python面向對象中的反射:
經過字符串的形式操做對象相關的屬性。python中的一切事物都是對象(均可以使用反射)
十一、多進程,多線程,協程,GIL

GIL:全局解釋器鎖,是鎖在cpython解釋器上,致使同一時刻,同一進程只能有一個線程被執行
多進程:多進程模塊multiprocessing來實現,cpu密集型,IO計算型能夠用多進程
多線程:多線程模塊threading來實現,IO密集型,多線程能夠提升效率
協程:依賴於geenlet,對於多線程應用。cpu經過切片的方式來切換線程間的執行,遇到IO操做自動切換,線程切換時須要耗時,
而協成好處沒有切換的消耗,沒有鎖定概念。
進程:是資源管理單位,進行是相互獨立的,實現併發和併發
線程:是最小的執行單位,線程的出現爲了下降上下文切換的消耗,提供系統的併發性

十二、IO多路複用/異步非阻塞

IO多路複用:經過一種機制,能夠監聽多個描述符 select/poll/epoll
select:鏈接數受限,查找配對速度慢,數據由內核拷貝到用戶態
poll:改善了鏈接數,可是仍是查找配對速度慢,數據由內核拷貝到用戶態
epoll:epoll是linux下多路複用IO接口,是select/poll的加強版,它能顯著提升程序在大量併發鏈接中只有少許活躍的狀況下的系統CPU利用率
異步非阻塞:異步體如今回調上,回調就是有消息返回時告知一聲兒進程進行處理。非阻塞就是不等待,不須要進程等待下去,
繼續執行其餘操做,無論其餘進程的狀態。

1四、PEP8規範,規範的好處是什麼?

1.縮進:4個空實現縮進,儘可能不使用Tab
2.行:沒行最大長度不超過79,換行可使用反斜槓
3.命名規範:
4.註釋規範:

1六、with上下文機制原理

enter_和_exit,上下文管理協議,即with語句,爲了讓一個對象兼容with語句,必須在這個對象類中聲明_enter_和_exit_方法,
使用with語句的目的就是把代碼塊放入with中執行,with結束後,自動完成清理工做,無須收到干預

1七、經典類、新式類

經典類遵循:深度優先,python2中
新式類遵循:廣度優先,Python3中

2五、Python都有哪些自帶的數據結構?
可變:列表  字典
不可變: 數字  字符串  元祖
2六、命名空間?

在python中,全部的名字都存在於一個空間中,它們在改空間中存在和被操做——這就是命名空間,它就好像一個盒子,在每一個變量名字都對應裝着一個對象,
當查詢變量的時候,會從該盒子裏面尋找相應的對象

2八、*args與**kwargs
*args表明位置參數,它會接收任意多個參數並把這些參數做爲元祖傳遞給函數。
**kwargs表明的關鍵字參數,返回的是字典,位置參數必定要放在關鍵字前面
7.索引B+樹

B+樹(數據結構,平衡樹,根節點,子節點,數據) 索引可以讓數據庫查詢數據的速度上升,而使寫入數據的速度降低, 由於平衡樹這個結構必須一直維持在一個正確的狀態, 增刪改數據都會改變平衡樹各節點中的索引數據內容,破壞樹結構, 所以,在每次數據改變時, DBMS必須去從新梳理樹(索引)的結構以確保它的正確,這會帶來不小的性能開銷, 也就是爲何索引會給查詢之外的操做帶來反作用的緣由。

8.哈希表

(Hash Table,又稱爲散列表),是一種線性表的存儲結構。經過把每一個對象的關鍵字k做爲自變量,經過一個哈希函數h(k),將k映射到下標h(k)處,並將該對象存儲在這個位置。

例如:數據集合{1,6,7,9},假設存在哈希函數h(x)使得h(1) = 0, h(6) = 2, h(7) = 4, h(9) = 5,那麼這個哈希表被存儲爲[1,None, 6, None, 7, 9]。
當咱們查找元素6所在的位置時,經過哈希函數h(x)得到該元素所在的下標(h(6) = 2),所以在2位置便可找到該元素。

相關文章
相關標籤/搜索