Python常見面試題的詳解10

1. 哪些操作會導致 Python 內存溢出,怎么處理?

  • 要點

??????? 1. 創建超大列表或字典:當我們一次性創建規模極為龐大的列表或字典時,會瞬間占用大量的內存資源。例如,以下代碼試圖創建一個包含 10 億個元素的列表,在執行這段代碼時,由于需要為這 10 億個整數分配內存空間,很容易就會導致內存溢出錯誤。

python

huge_list = [i for i in range(10**9)]

??????? 2. 遞歸深度過大:遞歸函數在沒有正確設置終止條件的情況下,會不斷地自我調用,從而使得棧空間持續被占用,最終耗盡內存。下面是一個簡單的無限遞歸示例:

python

def recursive_function():return recursive_function()
recursive_function()

???????? 3. 大文件讀取:使用 read() 方法一次性將大文件的全部內容讀取到內存中,對于大型文件而言,這會使內存占用急劇增加,若 large_file.txt 文件非常大,將其全部內容讀入內存會迅速耗盡可用內存。

python

with open('large_file.txt', 'r') as f:content = f.read()
  • 解決辦法
  1. 使用生成器:生成器是一種特殊的迭代器,它不會一次性生成所有元素,而是在需要時逐個生成,從而節省大量內存。例如,我們可以使用生成器表達式來生成一系列數字,在這個例子中,huge_generator 并不會立即生成 10 億個數字,而是在每次循環時才生成一個數字,當滿足條件 num > 100 時就停止生成,大大減少了內存的使用。

python

huge_generator = (i for i in range(10**9))
for num in huge_generator:if num > 100:break

????? 2. 優化遞歸:將遞歸函數改為迭代函數,或者手動實現尾遞歸優化(雖然 Python 本身不支持尾遞歸優化)。以下是將遞歸的階乘函數改為迭代實現的示例,通過迭代的方式,避免了遞歸調用帶來的棧空間占用問題。

python

# 遞歸實現階乘
def factorial_recursive(n):if n == 0 or n == 1:return 1return n * factorial_recursive(n - 1)# 迭代實現階乘
def factorial_iterative(n):result = 1for i in range(1, n + 1):result *= ireturn resultprint(factorial_iterative(5))

?????? 3. 分塊讀取文件:使用 read(size) 方法按指定大小分塊讀取文件,或者逐行讀取文件。例如按塊讀取文件的代碼如下,這樣每次只讀取 1024 字節的數據,處理完后再讀取下一塊,有效控制了內存的使用。

python

with open('large_file.txt', 'r') as f:while True:chunk = f.read(1024)if not chunk:break# 處理 chunkprint(chunk)
  • 總結
  1. 導致內存溢出的操作主要包括創建超大數據結構、遞歸深度過大和大文件一次性讀取。

  2. 處理內存溢出問題可以采用生成器、優化遞歸和分塊讀取文件等方法。

2. 內存管理機制及調優手段?

  • 要點

???? 1. 對象池:Python 對一些常用的小整數(-5 到 256)和短字符串進行了緩存處理。當多次使用相同的對象時,不會重新分配內存,而是直接復用已有的對象。這里的 100 在 -5 到 256 范圍內,所以 ab 指向同一個內存地址。

python

a = 100
b = 100
print(a is b)  # 輸出 True,說明 a 和 b 指向同一個對象

????? 2. 引用計數:每個 Python 對象都有一個引用計數,當引用計數為 0 時,對象所占用的內存會被自動釋放。以下是引用計數變化的示例,在這個過程中,通過 del 語句減少對象的引用計數,當引用計數為 0 時,Python 會回收該對象的內存。

python

a = [1, 2, 3]  # 列表對象引用計數加 1
b = a  # 引用計數再加 1
del a  # 引用計數減 1
del b  # 引用計數減為 0,對象內存釋放

????? 3. 垃圾回收:當存在循環引用時,引用計數機制無法解決內存泄漏問題,Python 會使用標記 - 清除和分代回收算法進行垃圾回收。

python

class A:pass
class B:passa = A()
b = B()
a.b = b
b.a = a# 此時 a 和 b 存在循環引用,即使沒有其他外部引用,引用計數也不會為 0
# Python 的垃圾回收機制會在適當的時候檢測并處理這種循環引用
  • 解決辦法

????? 1. 減少對象創建:盡量復用已有的對象,避免頻繁地創建和銷毀對象。例如,在需要多次使用相同字符串時,可以先將其賦值給一個變量,然后重復使用該變量,這樣避免了每次循環都創建一個新的字符串對象。

python

message = "Hello, World!"
for _ in range(10):print(message)

?????? 2. 及時釋放對象:使用 del 語句刪除不再使用的對象,減少引用計數,加快內存釋放。

python

data = [i for i in range(1000)]
# 使用 data 進行一些操作
# ...
del data  # 及時釋放 data 占用的內存

???????? 3. 使用 gc 模塊:手動調用 gc.collect() 方法可以觸發垃圾回收,清理不再使用的內存。

python

import gc
# 手動觸發垃圾回收
gc.collect()
  • 總結
  1. Python 的內存管理機制包括對象池、引用計數和垃圾回收。

  2. 內存調優手段有減少對象創建、及時釋放對象和手動觸發垃圾回收。

3. 內存泄露是什么?如何避免?

  • 要點

內存泄露是指程序在運行過程中,由于某些原因導致一些內存無法被釋放,隨著程序的持續運行,這些未釋放的內存會不斷累積,最終導致內存耗盡。例如以下代碼存在循環引用問題,可能會導致內存泄露:

python

class A:pass
class B:passa = A()
b = B()
a.b = b
b.a = a# 即使沒有其他外部引用指向 a 和 b,由于它們之間的循環引用,引用計數不會為 0,內存無法釋放
  • 解決辦法

?????? 1. 避免循環引用:盡量避免對象之間的循環引用,如果無法避免,可以手動解除引用。這樣就打破了循環引用,使得對象的引用計數可以降為 0,從而被垃圾回收機制回收。

python

class A:pass
class B:passa = A()
b = B()
a.b = b
b.a = a# 手動解除引用
del a.b
del b.a

?????? 2. 正確關閉資源:對于文件、數據庫連接等資源,使用 with 語句可以確保資源在使用完畢后正確關閉。

python

with open('file.txt', 'r') as f:content = f.read()
# 文件會自動關閉,避免資源占用
  • 總結
  1. 內存泄露是指內存無法正常釋放,導致內存不斷消耗。

  2. 避免內存泄露的方法包括避免循環引用和正確關閉資源。

4. python 常見的列表推導式?

  • 要點

?????? 1. 基本列表推導式:可以簡潔地生成列表。例如生成 0 到 9 的平方列表,這種方式比使用傳統的 for 循環更加簡潔明了。

python

squares = [i**2 for i in range(10)]
print(squares)  # 輸出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

??????? 2. 帶條件的列表推導式:帶條件的列表推導式可以根據條件篩選元素。例如生成 0 到 9 中偶數的平方列表,通過 if 條件篩選出偶數,然后計算其平方。

python

even_squares = [i**2 for i in range(10) if i % 2 == 0]
print(even_squares)  # 輸出 [0, 4, 16, 36, 64]

???????? 3. 嵌套列表推導式及示例可以用于生成多維列表。例如生成一個 3x3 的矩陣。

python

matrix = [[i * j for j in range(3)] for i in range(3)]
print(matrix)
# 輸出 [[0, 0, 0], [0, 1, 2], [0, 2, 4]]
  • 總結
  1. 基本列表推導式用于快速生成列表。

  2. 帶條件的列表推導式可根據條件篩選元素。

  3. 嵌套列表推導式用于生成多維列表。

5. 簡述 read、readline、readlines 的區別?

  • 要點

? 1.read() 方法:會一次性讀取文件的全部內容,并將其作為一個字符串返回。如果文件非常大,會占用大量內存。當 file.txt 文件內容較多時,content 會占用較多內存。

python

with open('file.txt', 'r') as f:content = f.read()print(content)

? 2.readline() 方法:每次讀取文件的一行內容,并將其作為一個字符串返回。可以通過循環多次調用 readline() 來逐行讀取文件。這種方式逐行讀取文件,內存占用相對較小。

python

with open('file.txt', 'r') as f:line = f.readline()while line:print(line)line = f.readline()

?? 3.readlines() 方法會一次性讀取文件的所有行,并將每行內容作為一個元素存儲在列表中返回。同樣,如果文件很大,會占用大量內存。例如:

python

with open('file.txt', 'r') as f:lines = f.readlines()for line in lines:print(line)
  • 總結
  1. read() 一次性讀取整個文件內容。

  2. readline() 逐行讀取文件。

  3. readlines() 一次性讀取所有行并存儲在列表中。

6. 什么是 Hash(散列函數)?

散列函數是一種將任意長度的輸入數據轉換為固定長度輸出的函數。這個固定長度的輸出通常稱為哈希值或散列值。

  • 要點

???? 1. 確定性:對于相同的輸入,散列函數總是返回相同的輸出。例如在 Python 中使用 hash() 函數:

python

hash_value1 = hash('hello')
hash_value2 = hash('hello')
print(hash_value1 == hash_value2)  # 輸出 True

?????? 2. 高效性:計算哈希值的速度很快,能夠在短時間內完成大量數據的哈希計算。

?????? 3. 均勻性:哈希值在輸出范圍內均勻分布,減少哈希沖突的概率。例如不同的字符串經過哈希函數計算后,其哈希值會盡可能均勻地分布在哈希空間中。

  • 總結
  1. 散列函數將任意長度輸入轉換為固定長度輸出。

  2. 具有確定性、高效性和均勻性特點。

7. 什么是函數重載機制?

  • 要點

Python 本身不支持傳統意義上的函數重載,即根據函數參數的數量或類型不同來定義多個同名函數。但可以通過以下幾種方式實現類似的功能:

????? 1. 使用默認參數及示例:使用默認參數可以讓函數在不同的調用方式下表現出不同的行為。當只傳入一個參數時,b 使用默認值 0;當傳入兩個參數時,使用傳入的參數進行計算。

python

def add(a, b=0):return a + bprint(add(1))  # 輸出 1
print(add(1, 2))  # 輸出 3

???????? 2. 使用 *args**kwargs 及示例*args 用于接收可變數量的位置參數,**kwargs 用于接收可變數量的關鍵字參數。通過判斷參數的類型和數量,可以實現不同的處理邏輯。

python

def func(*args, **kwargs):if len(args) == 1 and isinstance(args[0], int):print(f"Received an integer: {args[0]}")elif len(args) == 2 and all(isinstance(arg, str) for arg in args):print(f"Received two strings: {args[0]} and {args[1]}")else:print("Unknown input")func(1)
func("hello", "world")
  • 總結
  1. Python 不支持傳統函數重載。

  2. 可以使用默認參數、*args**kwargs 實現類似功能。

7. 手寫一個判斷時間的裝飾器

python

import timedef time_check(func):def wrapper(*args, **kwargs):start_time = time.time()result = func(*args, **kwargs)end_time = time.time()execution_time = end_time - start_timeprint(f"Function {func.__name__} took {execution_time} seconds to execute.")return resultreturn wrapper@time_check
def example_function():time.sleep(2)return "Function executed."print(example_function())
  • 要點

這個裝飾器 time_check 用于測量函數的執行時間。在函數執行前后分別記錄時間,計算時間差并打印出來。

  1. 裝飾器是一種高階函數,接收一個函數作為參數并返回一個新的函數。

  2. 可以利用裝飾器對函數進行功能擴展,如時間測量、日志記錄等。

9. 如何使用 Python 內置的 filter () 方法來過濾?

filter() 函數用于過濾序列,過濾掉不符合條件的元素,返回一個迭代器對象。例如過濾出列表中的偶數:

python

numbers = [1, 2, 3, 4, 5, 6]
even_numbers = filter(lambda x: x % 2 == 0, numbers)
print(list(even_numbers))  # 輸出 [2, 4, 6]
  • 要點
  1. filter() 函數接收一個函數和一個可迭代對象作為參數。

  2. 函數用于判斷元素是否符合條件,符合條件的元素會被保留。

  3. 返回的是一個迭代器對象,可通過 list() 函數將其轉換為列表。

10. 寫出編寫函數的 4 個原則

  • 單一職責原則

一個函數應該只做一件事情,并且把這件事情做好。這樣可以提高函數的可讀性和可維護性。例如一個函數只負責計算兩個數的和,這個函數的功能非常明確,只進行加法運算。

python

def add(a, b):return a + b
  • 避免副作用原則

函數應該盡量避免修改外部變量或產生其他副作用。如果需要修改外部狀態,應該明確告知調用者。add_to_list 函數不會修改原始列表,而是返回一個新的列表。

python

# 不好的示例,修改了外部列表
my_list = [1, 2, 3]
def modify_list():my_list.append(4)# 好的示例,返回新列表
def add_to_list(lst, item):return lst + [item]
  • 提供清晰的接口原則

函數的參數和返回值應該有明確的含義和類型。可以使用類型注解來提高代碼的可讀性。通過類型注解,明確了參數和返回值的類型。

python

def multiply(a: int, b: int) -> int:return a * b
  • 可測試性原則

函數應該易于測試,盡量減少依賴外部資源。可以通過單元測試來驗證函數的正確性。square 函數不依賴外部資源,很容易進行測試。

python

def square(x):return x ** 2# 簡單的測試
assert square(2) == 4
  • 要點
  1. 編寫函數應遵循單一職責、避免副作用、提供清晰接口和可測試性原則。

  2. 這些原則有助于提高代碼的質量和可維護性。

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

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

相關文章

多個用戶如何共用一根網線傳輸數據

前置知識 一、電信號 網線(如以太網線)中傳輸的信號主要是 電信號,它攜帶著數字信息。這些信號用于在計算機和其他網絡設備之間傳輸數據。下面是一些關于網線傳輸信號的詳細信息: 1. 電信號傳輸 在以太網中,數據是…

華為昇騰 910B 部署 DeepSeek-R1 蒸餾系列模型詳細指南

本文記錄 在 華為昇騰 910B(65GB) * 8 上 部署 DeepSeekR1 蒸餾系列模型(14B、32B)全過程與測試結果。 NPU:910B3 (65GB) * 8 (910B 有三個版本 910B1、2、3) 模型:DeepSeek-R1-Distill-Qwen-14B、DeepSeek…

【前端】Vue組件庫之Element: 一個現代化的 UI 組件庫

文章目錄 前言一、官網1、官網主頁2、設計原則3、導航4、組件 二、核心功能:開箱即用的組件生態1、豐富的組件體系2、特色功能亮點 三、快速上手:三步開啟組件化開發1、安裝(使用Vue 3)2、全局引入3、按需導入(推薦&am…

關于uniApp的面試題及其答案解析

我的血液里流淌著戰意!力量與智慧指引著我! 文章目錄 1. 什么是uniApp?2. uniApp與原生小程序開發有什么區別?3. 如何使用uniApp實現條件編譯?4. uniApp支持哪些平臺,各有什么特點?5. 在uniApp中…

Ubuntu 下 nginx-1.24.0 源碼分析 - ngx_pool_t 類型

ngx_pool_t 定義在 src/core/ngx_core.h typedef struct ngx_pool_s ngx_pool_t; ngx_pool_s 定義在 src/core/ngx_palloc.h struct ngx_pool_s {ngx_pool_data_t d;size_t max;ngx_pool_t *current;ngx_chain_t *chain;ng…

力扣 最長遞增子序列

動態規劃,二分查找。 題目 由題,從數組中找一個最長子序列,不難想到,當這個子序列遞增子序列的數越接近時是越容易拉長的。從dp上看,當遍歷到這個數,會從前面的dp選一個最大的數加上當前數,注意…

Linux | 進程控制(進程終止與進程等待)

文章目錄 Linux | 進程控制 — 進程終止 & 進程等待1、進程終止進程常見退出方法1.1退出碼基本概念獲取退出碼的方式常見退出碼約定使用場景 1.2 strerror函數 & errno宏1.3 _exit函數1.4_exit和exit的區別1.4.1 所屬頭文件與函數原型1.4.2 執行過程差異**結合現象分析…

Android - Handler使用post之后,Runnable沒有執行

問題:子線程創建的Handler。如果 post 之后,在Handler.removeCallbacks(run)移除了,下次再使用Handler.postDelayed(Runnable)接口或者使用post時,Runnable是沒有執行。導致沒有收到消息。 解決辦法:只有主線程創建的…

魚皮面試鴨30天后端面試營

day1 1. MySQL的索引類型有哪些? MySQL里的索引就像是書的目錄,能幫數據庫快速找到你要的數據。以下是各種索引類型的通俗解釋: 按數據結構分 B樹索引:最常用的一種,數據像在一棵樹上分層存放,能快速定位范圍數據…

【核心算法篇十二】《深入解剖DeepSeek多任務學習:共享表示層的24個設計細節與實戰密碼 》

引言:為什么你的模型總在"精神分裂"? 想象你訓練了一個AI實習生: 早上做文本分類時準確率90%下午做實體識別卻把"蘋果"都識別成水果公司晚上做情感分析突然開始輸出亂碼這就是典型的任務沖突災難——模型像被不同任務"五馬分尸"。DeepSeek通…

DeepSeek應用——與PyCharm的配套使用

目錄 一、配置方法 二、使用方法 三、注意事項 1、插件市場無continue插件 2、無結果返回,且在本地模型報錯 記錄自己學習應用DeepSeek的過程,使用的是自己電腦本地部署的私有化蒸餾模型...... (舉一反三,這個不單單是可以用…

2025最新智能優化算法:改進型雪雁算法(Improved Snow Geese Algorithm, ISGA)求解23個經典函數測試集,MATLAB

一、改進型雪雁算法 雪雁算法(Snow Geese Algorithm,SGA)是2024年提出的一種新型元啟發式算法,其靈感來源于雪雁的遷徙行為,特別是它們在遷徙過程中形成的獨特“人字形”和“直線”飛行模式。該算法通過模擬雪雁的飛行…

vscode通過ssh連接服務器實現免密登錄+刪除

文章目錄 參考: 1、 vscode通過ssh連接服務器實現免密登錄刪除(吐血總結)

MySQL 主從復制原理及其工作過程

一、MySQL主從復制原理 MySQL 主從復制是一種將數據從一個 MySQL 數據庫服務器(主服務器,Master)復制到一個或多個 MySQL 數據庫服務器(從服務器,Slave)的技術。以下簡述其原理,主要包含三個核…

【趙渝強老師】Spark RDD的緩存機制

Spark RDD通過persist方法或cache方法可以將計算結果的緩存,但是并不是這兩個方法被調用時立即緩存,而是觸發后面的action時,該RDD才會被緩存在計算節點的內存中并供后面重用。下面是persist方法或cache方法的函數定義: def pers…

設計模式相關知識點

目錄 設計模式 設計模式 代碼設計原則 設計模式 設計模式 干掉if...else,最好用的3種設計模式! | 小傅哥 bugstack 蟲洞棧 代碼設計原則-CSDN博客 23種設計模式-CSDN博客 策略模式(Strategy Pattern)-CSDN博客 責任鏈模式…

ShenNiusModularity項目源碼學習(9:項目結構)

ShenNiusModularity源碼主要有11個project(其實還有officialweb、test兩個文件夾,大致有4、5個project,但看著跟主要項目代碼沒太大關系,暫時不管),這11個project的依賴關系如下圖所示,其中最下…

ubuntu22.4搭建單節點es8.1

下載對應的包 elasticsearch-8.1.1-linux-x86_64.tar.gz 創建es租戶 groupadd elasticsearc useradd elasticsearch -g elasticsearch -p elasticsearch chmod uw /etc/sudoers chmod -R elasticsearch:elasticsearch elasticsearch 修改配置文件 vim /etc/sysctl.conf vm…

Docker 部署 ollama + DeepSeek

拉取并運行 Ollama Docker 鏡像 使用以下命令從 Docker Hub 拉取 Ollama 鏡像并運行容器: docker run -d -p 11434:11434 --name ollama ollama/ollama -d:以守護進程模式運行容器,即讓容器在后臺運行。-p 11434:11434:將容器內…

解決DeepSeek服務器繁忙的有效方法

全球42%的企業遭遇過AI工具服務器過載導致內容生產中斷(數據來源:Gartner 2025)。當競品在凌晨3點自動發布「智能家居安裝指南」時,你的團隊可能正因DeepSeek服務器繁忙錯失「凈水器保養教程」的流量黃金期?。147SEO智能調度系統…