學習Python一年,基礎忘記了,看看面試題回憶回議,Python面試題No3


這邊有幾個面試題,好棒

第1題:你如何管理不同版本的代碼?

git,svn兩個都要說到,github,碼雲也要提及,面試官想要的就是版本管理工具,你只要選擇一個你熟悉的,瘋狂的說一通就可以了,最好說一下自己以前做過哪些開源的項目,放在上面,沒有,就另當別論了。

第2題:python中生成隨機整數、隨機小數、0~1之間小數方法?

python中生成隨機整數

import random
random.randint(1,10)

隨機小數

看自己習慣,可以用random庫,也可以用numpy庫

import random
random.random()

# 利用np.random.randn(5)生成5個隨機小數
import numpy as np
np.random.randn(5)

0~1之間小數

random.random()

第3題:迭代器、可迭代對象、生成器?

第一步,你要知道什么是迭代

對list、tuple、str等類型的數據使用for...in...的循環語法從其中依次拿到數據進行使用,我們把這樣的過程稱為遍歷,也叫迭代

從結果去分析原因,能被for循環的就是“可迭代的”,但是如果正着想,for怎么知道誰是可迭代的呢?

假如我們自己寫了一個數據類型,希望這個數據類型里的東西也可以使用for被一個一個的取出來,那我們就必須滿足for的要求--- 這個要求就叫做 協議

可以被迭代要滿足的要求就叫做:可迭代協議

可迭代協議的定義非常簡單,就是內部實現了__iter()__方法

如果某個對象中有_ iter _()方法,這個對象就是可迭代對象 (Iterable)

if '__iter__' in dir(str)

通俗易懂 :可以被for循環迭代的對象就是可迭代對象。

從代碼上面可以使用isinstance()判斷一個對象是否是Iterable對象

from collections import Iterable
a = isinstance([], Iterable)

b = isinstance({}, Iterable)

c = isinstance('abc', Iterable)

d = isinstance((x for x in range(10)), Iterable)

e = isinstance(100, Iterable)

print(a,b,c,d,e)

結論

True True True True False

只有最后的數字不是可迭代對象

可迭代對象的本質

我們分析對可迭代對象進行迭代使用的過程,發現每迭代一次(即在for...in...中每循環一次)都會返回對象中的下一條數據,一直向后讀取數據直到迭代了所有數據后結束。

那么,在這個過程中就應該有一個“人”去記錄每次訪問到了第幾條數據,以便每次迭代都可以返回下一條數據。

我們把這個能幫助我們進行數據迭代的“人”稱為迭代器(Iterator)

可迭代對象的本質就是可以 向我們提供一個這樣的中間“人”即迭代器 幫助我們對其進行迭代遍歷使用。

可迭代對象通過__iter__方法向我們提供一個迭代器,在迭代一個可迭代對象的時候,實際上就是先獲取該對象提供的一個迭代器,然后通過這個迭代器來依次獲取對象中的每一個數據。

綜上所述,一個具備了__iter__方法的對象,就是一個可迭代對象。

class MyList(object):
    def __init__(self):
        self.container = []
    def add(self, item):
        self.container.append(item)
    def __iter__(self):
        """返回一個迭代器"""
        # 我們暫時忽略如何構造一個迭代器對象
        pass
    
mylist = MyList()
from collections import Iterable
isinstance(mylist, Iterable)

iter()函數與next()函數

listtuple等都是可迭代對象,我們可以通過iter()函數獲取這些可迭代對象的迭代器。
然后我們可以對獲取到的迭代器不斷使用next()函數來獲取下一條數據。iter()函數實際上就是調用了可迭代對象的__iter__方法。

>>> i = iter('spam')
>>> next(i)
's'
>>> next(i)
'p'
>>> next(i)
'a'
>>> next(i)
'm'
>>> next(i)
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    next(i)
StopIteration
>>> 

當序列遍歷完時,將拋出一個StopIteration異常。這將使迭代器與循環兼容,因為它們將捕獲這個異常以停止循環。
要創建定制的迭代器,可以編寫一個具有next方法的類。

迭代器Iterator

通過上面的分析,現在你應該已經知道了,迭代器是用來幫助我們記錄每次迭代訪問到的位置,當我們對迭代器使用next()函數的時候,迭代器會向我們返回它所記錄位置的下一個位置的數據。
實際上,在使用next()函數的時候,調用的就是迭代器對象的__next__方法(Python3中是對象的__next__方法,Python2中是對象的next()方法)。

所以,我們要想構造一個迭代器,就要實現它的__next__方法。但這還不夠,python要求迭代器本身也是可迭代的,所以我們還要為迭代器實現__iter__方法,而__iter__方法要返回一個迭代器,迭代器自身正是一個迭代器,所以迭代器的__iter__方法返回自身即可。

一個實現了__iter__方法和__next__方法的對象,就是迭代器。

class MyList(object):
    """自定義的一個可迭代對象"""
    def __init__(self):
        self.items = []
 
    def add(self, val):
        self.items.append(val)
 
    def __iter__(self):
        myiterator = MyIterator(self)
        return myiterator
 
 
class MyIterator(object):
    """自定義的供上面可迭代對象使用的一個迭代器"""
    def __init__(self, mylist):
        self.mylist = mylist
        # current用來記錄當前訪問到的位置
        self.current = 0
 
    def __next__(self):
        if self.current < len(self.mylist.items):
            item = self.mylist.items[self.current]
            self.current += 1
            return item
        else:
            raise StopIteration
 
    def __iter__(self):
        return self
 
 
if __name__ == '__main__':
    mylist = MyList()
    mylist.add(1)
    mylist.add(2)
    mylist.add(3)
    mylist.add(4)
    mylist.add(5)
    for num in mylist:
        print(num)

本部分代碼來源: https://blog.csdn.net/weixin_42225318/article/details/81274348 博主這篇博客寫的真好

可迭代對象與迭代器

  1. 可迭代對象包含迭代器。
  2. 如果一個對象擁有__iter__方法,那么它是可迭代對象;如果一個對象擁有next方法,其是迭代器。
  3. 定義可迭代對象,必須實現__iter__方法;定義迭代器,必須實現__iter__next方法。
  • _iter_()
    該方法返回的是當前對象的迭代器類的實例。因為可迭代對象與迭代器都要實現這個方法

  • next()
    返回迭代的每一步,實現該方法時注意要最后超出邊界要拋出StopIteration異常。

迭代器一定是可迭代對象,反過來則不一定成立。用iter()函數可以把list、dict、str等Iterable變成Iterator

生成器

  1. 生成器是一種特殊的迭代器,生成器自動實現了“迭代器協議”(即__iter__next方法),不需要再手動實現兩方法。
  2. 生成器在迭代的過程中可以改變當前迭代值,而修改普通迭代器的當前迭代值往往會發生異常,影響程序的執行。
  3. 具有yield關鍵字的函數都是生成器,yield可以理解為return,返回后面的值給調用者。不同的是return返回后,函數會釋放,而生成器則不會。在直接調用next方法或用for語句進行下一次迭代時,生成器會從yield下一句開始執行,直至遇到下一個yield。

第4題:單引號,雙引號,三引號的區別?

  • 單引號和雙引號主要用來表示字符串

      比如: 
      單引號:'python'
      雙引號:"python"
    
  • 三引號

三單引號:'''python ''',也可以表示字符串一般用來輸入多行文本,或者用於大段的注釋;
三雙引號:"""python""",一般用在類里面,用來注釋類,這樣省的寫文檔,直接用類的對象__doc__訪問獲得文檔。

區別

若你的字符串里面本身包含單引號,必須用雙引號

例子:"can't find the log\n"

第5題:Python是如何進行內存管理的?

對象的引用計數機制
Python內部使用引用計數,來保持追蹤內存中的對象,所有對象都有引用計數。

引用計數增加的情況:

總結一下對象會在一下情況下引用計數加1:

  1. 對象被創建:x='spam'
  2. 另外的別人被創建:y=x
  3. 被作為參數傳遞給函數:foo(x)
  4. 作為容器對象的一個元素:a=[1,x,'33']

引用計數減少情況

  1. 一個本地引用離開了它的作用域。比如上面的foo(x)函數結束時,x指向的對象引用減1。
  2. 對象的別名被顯式的銷毀:del x ;或者del y
  3. 對象的一個別名被賦值給其他對象:x=789
  4. 對象從一個窗口對象中移除:myList.remove(x)
  5. 窗口對象本身被銷毀:del myList,或者窗口對象本身離開了作用域。

垃圾回收

  1. 當內存中有不再使用的部分時,垃圾收集器就會把他們清理掉。它會去檢查那些引用計數為0的對象,然后清除其在內存的空間。當然除了引用計數為0的會被清除,還有一種情況也會被垃圾收集器清掉:當兩個對象相互引用時,他們本身其他的引用已經為0了。
  2. 垃圾回收機制還有一個循環垃圾回收器, 確保釋放循環引用對象(a引用b, b引用a, 導致其引用計數永遠不為0)。

在Python中,許多時候申請的內存都是小塊的內存,這些小塊內存在申請后,很快又會被釋放,由於這些內存的申請並不是為了創建對象,所以並沒有對象一級的內存池機制。這就意味着Python在運行期間會大量地執行malloc和free的操作,頻繁地在用戶態和核心態之間進行切換,這將嚴重影響Python的執行效率。為了加速Python的執行效率,Python引入了一個內存池機制,用於管理對小塊內存的申請和釋放。

內存池機制

  1. Python提供了對內存的垃圾收集機制,但是它將不用的內存放到內存池而不是返回給操作系統;
  2. Pymalloc機制:為了加速Python的執行效率,Python引入了一個內存池機制,用於管理對小塊內存的申請和釋放;
  3. 對於Python對象,如整數,浮點數和List,都有其獨立的私有內存池,對象間不共享他們的內存池。也就是說如果你分配又釋放了大量的整數,用於緩存這些整數的內存就不能再分配給浮點數。

第6題:寫一個函數, 輸入一個字符串, 返回倒序排列的結果?

使用字符串本身的翻轉

def order_by(str):
    return str[::-1]
 
print(order_by('123456'))
 
輸出:654321

把字符串變為列表,用列表的reverse函數

def reverse2(text='abcdef'):
    new_text=list(text)
    new_text.reverse()
    return ''.join(new_text)

reverse2('abcdef')

新建一個列表,從后往前取

def reverse3(text='abcdef'):
    new_text=[]
    for i in range(1,len(text)+1):
        new_text.append(text[-i])
    return ''.join(new_text)

reverse3('abcdef')

利用雙向列表deque中的extendleft函數

from collections import deque
def reverse4(text='abcdef'):
    d = deque()
    d.extendleft(text)
    return ''.join(d)

reverse4('abcdef')

微信搜索:非本科程序員

關注微信公眾號「非本科程序員」,獲取2T學習資源


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM