Python常見面試知識總結(一):迭代器、拷貝、線程及底層結構

前言: Hello大家好,我是Dream。 今天來總結一下Python和C語言中常見的面試知識,歡迎大家一起前來探討學習~

【一】Python中迭代器的概念?

可迭代對象是迭代器、生成器和裝飾器的基礎。簡單來說,可以使用for來循環遍歷的對象就是可迭代對象。比如常見的list、set和dict。

我們來看一個例子:

from collections import Iterable
print(isinstance('abcddddd', Iterable))     # str是否可迭代print(isinstance([1,2,3,4,5,6], Iterable))   # list是否可迭代print(isinstance(12345678, Iterable))       # 整數是否可迭代-------------結果如下----------------
True
True
False

當對所有的可迭代對象調用 dir() 方法時,會發現他們都實現了 iter 方法。這樣就可以通過 iter(object) 來返回一個迭代器。

x = [1, 2, 3]
y = iter(x)
print(type(x))print(type(y))------------結果如下------------
<class 'list'>
<class 'list_iterator'>

可以看到調用iter()之后,變成了一個list_iterator的對象。可以發現增加了一個__next__方法。所有實現了__iter__和__next__兩個方法的對象,都是迭代器

迭代器是帶狀態的對象,它會記錄當前迭代所在的位置,以方便下次迭代的時候獲取正確的元素。__iter__返回迭代器自身,__next__返回容器中的下一個值,如果容器中沒有更多元素了,則拋出Stoplteration異常。

x = [1, 2, 3]
y = iter(x)
print(next(y))
print(next(y))
print(next(y))
print(next(y))----------結果如下----------
1
2
3
Traceback (most recent call last):File "/Users/Desktop/test.py", line 6, in <module>print(next(y))
StopIteration

如何判斷對象是否是迭代器,和判斷是否是可迭代對象的方法差不多,只要把 Iterable 換成 Iterator。

Python的for循環本質上就是通過不斷調用next()函數實現的,舉個栗子,下面的代碼先將可迭代對象轉化為Iterator,再去迭代。這樣可以節省對內存,因為迭代器只有在我們調用 next() 才會實際計算下一個值

x = [1, 2, 3]
for elem in x:...

itertools 庫提供了很多常見迭代器的使用。

>>> from itertools import count     # 計數器
>>> counter = count(start=13)
>>> next(counter)
13
>>> next(counter)
14

【二】Python中生成器的相關知識

我們創建列表的時候,受到內存限制,容量肯定是有限的,而且不可能全部給他一次枚舉出來。Python常用的列表生成式有一個致命的缺點就是定義即生成,非常的浪費空間和效率。

如果列表元素可以按照某種算法推算出來,那我們可以在循環的過程中不斷推算出后續的元素,這樣就不必創建完整的list,從而節省大量的空間。在Python中,這種一邊循環一邊計算的機制,稱為生成器:generator。

要創建一個generator,最簡單的方法是改造列表生成式:

a = [x * x for x in range(10)]
print(a)
b = (x * x for x in range(10))
print(b)--------結果如下--------------
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
<generator object <genexpr> at 0x10557da50>

還有一個方法是生成器函數,通過def定義,然后使用yield來支持迭代器協議,比迭代器寫起來更簡單。

def spam():yield"first"yield"second"yield"third"for x in spam():print(x)-------結果如下---------
first
second
third

進行函數調用的時候,返回一個生成器對象。在使用next()調用的時候,遇到yield就返回,記錄此時的函數調用位置,下次調用next()時,從斷點處開始。

我們完全可以像使用迭代器一樣使用 generator ,當然除了定義。定義一個迭代器,需要分別實現 iter() 方法和 next() 方法,但 generator 只需要一個小小的yield。

generator還有 send() 和 close() 方法,都是只能在next()調用之后,生成器處于掛起狀態時才能使用的。

python是支持協程的,也就是微線程,就是通過generator來實現的。配合generator我們可以自定義函數的調用層次關系從而自己來調度線程。

【三】Python中裝飾器的相關知識

裝飾器允許通過將現有函數傳遞給裝飾器,從而向現有函數添加一些額外的功能,該裝飾器將執行現有函數的功能和添加的額外功能。

裝飾器本質上還是一個函數,它可以讓已有的函數不做任何改動的情況下增加功能。

接下來我們使用一些例子來具體說明裝飾器的作用:

如果我們不使用裝飾器,我們通常會這樣來實現在函數執行前插入日志:

def foo():print('i am foo')def foo():print('foo is running')print('i am foo')

雖然這樣寫是滿足了需求,但是改動了原有的代碼,如果有其他的函數也需要插入日志的話,就需要改寫所有的函數,這樣不能復用代碼。

我們可以進行如下改寫:

import loggingdef use_log(func):logging.warning("%s is running" % func.__name__)func()def bar():print('i am bar')use_log(bar)    #將函數作為參數傳入-------------運行結果如下--------------
WARNING:root:bar is running
i am bar

這樣寫的確可以復用插入的日志,缺點就是顯式的封裝原來的函數,我們希望能隱式的做這件事。

我們可以用裝飾器來寫:

import loggingdef use_log(func):def wrapper(*args, **kwargs):logging.warning('%s is running' % func.__name__)return func(*args, **kwargs)return wrapperdef bar():print('I am bar')bar = use_log(bar)
bar()------------結果如下------------
WARNING:root:bar is running
I am bar

其中,use_log函數就是裝飾器,它把我們真正想要執行的函數bar()封裝在里面,返回一個封裝了加入代碼的新函數,看起來就像是bar()被裝飾了一樣。

但是這樣寫還是不夠隱式,我們可以通過@語法糖來起到bar = use_log(bar)的作用。

import loggingdef use_log(func):def wrapper(*args, **kwargs):logging.warning('%s is running' % func.__name__)return func(*args, **kwargs)return wrapper@use_log
def bar():print('I am bar')@use_log
def haha():print('I am haha')bar()
haha()------------結果如下------------
WARNING:root:bar is running
I am bar
WARNING:root:haha is running
I am haha

這樣子看起來就非常簡潔,而且代碼很容易復用。可以看成是一種智能的高級封裝。

【四】Python的深拷貝與淺拷貝?

在Python中,用一個變量給另一個變量賦值,其實就是給當前內存中的對象增加一個“標簽”而已。

>>> a = [6, 6, 6, 6]
>>> b = a
>>> print(id(a), id(b), sep = '\n')
66668888
66668888>>> a is b
True(可以看出,其實a和b指向內存中同一個對象。)

淺拷貝是指創建一個新的對象,其內容是原對象中元素的引用(新對象與原對象共享內存中的子對象)。

注:淺拷貝和深拷貝的不同僅僅是對組合對象來說,所謂的組合對象就是包含了其他對象的對象,如列表,類實例等等。而對于數字、字符串以及其他“原子”類型,沒有拷貝一說,產生的都是原對象的引用。

常見的淺拷貝有:切片操作、工廠函數、對象的copy()方法,copy模塊中的copy函數。

>>> a = [6, 8, 9]
>>> b = list(a)
>>> print(id(a), id(b))
4493469248 4493592128    #a和b的地址不同>>> for x, y in zip(a, b):
...     print(id(x), id(y))
... 
4489786672 4489786672
4489786736 4489786736
4489786768 4489786768
# 但是他們的子對象地址相同

從上面的例子中可以看出,a淺拷貝得到b,a和b指向內存中不同的list對象,但是他們的元素指向相同的int對象,這就是淺拷貝。

深拷貝是指創建一個新的對象,然后遞歸的拷貝原對象所包含的子對象。深拷貝出來的對象與原對象沒有任何關聯。

深拷貝只有一種方式:copy模塊中的deepcopy函數。

我們接下來用一個包含可變對象的列表來確切地展示淺拷貝和深拷貝的區別:

>>> a = [[6, 6], [8, 8], [9, 9]]
>>> b = copy.copy(a)   # 淺拷貝
>>> c = copy.deepcopy(a) # 深拷貝
>>> print(id(a), id(b)) # a和b地址不同
4493780304 4494523680
>>> for x, y in zip(a, b):   # a和b的子對象地址相同
...     print(id(x), id(y))
... 
4493592128 4493592128
4494528592 4494528592
4493779024 4493779024
>>> print(id(a), id(c))   # a和c不同
4493780304 4493469248
>>> for x, y in zip(a, c): # a和c的子對象地址也不同
...     print(id(x), id(y))
... 
4493592128 4493687696
4494528592 4493686336
4493779024 4493684896

【五】Python是解釋語言還是編譯語言?

Python是解釋語言。

解釋語言的優點是可移植性好,缺點是運行需要解釋環境,運行起來比編譯語言要慢,占用的資源也要多一些,代碼效率低。

編譯語言的優點是運行速度快,代碼效率高,編譯后程序不可以修改,保密性好。缺點是代碼需要經過編譯才能運行,可移植性較差,只能在兼容的操作系統上運行。

【六】Python的垃圾回收機制

在Python中,使用引用計數進行垃圾回收;同時通過標記-清除算法解決容器對象可能產生的循環引用問題;最后通過分代回收算法提高垃圾回收效率。

【七】Python里有多線程嗎?

Python里的多線程是假的多線程

Python解釋器由于設計時有GIL全局鎖,導致了多線程無法利用多核,只有一個線程在解釋器中運行。

對于I/O密集型任務,Python的多線程能起到作用,但對于CPU密集型任務,Python的多線程幾乎占不到任何優勢,還有可能因為爭奪資源而變慢。

對所有面向I/O的(會調用內建的操作系統C代碼的)程序來說,GIL會在這個I/O調用之前被釋放,以允許其它的線程在這個線程等待I/O的時候運行。

如果是純計算的程序,沒有 I/O 操作,解釋器會每隔 100 次操作就釋放這把鎖,讓別的線程有機會執行(這個次數可以通過 sys.setcheckinterval 來調整)如果某線程并未使用很多I/O 操作,它會在自己的時間片內一直占用處理器和GIL。

緩解GIL鎖的方法:多進程和協程(協程也只是單CPU,但是能減小切換代價提升性能)

【八】Python中range和xrange的區別?

首先,xrange函數和range函數的用法完全相同,不同的地方是xrange函數生成的不是一個list對象,而是一個生成器。

要生成很大的數字序列時,使用xrange會比range的性能優很多,因為其不需要一上來就開辟很大的內存空間。

Python 2.7.15 | packaged by conda-forge | (default, Jul  2 2019, 00:42:22) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> xrange(10)
xrange(10)
>>> list(xrange(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

xrange函數和range函數一般都用在循環的時候。具體例子如下所示:

>>> for i in range(0,7):
...     print(i)
... 
0
1
2
3
4
5
6>>> for i in xrange(0,7):
...     print(i)
... 
0
1
2
3
4
5
6

在Python3中,xrange函數被移除了,只保留了range函數的實現,但是此時range函數的功能結合了xrange和range。并且range函數的類型也發生了變化,在Python2中是list類型,但是在Python3中是range序列的對象。

【九】Python中列表和元組的區別?

  1. 列表是可變的,在創建之后可以對其進行任意的修改。

  2. 元組是不可變的,元組一旦創建,便不能對其進行更改,可以元組當作一個只讀版本的列表。

  3. 元組無法復制。

  4. Python將低開銷的較大的塊分配給元組,因為它們是不可變的。對于列表則分配小內存塊。與列表相比,元組的內存更小。當你擁有大量元素時,元組比列表快。

【十】Python中dict(字典)的底層結構?

Python的dict(字典)為了支持快速查找使用了哈希表作為底層結構,哈希表平均查找時間復雜度為O(1)。CPython 解釋器使用二次探查解決哈希沖突問題。

【十一】常用的深度學習框架有哪些,都是哪家公司開發的?

  1. PyTorch:Facebook

  2. TensorFlow:Google

  3. Keras:Google

  4. MxNet:Dmlc社區

  5. Caffe:UC Berkeley

  6. PaddlePaddle:百度

【十二】PyTorch動態圖和TensorFlow靜態圖的區別?

PyTorch動態圖:計算圖的運算與搭建同時進行;其較靈活,易調節。

TensorFlow靜態圖:計算圖先搭建圖,后運算;其較高效,不靈活。

文末推薦

在這里插入圖片描述
內容介紹:
《機器學習平臺架構實戰》詳細闡述了與機器學習平臺架構相關的基本解決方案,主要包括機器學習和機器學習解決方案架構,機器學習的業務用例,機器學習算法,機器學習的數據管理,開源機器學習庫,Kubernetes容器編排基礎設施管理,開源機器學習平臺,使用AWS機器學習服務構建數據科學環境,使用AWS機器學習服務構建企業機器學習架構,高級機器學習工程,機器學習治理、偏差、可解釋性和隱私,使用人工智能服務和機器學習平臺構建機器學習解決方案等內容。此外,本書還提供了相應的示例、代碼,以幫助讀者進一步理解相關方案的實現過程。
當當: https://product.dangdang.com/29625469.html
京東: https://item.jd.com/13855627.html

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/215369.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/215369.shtml
英文地址,請注明出處:http://en.pswp.cn/news/215369.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[古劍山2023] pwn

最近這個打stdout的題真多。這個比賽沒打。拿到附件作了一天。 choice 32位&#xff0c;libc-2.23-i386&#xff0c;nbytes初始值為0x14,讀入0x804A04C 0x14字節后會覆蓋到nbytes 1個字節。當再次向v1讀入nbytes字節時會造成溢出。 先寫0x14p8(0xff)覆蓋到nbytes然后溢出寫傳…

初次參加軟考就想報高級,哪個相對容易考?

如果你想第一次參加軟考時就報考高級科目&#xff0c;但是卻不知道該報考高級中的哪個科目好、 ? ?那么今天的這篇文章你一定不要錯過&#xff01;首先&#xff0c;我們一起來了解一下&#xff0c;軟考高級中的5個科目。 ? ?軟考高級科目 ? 信息系統項目管理師 ? …

記錄一次postgresql臨時表丟失問題

項目相關技術棧 springboot hikari連接池pgbouncerpostgresql數據庫 背景 為了優化一個任務執行的速度&#xff0c;我將任務的sql中部分語句抽出生成臨時表&#xff08;create temp table tempqw as xxxxxxxxx&#xff09;&#xff0c;再和其他表關聯&#xff0c;提高查詢速…

三翼鳥2023輝煌收官, 定盤2024高質量棋局

最近在不同平臺上接連看到這樣的熱搜話題&#xff1a;用時間膠囊記錄2023的自己、2023年度問答、2023十大網絡流行語公布… 顯然&#xff0c; 2023年進入最后一個月&#xff0c;時間匆匆&#xff0c;這也意味著又到了總結過去和規劃未來的時候。拿到結果、取得成績當然是對202…

算法通關村第十五關 | 白銀 | 海量數據場景下的熱門算法題

1.從 40 個億中產生一個不存在的整數 可以采用位圖存儲數據&#xff0c;申請一個 bit 類型的數組 bitArr &#xff0c;每個位置只表示 0 或者 1 狀態&#xff0c;可以將占用內存縮小為使用哈希表的 1/32 。 遍歷給定的 40 億個數&#xff0c;遇到數時就將 bitArr 相應位置設置…

短視頻引流獲客系統:引領未來營銷的新潮流

在這個信息爆炸的時代&#xff0c;短視頻已經成為了人們獲取信息的主要渠道之一。而隨著短視頻的火爆&#xff0c;引流獲客系統也逐漸成為了營銷領域的新寵。本文將詳細介紹短視頻引流獲客系統的開發流程以及涉及到的技術&#xff0c;讓我們一起來看看這個引領未來營銷的新潮流…

華清遠見作業第二十四天

使用消息隊列完成兩個進程之間相互通信 代碼 #include<stdio.h> #include<string.h> #include<stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ipc.h> #include <sys/msg.h> #in…

k8s一鍵部署uniswap

1、拉取uniswap源碼 github地址 2、編寫Dockerfile并打鏡像 # Set the base image FROM node:18.10.0# WORKDIR /usr/src/app/ WORKDIR /home/gateway# Copy files COPY ./ /home/gateway/# Dockerfile author / maintainer LABEL maintainer"Michael Feng <mikehummi…

Java最全面試題專題---2、Java集合容器(2)

Map接口 說一下 HashMap 的實現原理&#xff1f; HashMap概述&#xff1a; HashMap是基于哈希表的Map接口的非同步實現。此實現提供所有可選的映射操作&#xff0c;并允許使用null值和null鍵。此類不保證映射的順序&#xff0c;特別是它不保證該順序恒久不變。 HashMap的數據…

C語言-枚舉

常量符號化 用符號而不是具體的數字來表示程序中的數字 枚舉 用枚舉而不是定義獨立的const int變量 枚舉是一種用戶定義的數據類型&#xff0c;他用關鍵詞enum以如下語法來聲明&#xff1a; enum枚舉類型名字{名字0&#xff0c;…&#xff0c;名字n}&#xff1b; 枚舉類型名…

外包干了3年,技術退步太明顯了。。。。。

先說一下自己的情況&#xff0c;本科生生&#xff0c;18年通過校招進入武漢某軟件公司&#xff0c;干了差不多3年的功能測試&#xff0c;今年國慶&#xff0c;感覺自己不能夠在這樣下去了&#xff0c;長時間呆在一個舒適的環境會讓一個人墮落!而我已經在一個企業干了四年的功能…

6_CSS布局之浮動的應用

day06_CSS布局之浮動的應用 本課目標&#xff08;Objective&#xff09; 理解什么是浮動掌握浮動的三種機制掌握浮動的案例應用 1 CSS 布局的三種機制 CSS 提供了 3 種機制來設置盒子的擺放位置&#xff0c;分別是普通流&#xff08;標準流&#xff09;、浮動和定位。 普通流…

HarmonyOS開發:回調實現網絡的攔截

前言 基于http封裝的一個網絡庫&#xff0c;里面有一個知識點&#xff0c;在初始化的時候&#xff0c;可以設置請求頭攔截和請求錯誤后的信息的攔截&#xff0c;具體案例如下&#xff1a; et.getInstance().init({netErrorInterceptor: new MyNetErrorInterceptor(), //設置全…

web網絡安全

web安全 一&#xff0c;xss 跨站腳本攻擊(全稱Cross Site Scripting,為和CSS&#xff08;層疊樣式表&#xff09;區分&#xff0c;簡稱為XSS)是指惡意攻擊者在Web頁面中插入惡意javascript代碼&#xff08;也可能包含html代碼&#xff09;&#xff0c;當用戶瀏覽網頁之時&…

關于北京醫學sci論文翻譯

在醫學領域&#xff0c;翻譯論文是一項非常重要的工作。醫學論文的翻譯需要準確、專業、嚴謹&#xff0c;同時也需要考慮到醫學領域的特殊性和復雜性。那么&#xff0c;如何翻譯醫學論文呢&#xff1f;北京醫學SCI論文翻譯哪家好呢&#xff1f; 首先&#xff0c;需要具備專業的…

多目標跟蹤數據集

目錄 DanceTrack數據集 自己改進的可視化代碼: DanceTrack數據集 DanceTrack 是一個大規模的多對象跟蹤數據集。用于在遮擋、頻繁交叉、同樣服裝和多樣化身體姿態條件下對人進行跟蹤。強調運動分析在多對象跟蹤中的重要性。 GitHub地址:https://github.com/DanceTrack/Dan…

python自動化測試實戰 —— 單元測試框架

軟件測試專欄 感興趣可看&#xff1a;軟件測試專欄 自動化測試學習部分源碼 python自動化測試相關知識&#xff1a; 【如何學習Python自動化測試】—— 自動化測試環境搭建 【如何學習python自動化測試】—— 瀏覽器驅動的安裝 以及 如何更…

swing快速入門(五)

注釋很詳細&#xff0c;直接上代碼 上一篇 本篇新增內容&#xff1a; 1.布局管理器BorderLayout 2.自適應尺寸方法pack() import java.awt.*; public class swing_test_3 {public static void main(String[] args) {Frame framenew Frame("演示BorderLayout");//…

第十六屆山東省職業院校技能大賽高職組“應用軟件系統開發”賽項樣題

第十六屆山東省職業院校技能大賽 高職組“應用軟件系統開發”賽項樣題 目錄 一&#xff0e;競賽須知 二&#xff0e;競賽任務標題二 模塊一&#xff1a;系統需求分析&#xff08;25分&#xff09; 模塊二&#xff1a;軟件系統開發&#xff08;55分&#xff09; 模塊三&am…

【APP安卓測試工具】adb(Android Debug Bridge)

1.常見的命令 列出已連接的設備 adb device安裝 adb install <APK文件路徑>卸載 adb uninstall <APK文件路徑>啟動和停止 adb shell am start -n <包名>[/<Activity>]adb shell am force -stop <包名>截屏和錄屏 adb shell screencap <文件路…