《前后端面試題
》專欄集合了前后端各個知識模塊的面試題,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,SQL,Linux… 。
文章目錄
- 一、本文面試題目錄
- 136. 什么是HTTP協議?常用的HTTP方法有哪些?
- 137. `urllib`和`requests`庫的區別是什么?
- 138. 如何使用`socket`模塊實現簡單的TCP客戶端和服務器?
- 139. 什么是RESTful API?如何設計RESTful接口?
- 140. 簡述Django的MTV架構。
- 141. Django和Flask的區別是什么?
- 142. 什么是中間件(Middleware)?Django中間件的作用?
- 143. Flask中如何使用藍圖(Blueprint)?
- 144. 如何處理HTTP請求中的Cookie和Session?
- 145. 什么是WebSocket?它與HTTP有何區別?
- 146. 什么是單元測試?如何使用`unittest`或`pytest`進行單元測試?
- 原理說明
- 示例代碼
- 1. 使用`unittest`
- 2. 使用`pytest`
- 147. 什么是文檔字符串(Docstring)?它的作用是什么?
- 原理說明
- 示例代碼
- 148. 如何實現Python代碼的打包和分發(如`setup.py`)?
- 原理說明
- 示例代碼
- 1. 項目結構
- 2. `setup.py`配置
- 3. 打包與分發步驟
- 149. 解釋Python中的垃圾回收機制(GC)。
- 原理說明
- 示例代碼
- 150. 你在項目中使用Python解決過哪些實際問題?請舉例說明。
- 示例1:數據清洗與分析工具
- 示例2:定時任務監控系統
- 二、150道Python面試題目錄列表
一、本文面試題目錄
136. 什么是HTTP協議?常用的HTTP方法有哪些?
原理說明:
HTTP(HyperText Transfer Protocol,超文本傳輸協議)是用于在客戶端和服務器之間傳輸數據的應用層協議,基于TCP/IP通信,采用請求-響應模式,無狀態(每次請求獨立,不保留上下文)。
常用HTTP方法:
方法 | 作用 | 特點 |
---|---|---|
GET | 請求獲取資源 | 冪等(多次請求結果一致),參數在URL中,有長度限制 |
POST | 提交數據到服務器(如表單提交) | 非冪等,參數在請求體中,無長度限制 |
PUT | 全量更新資源 | 冪等,需提供資源完整數據 |
PATCH | 部分更新資源 | 非冪等,僅提供需修改的字段 |
DELETE | 刪除指定資源 | 冪等 |
HEAD | 類似GET,但僅返回響應頭 | 用于檢查資源是否存在或獲取元數據 |
OPTIONS | 獲取服務器支持的HTTP方法 | 跨域請求時用于預檢 |
示例:
- GET請求:
https://api.example.com/users
(獲取用戶列表) - POST請求:向
https://api.example.com/users
提交{"name":"Alice"}
(創建用戶)
137. urllib
和requests
庫的區別是什么?
原理說明:
兩者都是Python用于HTTP請求的庫,urllib
是標準庫,requests
是第三方庫(需安裝),后者API更簡潔,功能更豐富。
核心區別:
特性 | urllib | requests |
---|---|---|
所屬 | 標準庫(無需安裝) | 第三方庫(需pip install requests ) |
API設計 | 較繁瑣(需構造Request 對象) | 簡潔(如requests.get() ) |
會話管理 | 需手動處理CookieJar | 內置Session 對象自動維護Cookie |
響應處理 | 需手動解碼(如response.read().decode() ) | 自動解碼(response.text ) |
異常處理 | 較復雜(需捕獲URLError 等) | 統一的RequestException |
支持功能 | 基礎HTTP操作 | 支持會話、代理、SSL驗證、文件上傳等 |
示例對比:
-
GET請求
# urllib from urllib.request import urlopen response = urlopen("https://www.baidu.com") print(response.read().decode('utf-8'))# requests import requests response = requests.get("https://www.baidu.com") print(response.text) # 自動解碼
-
帶參數的POST請求
# urllib from urllib.request import Request, urlopen from urllib.parse import urlencode data = urlencode({"name": "Alice"}).encode('utf-8') request = Request("https://api.example.com", data=data, method="POST") response = urlopen(request)# requests response = requests.post("https://api.example.com", data={"name": "Alice"})
總結:requests
語法更簡潔,推薦用于大多數HTTP請求場景;urllib
適合無第三方庫依賴的環境。
138. 如何使用socket
模塊實現簡單的TCP客戶端和服務器?
原理說明:
TCP(Transmission Control Protocol)是面向連接的可靠傳輸協議,通過三次握手建立連接,四次揮手關閉連接。Python的socket
模塊提供了TCP通信的底層接口,可實現客戶端和服務器的雙向通信。
示例代碼:
-
TCP服務器
import socket# 創建TCP套接字(IPv4,TCP) server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 綁定IP和端口(空IP表示監聽所有網絡接口) server_address = ('', 8888) server_socket.bind(server_address)# 監聽連接(最大等待隊列長度為5) server_socket.listen(5) print("服務器啟動,等待連接...")while True:# 接受客戶端連接(阻塞)client_socket, client_addr = server_socket.accept()print(f"接收到來自{client_addr}的連接")try:# 接收客戶端數據(最多1024字節)data = client_socket.recv(1024)if data:print(f"收到數據:{data.decode('utf-8')}")# 發送響應response = "消息已收到:" + data.decode('utf-8')client_socket.sendall(response.encode('utf-8'))finally:# 關閉客戶端連接client_socket.close()print(f"與{client_addr}的連接已關閉")
-
TCP客戶端
import socket# 創建TCP套接字 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 連接服務器 server_address = ('localhost', 8888) client_socket.connect(server_address)try:# 發送數據message = "Hello, Server!"client_socket.sendall(message.encode('utf-8'))# 接收響應data = client_socket.recv(1024)print(f"收到服務器響應:{data.decode('utf-8')}") finally:# 關閉連接client_socket.close()
通信流程:
- 服務器:創建套接字 → 綁定端口 → 監聽 → 接受連接 → 收發數據 → 關閉連接。
- 客戶端:創建套接字 → 連接服務器 → 收發數據 → 關閉連接。
注意:實際應用中需處理異常(如連接中斷)和多客戶端并發(如使用多線程)。
139. 什么是RESTful API?如何設計RESTful接口?
原理說明:
RESTful API是一種基于REST(Representational State Transfer)架構風格設計的API,通過HTTP方法對資源進行操作,強調無狀態、資源導向和統一接口。
核心設計原則:
- 資源導向:用URL表示資源(如
/users
表示用戶列表),而非動作(避免/getUsers
)。 - 使用HTTP方法表達操作:
- GET:查詢資源(
/users/1
獲取ID=1的用戶) - POST:創建資源(
/users
創建新用戶) - PUT/PATCH:更新資源(
/users/1
更新用戶信息) - DELETE:刪除資源(
/users/1
刪除用戶)
- GET:查詢資源(
- 無狀態:服務器不存儲客戶端狀態,每次請求需包含所有必要信息。
- 返回合適的狀態碼:如200(成功)、201(創建成功)、404(資源不存在)、500(服務器錯誤)。
- 使用JSON作為數據交換格式。
設計示例:
接口 | HTTP方法 | 功能 | 響應狀態碼 |
---|---|---|---|
/api/users | GET | 獲取所有用戶 | 200 OK |
/api/users/1 | GET | 獲取ID=1的用戶 | 200 OK / 404 Not Found |
/api/users | POST | 創建新用戶(請求體含用戶數據) | 201 Created |
/api/users/1 | PUT | 全量更新用戶1 | 200 OK / 404 |
/api/users/1 | PATCH | 部分更新用戶1(如僅改姓名) | 200 OK / 404 |
/api/users/1 | DELETE | 刪除用戶1 | 204 No Content / 404 |
示例請求與響應:
- 創建用戶(POST
/api/users
):
請求體:{"name": "Alice", "age": 25}
響應:{"id": 1, "name": "Alice", "age": 25}
(狀態碼201)
140. 簡述Django的MTV架構。
原理說明:
Django是Python的Web框架,采用MTV(Model-Template-View)架構,是MVC(Model-View-Controller)的變種,目的是分離數據、界面和業務邏輯。
MTV各組件及作用:
-
Model(模型)
- 負責數據管理和數據庫交互,對應數據庫表結構。
- 使用Django ORM定義,自動映射到數據庫,無需編寫SQL。
- 示例:
# models.py from django.db import models class Book(models.Model):title = models.CharField(max_length=100)author = models.CharField(max_length=50)publish_date = models.DateField()
-
Template(模板)
- 負責用戶界面渲染,定義HTML頁面結構和展示邏輯。
- 支持模板繼承、變量替換、條件判斷等,分離業務邏輯和展示。
- 示例(
book_list.html
):<h1>圖書列表</h1> <ul>{% for book in books %}<li>{{ book.title }} - {{ book.author }}</li>{% endfor %} </ul>
-
View(視圖)
- 負責處理用戶請求、業務邏輯(如數據查詢、驗證),連接Model和Template。
- 接收請求,調用Model獲取數據,傳遞給Template渲染后返回響應。
- 示例:
# views.py from django.shortcuts import render from .models import Book def book_list(request):books = Book.objects.all() # 從Model獲取數據return render(request, 'book_list.html', {'books': books}) # 傳遞給Template
工作流程:
- 用戶發送HTTP請求到Django服務器。
- URL路由系統將請求分發到對應的View。
- View調用Model獲取或處理數據。
- View將數據傳遞給Template,生成HTML響應。
- 響應返回給用戶。
MTV架構通過分離關注點,使代碼更易維護、擴展和測試。
141. Django和Flask的區別是什么?
原理說明:
Django和Flask都是Python主流Web框架,但設計理念不同:Django是“全棧框架”(內置豐富功能),Flask是“微框架”(輕量靈活,需手動擴展)。
核心區別對比:
特性 | Django | Flask |
---|---|---|
定位 | 全棧框架(內置完整解決方案) | 微框架(輕量,按需擴展) |
內置功能 | ORM、Admin后臺、表單驗證、用戶認證、模板引擎、路由等 | 僅核心功能(路由、模板),其他需通過擴展(如Flask-SQLAlchemy ) |
靈活性 | 較低(遵循Django規范) | 較高(可自由選擇組件) |
學習曲線 | 較陡(功能多,概念復雜) | 較平緩(入門簡單) |
適用場景 | 大型復雜項目(如電商、CMS) | 小型應用、API服務、快速原型開發 |
模板引擎 | 內置Django Template | 依賴Jinja2(需單獨安裝) |
擴展方式 | 內置功能為主,第三方插件為輔 | 高度依賴第三方擴展 |
示例對比:
-
創建簡單頁面
# Django(需配置項目、應用、URL) # views.py from django.http import HttpResponse def hello(request):return HttpResponse("Hello, Django!")# Flask(單文件即可) from flask import Flask app = Flask(__name__) @app.route('/') def hello():return "Hello, Flask!" if __name__ == '__main__':app.run()
-
數據庫操作
# Django(內置ORM) from django.db import models class User(models.Model):name = models.CharField(max_length=50) user = User(name="Alice") user.save() # 自動寫入數據庫# Flask(需擴展Flask-SQLAlchemy) from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db' db = SQLAlchemy(app) class User(db.Model):id = db.Column(db.Integer, primary_key=True)name = db.Column(db.String(50)) db.create_all() user = User(name="Alice") db.session.add(user) db.session.commit()
總結:Django適合需要快速開發且功能全面的項目,Flask適合追求靈活和輕量的場景。
142. 什么是中間件(Middleware)?Django中間件的作用?
原理說明:
中間件是Web框架中位于請求和響應之間的處理層,用于在全局范圍內處理請求和響應(如身份驗證、日志記錄、跨域處理)。Django中間件通過鉤子函數介入請求-響應生命周期的各個階段。
Django中間件的作用:
- 預處理請求:在視圖函數執行前處理請求(如驗證Token、設置語言)。
- 后處理響應:在響應返回客戶端前處理(如添加響應頭、壓縮數據)。
- 全局異常處理:捕獲視圖函數拋出的異常,返回統一錯誤響應。
- 日志記錄:記錄所有請求的URL、耗時、狀態碼等信息。
Django中間件工作流程:
請求 → 中間件process_request
→ URL路由 → 中間件process_view
→ 視圖函數 → 中間件process_template_response
(若有) → 中間件process_response
→ 響應客戶端。
自定義中間件示例:
# myapp/middleware.py
class SimpleMiddleware:def __init__(self, get_response):self.get_response = get_response # 保存下一個中間件/視圖的引用def __call__(self, request):# 1. 請求到達視圖前執行(process_request)print(f"請求URL:{request.path}")start_time = time.time()# 調用下一個中間件或視圖response = self.get_response(request)# 2. 響應返回客戶端前執行(process_response)duration = time.time() - start_timeprint(f"請求耗時:{duration:.2f}秒")# 添加自定義響應頭response["X-Request-Duration"] = f"{duration:.2f}s"return responsedef process_exception(self, request, exception):# 3. 捕獲視圖拋出的異常print(f"發生異常:{str(exception)}")# 返回自定義錯誤響應return HttpResponse("服務器內部錯誤", status=500)
啟用中間件:
在settings.py
的MIDDLEWARE
列表中添加路徑:
MIDDLEWARE = [# ... 其他中間件 ...'myapp.middleware.SimpleMiddleware',
]
內置中間件示例:
django.middleware.csrf.CsrfViewMiddleware
:處理CSRF防護。django.contrib.auth.middleware.AuthenticationMiddleware
:管理用戶認證。
143. Flask中如何使用藍圖(Blueprint)?
原理說明:
藍圖(Blueprint)是Flask中用于模塊化組織路由、視圖和靜態資源的工具,可將大型應用拆分為多個子模塊(如用戶模塊、商品模塊),便于維護。
藍圖的作用:
- 拆分應用功能,實現代碼分離。
- 共享模板和靜態文件。
- 延遲注冊(可在應用初始化后注冊藍圖)。
使用示例:
-
創建藍圖(
auth.py
,用戶認證模塊)from flask import Blueprint, render_template, redirect, url_for# 創建藍圖('auth'為藍圖名稱,__name__為模塊名) auth_bp = Blueprint('auth', __name__, url_prefix='/auth') # 路由前綴# 定義藍圖路由 @auth_bp.route('/login') def login():return render_template('auth/login.html') # 模板默認查找templates/auth/目錄@auth_bp.route('/logout') def logout():return redirect(url_for('auth.login')) # 生成帶前綴的URL
-
創建主應用并注冊藍圖(
app.py
)from flask import Flask from auth import auth_bp # 導入藍圖app = Flask(__name__)# 注冊藍圖(所有路由會自動添加/auth前綴) app.register_blueprint(auth_bp)# 主應用路由 @app.route('/') def index():return "首頁"if __name__ == '__main__':app.run()
-
目錄結構
myapp/ ├── app.py # 主應用 ├── auth.py # 認證藍圖 └── templates/├── index.html # 主應用模板└── auth/ # 藍圖模板目錄└── login.html
訪問路由:
- 藍圖路由:
/auth/login
(對應auth_bp.route('/login')
) - 主應用路由:
/
(對應app.route('/')
)
高級用法:
- 藍圖可擁有獨立的靜態文件目錄(
static_folder
參數)。 - 可通過
url_for('藍圖名.視圖函數名')
生成藍圖路由URL。
藍圖是Flask構建大型應用的核心工具,通過模塊化組織使代碼結構更清晰。
144. 如何處理HTTP請求中的Cookie和Session?
原理說明:
Cookie和Session都是用于在客戶端和服務器之間保存狀態的機制(因HTTP無狀態),但存儲位置和安全性不同:
- Cookie:存儲在客戶端(瀏覽器),由服務器通過響應頭
Set-Cookie
設置,每次請求自動攜帶。 - Session:存儲在服務器,客戶端僅保存Session ID(通常通過Cookie傳遞),更安全。
處理方法示例:
-
使用Flask處理Cookie和Session
from flask import Flask, make_response, request, sessionapp = Flask(__name__) app.secret_key = 'secret_key_for_session' # Session需配置密鑰(加密用)# 處理Cookie @app.route('/set_cookie') def set_cookie():response = make_response("Cookie已設置")# 設置Cookie(鍵、值、過期時間(秒))response.set_cookie('username', 'Alice', max_age=3600)return response@app.route('/get_cookie') def get_cookie():# 獲取Cookie(默認None)username = request.cookies.get('username')return f"Cookie中的用戶名:{username}"# 處理Session @app.route('/set_session') def set_session():# 設置Session(自動加密存儲在服務器)session['user_id'] = 123session['username'] = 'Alice'return "Session已設置"@app.route('/get_session') def get_session():# 獲取Sessionuser_id = session.get('user_id')username = session.get('username')return f"Session:用戶ID={user_id},用戶名={username}"@app.route('/logout') def logout():# 清除Sessionsession.pop('user_id', None)session.pop('username', None)return "已退出登錄"
-
使用Django處理Cookie和Session
# Django視圖 from django.http import HttpResponse# 處理Cookie def set_cookie(request):response = HttpResponse("Cookie已設置")response.set_cookie('username', 'Bob', max_age=3600)return responsedef get_cookie(request):username = request.COOKIES.get('username')return HttpResponse(f"Cookie中的用戶名:{username}")# 處理Session(Django默認存儲在數據庫,可配置為Redis等) def set_session(request):request.session['user_id'] = 456request.session['username'] = 'Bob'return HttpResponse("Session已設置")def get_session(request):user_id = request.session.get('user_id')username = request.session.get('username')return HttpResponse(f"Session:用戶ID={user_id},用戶名={username}")
安全注意事項:
- Cookie存儲在客戶端,敏感信息(如密碼)不應存于Cookie。
- Session需使用密鑰加密(如Flask的
secret_key
),防止篡改。 - 重要Cookie可設置
secure=True
(僅HTTPS傳輸)和httpOnly=True
(禁止JS訪問,防XSS)。
145. 什么是WebSocket?它與HTTP有何區別?
原理說明:
WebSocket是一種在單個TCP連接上實現全雙工(雙向)通信的協議,允許客戶端和服務器實時交換數據,適合實時應用(如聊天、股票行情)。
與HTTP的區別:
特性 | HTTP | WebSocket |
---|---|---|
連接方式 | 單向請求-響應(客戶端主動請求,服務器被動響應) | 雙向持久連接(客戶端和服務器可隨時發送數據) |
連接狀態 | 無狀態(每次請求獨立) | 有狀態(連接建立后保持打開) |
通信效率 | 低(每次請求需攜帶完整HTTP頭) | 高(連接建立后僅傳輸數據,無冗余頭) |
適用場景 | 普通Web頁面、API請求(非實時) | 實時通信(如聊天、實時通知、游戲) |
協議標識 | http:// 或https:// | ws:// 或wss:// (加密) |
Python中使用WebSocket示例(websockets
庫):
-
安裝庫
pip install websockets
-
WebSocket服務器
import asyncio import websockets# 處理客戶端連接 async def handle_client(websocket):# 接收客戶端消息async for message in websocket:print(f"收到消息:{message}")# 發送響應(雙向通信)response = f"服務器已收到:{message}"await websocket.send(response)# 啟動服務器 start_server = websockets.serve(handle_client, "localhost", 8765) asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever()
-
WebSocket客戶端
import asyncio import websocketsasync def send_message():# 連接服務器async with websockets.connect("ws://localhost:8765") as websocket:# 發送消息message = "Hello, WebSocket!"await websocket.send(message)# 接收響應response = await websocket.recv()print(f"收到響應:{response}")asyncio.get_event_loop().run_until_complete(send_message())
工作流程:
- 客戶端通過HTTP握手請求升級協議(
Upgrade: websocket
)。 - 服務器同意后,HTTP連接升級為WebSocket連接。
- 雙方通過該連接實時雙向通信,直到一方關閉連接。
WebSocket解決了HTTP在實時通信場景下的低效問題,是構建實時Web應用的首選協議。
146. 什么是單元測試?如何使用unittest
或pytest
進行單元測試?
原理說明
- 單元測試:是對軟件中最小可測試單元(如函數、方法、類)進行的獨立驗證,目的是確保每個單元能按預期工作。
- 作用:提前發現bug、便于代碼重構、保障代碼質量。
- 常用框架:
unittest
:Python內置的單元測試框架,靈感來自Java的JUnit,支持斷言、測試用例組織、測試套件等。pytest
:第三方框架,語法更簡潔,支持unittest
兼容的用例,還提供更豐富的功能(如參數化、 fixtures)。
示例代碼
1. 使用unittest
# 待測試的函數
def add(a, b):return a + bdef is_even(n):return n % 2 == 0# 測試用例
import unittestclass TestMathFunctions(unittest.TestCase):# 測試前執行(可選)def setUp(self):print("開始測試...")# 測試add函數def test_add(self):self.assertEqual(add(2, 3), 5) # 斷言相等self.assertEqual(add(-1, 1), 0)# 測試is_even函數def test_is_even(self):self.assertTrue(is_even(4)) # 斷言為Trueself.assertFalse(is_even(7)) # 斷言為Falseself.assertRaises(TypeError, is_even, "string") # 斷言拋出異常# 測試后執行(可選)def tearDown(self):print("測試結束...")if __name__ == "__main__":unittest.main() # 運行測試
2. 使用pytest
需先安裝:pip install pytest
# 待測試的函數(同上)
def add(a, b):return a + bdef is_even(n):return n % 2 == 0# 測試用例(pytest無需繼承類,函數名以test_開頭即可)
def test_add():assert add(2, 3) == 5 # 直接使用assert斷言assert add(-1, 1) == 0def test_is_even():assert is_even(4) is Trueassert is_even(7) is Falsewith pytest.raises(TypeError): # 斷言拋出異常is_even("string")
運行方式:命令行執行pytest 文件名.py -v
(-v
顯示詳細信息)。
147. 什么是文檔字符串(Docstring)?它的作用是什么?
原理說明
- 文檔字符串(Docstring):是位于函數、類、模塊開頭的字符串,用于解釋其功能、參數、返回值、示例等信息。
- 格式:通常用三重引號(
"""
)包裹,支持單行和多行。 - 作用:
- 提高代碼可讀性,方便其他開發者理解代碼用途。
- 可通過
__doc__
屬性或help()
函數獲取文檔信息。 - 支持自動生成文檔工具(如Sphinx、pdoc)。
示例代碼
def calculate_area(radius):"""計算圓的面積。參數:radius (float): 圓的半徑,必須為正數。返回:float: 圓的面積(π * radius2)。異常:ValueError: 當半徑為負數或非數字時拋出。示例:>>> calculate_area(2)12.566370614359172"""if not isinstance(radius, (int, float)):raise ValueError("半徑必須是數字")if radius <= 0:raise ValueError("半徑必須為正數")return 3.1415926535 * radius ** 2# 獲取文檔字符串
print(calculate_area.__doc__) # 打印完整文檔
help(calculate_area) # 更友好的格式顯示文檔
148. 如何實現Python代碼的打包和分發(如setup.py
)?
原理說明
- 打包:將Python代碼、依賴、配置文件等整理成標準格式(如
.tar.gz
、.whl
),便于安裝和分發。 - 分發渠道:常用PyPI(Python Package Index),用戶可通過
pip install
安裝。 - 核心文件:
setup.py
:打包配置腳本,定義包名、版本、依賴等。setup.cfg
:補充配置(可選)。MANIFEST.in
:指定需要打包的非代碼文件(如文檔、數據)。
示例代碼
1. 項目結構
my_package/
├── my_package/ # 包目錄
│ ├── __init__.py
│ └── utils.py # 功能模塊
├── setup.py # 打包配置
└── README.md # 說明文檔
2. setup.py
配置
from setuptools import setup, find_packagessetup(name="my_package", # 包名(PyPI上需唯一)version="0.1.0", # 版本號(遵循語義化版本)author="Your Name",author_email="your@email.com",description="A sample Python package",long_description=open("README.md").read(), # 長描述(通常來自README)long_description_content_type="text/markdown",url="https://github.com/yourusername/my_package", # 項目地址packages=find_packages(), # 自動發現包install_requires=[ # 依賴列表"requests>=2.25.0","numpy>=1.19.0"],classifiers=[ # 分類信息(便于PyPI檢索)"Programming Language :: Python :: 3","License :: OSI Approved :: MIT License","Operating System :: OS Independent",],python_requires=">=3.6", # 支持的Python版本
)
3. 打包與分發步驟
# 生成源碼包和wheel包
python setup.py sdist bdist_wheel# 安裝到本地(開發模式,修改代碼無需重新安裝)
pip install -e .# 上傳到PyPI(需先注冊賬號,安裝twine工具)
pip install twine
twine upload dist/* # 輸入PyPI賬號密碼
149. 解釋Python中的垃圾回收機制(GC)。
原理說明
- 垃圾回收(GC):Python自動管理內存的機制,用于回收不再使用的對象所占用的內存,避免內存泄漏。
- 核心算法:
- 引用計數:每個對象有一個引用計數器,當引用數為0時,對象被立即回收。
- 觸發引用計數減少的情況:變量賦值給其他對象、函數執行結束局部變量銷毀、對象從容器中移除等。
- 標記-清除:解決循環引用問題(如兩個對象互相引用,引用計數不為0但已無用)。
- 標記:遍歷所有可達對象(從根對象出發能訪問到的對象),標記為“存活”。
- 清除:未被標記的對象被回收。
- 分代回收:基于“存活越久的對象越不可能被回收”的假設,將對象分為3代(0、1、2)。
- 新對象放入0代,回收頻率最高;存活的對象晉升到更高代,回收頻率降低。
- 引用計數:每個對象有一個引用計數器,當引用數為0時,對象被立即回收。
示例代碼
import gc# 查看GC是否啟用(默認啟用)
print(gc.isenabled()) # 輸出: True# 禁用GC(僅調試用)
gc.disable()
# 手動觸發GC
gc.collect()
# 啟用GC
gc.enable()# 循環引用示例(引用計數無法回收)
class Node:def __init__(self):self.next = None# 創建循環引用
a = Node()
b = Node()
a.next = b
b.next = a# 刪除引用(此時a和b的引用計數仍為1,因互相引用)
del a
del b# 手動回收循環引用的對象
gc.collect()
print(gc.garbage) # 輸出回收的對象列表(通常為空,因已被清理)
- 注意:Python的GC機制幾乎無需手動干預,但可通過
gc
模塊調整參數(如回收閾值)或強制回收。
150. 你在項目中使用Python解決過哪些實際問題?請舉例說明。
示例1:數據清洗與分析工具
- 問題:某電商平臺需要從多個Excel表格中提取銷售數據,清洗重復值、缺失值,并生成月度銷售報表。
- 解決方案:
- 使用
pandas
讀取Excel文件,合并多表數據。 - 用
pandas
的drop_duplicates()
去重,fillna()
填充缺失值。 - 用
matplotlib
/seaborn
繪制銷量趨勢圖、品類占比圖。 - 封裝成腳本,支持命令行傳入文件路徑,自動輸出清洗后的數據和報表。
- 使用
import pandas as pd
import matplotlib.pyplot as pltdef clean_and_analyze(file_paths):# 合并數據dfs = [pd.read_excel(path) for path in file_paths]combined = pd.concat(dfs, ignore_index=True)# 清洗數據combined = combined.drop_duplicates(subset=["訂單號"])combined["銷售額"] = combined["銷售額"].fillna(0)# 分析:月度銷售額combined["訂單日期"] = pd.to_datetime(combined["訂單日期"])combined["月份"] = combined["訂單日期"].dt.to_period("M")monthly_sales = combined.groupby("月份")["銷售額"].sum()# 繪圖monthly_sales.plot(kind="bar")plt.title("月度銷售額趨勢")plt.savefig("monthly_sales.png")# 保存清洗后的數據combined.to_excel("cleaned_sales.xlsx", index=False)return monthly_sales# 使用示例
if __name__ == "__main__":import sysfile_paths = sys.argv[1:] # 從命令行接收文件路徑clean_and_analyze(file_paths)
示例2:定時任務監控系統
- 問題:某系統需要定時檢查多個服務的可用性(如HTTP接口、數據庫連接),異常時發送郵件報警。
- 解決方案:
- 用
schedule
庫實現定時任務(如每5分鐘執行一次檢查)。 - 用
requests
檢查HTTP接口狀態,pymysql
檢查數據庫連接。 - 用
smtplib
發送報警郵件,包含異常詳情。
- 用
import schedule
import time
import requests
import pymysql
import smtplib
from email.mime.text import MIMEText# 配置
SERVICES = {"API服務": "https://api.example.com/health","數據庫": {"host": "db.example.com", "user": "admin", "password": "xxx"}
}
ALERT_EMAIL = "admin@example.com"def send_alert(message):"""發送報警郵件"""msg = MIMEText(message)msg["Subject"] = "服務異常報警"msg["From"] = "monitor@example.com"msg["To"] = ALERT_EMAILwith smtplib.SMTP("smtp.example.com", 587) as server:server.starttls()server.login("monitor@example.com", "password")server.send_message(msg)def check_service():"""檢查服務可用性"""for name, config in SERVICES.items():if isinstance(config, str): # HTTP服務try:response = requests.get(config, timeout=10)if response.status_code != 200:raise Exception(f"狀態碼異常: {response.status_code}")except Exception as e:send_alert(f"{name}異常: {str(e)}")else: # 數據庫服務try:conn = pymysql.connect(**config, timeout=10)conn.close()except Exception as e:send_alert(f"{name}異常: {str(e)}")# 定時任務:每5分鐘檢查一次
schedule.every(5).minutes.do(check_service)# 啟動監控
while True:schedule.run_pending()time.sleep(1)
- 效果:實現了自動化監控,減少人工干預,及時發現并處理服務故障。
二、150道Python面試題目錄列表
文章序號 | Python面試題150道 |
---|---|
1 | Python面試題及詳細答案150道(01-15) |
2 | Python面試題及詳細答案150道(16-30) |
3 | Python面試題及詳細答案150道(31-40) |
4 | Python面試題及詳細答案150道(41-55) |
5 | Python面試題及詳細答案150道(56-70) |
6 | Python面試題及詳細答案150道(71-80) |
7 | Python面試題及詳細答案150道(81-90) |
8 | Python面試題及詳細答案150道(91-100) |
9 | Python面試題及詳細答案150道(101-115) |
10 | Python面試題及詳細答案150道(116-125) |
11 | Python面試題及詳細答案150道(126-135) |
12 | Python面試題及詳細答案150道(136-150) |