Llama-2 vs. Llama-3:利用微型基準測試(井字游戲)評估大模型

編者按: 如何更好地評估和比較不同版本的大語言模型?傳統的學術基準測試固然重要,但往往難以全面反映模型在實際應用場景中的表現。在此背景下,本文作者別出心裁,通過讓 Llama-2 和 Llama-3 模型進行井字游戲對決,為我們提供了一個新穎而有趣的模型評估視角。

此文不僅展示了一種創新的模型比較方法,更揭示了當前大語言模型在處理看似簡單的空間邏輯任務時所面臨的挑戰。讓我們得以一窺不同參數規模模型的表現差異,以及新一代模型相較前代的進步與不足。

尤為值得關注的是,即便是參數量達到 70B 的大模型,在面對井字游戲這樣的基礎任務時仍會出現一些令人意外的錯誤。這一發現不僅為大語言模型的能力邊界劃定提供了新的參考,也為未來模型的優化方向指明了道路。

我們希望這篇文章能夠啟發讀者思考:在評估人工智能模型時,我們是否應該更多地關注那些看似簡單卻能深入考察模型認知能力的任務?同時,如何設計更多類似“井字游戲”的“微型基準測試“,以更加全面而直觀地評估模型性能?

作者 | Dmitrii Eliuseev

編譯 | 岳揚

在這里插入圖片描述
Image by Solstice Hannan, Unsplash(https://unsplash.com/@darkersolstice)

就在我撰寫這篇文章的大約一周前,Meta 推出了新的開源模型 Llama-3[1] 。他們宣稱這是“當前在 8B 與 70B 參數量級下的最好模型”。通過 HuggingFace 平臺的模型頁面[2]可以看到,Llama-3 8B 在 MMLU(Massive Multitask Language Understanding) 基準測試上的表現,以 66.6 的得分超越了 Llama-2 7B 的 45.7 ;而在 CommonSense QA(dataset for commonsense question answering)上進行評估,Llama-3 同樣領先,分別以 72.6 和 57.6 的得分戰勝了對手。有一款經過特殊指令數據微調(instruction-tuned)的 Llama-3 8B 模型尤其值得一提,在數學基準測試中的表現得分從 3.8 躍升至 30.0,這一進步令人印象深刻。

通過學術基準測試(Academic benchmarks)進行大模型評估固然很重要,但親眼見證它們的實際表現豈不更加直觀且更有趣?答案是肯定的,而且這種體驗往往妙趣橫生。設想一下,如果讓兩個模型進行一場經典的井字棋對決(tic-tac-toe game),勝負究竟如何?在接下來的游戲環節中,我將全面測試 7B、8B以及70B 等參數規格的模型。與此同時,我還會記錄下模型的性能指標及系統配置要求。

話不多說,讓我們即刻啟程,一探究竟!

01 加載模型

為了全面測試這些模型,我選擇使用 Python 庫Llama-cpp[3] 進行測試,該工具的一大優點在于其既能適應 CPU 環境,也能在 GPU 上高效運行。我們需要并行運行兩個 LLM。好消息是,無論是 7B 還是 8B 的模型,都能在 Google Colab 的 16GB GPU 環境中順暢運行。然而,當面對 70B 參數級別的龐大模型時,我們不得不退而求其次,轉而使用 CPU 進行測試,因為即便是頂級的 NVIDIA A100 顯卡,其內存容量也難以承擔起同時運行兩個此類巨無霸模型的重任。

首先需要我們先動手安裝 Llama-cpp,緊接著下載 7B 與 8B 參數級別的這兩個模型。至于 70B 參數級別的模型,其操作流程基本一致,唯一的區別僅在于替換其下載鏈接而已。

!CMAKE_ARGS="-DLLAMA_CUBLAS=on" FORCE_CMAKE=1 pip3 install llama-cpp-python -U
!pip3 install huggingface-hub hf-transfer sentence-transformers!export HF_HUB_ENABLE_HF_TRANSFER="1" && huggingface-cli download TheBloke/Llama-2-7B-Chat-GGUF llama-2-7b-chat.Q4_K_M.gguf --local-dir /content --local-dir-use-symlinks False
!export HF_HUB_ENABLE_HF_TRANSFER="1" && huggingface-cli download QuantFactory/Meta-Llama-3-8B-Instruct-GGUF Meta-Llama-3-8B-Instruct.Q4_K_M.gguf --local-dir /content --local-dir-use-symlinks False

模型下載完成后,接下來就需要正式啟動這些模型了:

from llama_cpp import Llamallama2 = Llama(model_path="/content/llama-2-7b-chat.Q4_K_M.gguf",n_gpu_layers=-1,n_ctx=1024,echo=False
)
llama3 = Llama(model_path="/content/Meta-Llama-3-8B-Instruct.Q4_K_M.gguf",n_gpu_layers=-1,n_ctx=1024,echo=False
)

接下來,我們著手創建一個函數,用于處理和執行各種提示詞信息:

def llm_make_move(model: Llama, prompt: str) -> str:""" Call a model with a prompt """res = model(prompt, stream=False, max_tokens=1024, temperature=0.8)return res["choices"][0]["text"]

02 Prompts

現在,我們來編寫代碼實現井字游戲(Tic-Tac-Toe)。在棋盤上交替放置“X”和“O”,首位成功在任意一行、一列或對角線上連成一線的玩家即為勝者:

在這里插入圖片描述

Image source Wikipedia(https://en.wikipedia.org/wiki/Tic-tac-toe)

正如我們所見,這個游戲對于人類來說非常簡單,但對語言模型而言可能頗具挑戰;要走出正確的一步棋,需要理解棋盤空間、物體之間的關系,甚至還會涉及一些簡單的數學知識。

首先,我們將棋盤編碼為一個二維數組。同時也會創建一個函數方法用于將棋盤轉換成字符串形式:

board = [["E", "E", "E"],["E", "E", "E"],["E", "E", "E"]]def board_to_string(board_data: List) -> str:""" Convert board to the string representation """return "\n".join([" ".join(x) for x in board_data])

輸出結果如下:

E E E
E E E
E E E

現在,我們可以創建模型提示詞(model prompts)了:

sys_prompt1 = """You play a tic-tac-toe game. You make a move by placing X, your opponent plays by placing O. Empty cells are marked with E. You can place X only to the empty cell."""
sys_prompt2 = """You play a tic-tac-toe game. You make a move by placing O, your opponent plays by placing X. Empty cells are marked with E. You can place O only to the empty cell."""
game_prompt = """What is your next move? Think in steps. Each row and column should be in range 1..3. Writethe answer in JSON as {"ROW": ROW, "COLUMN": COLUMN}."""

在這里,我為模型 1 和模型 2 分別創建了兩個提示詞(prompt)。我們可以看到,這兩個句子幾乎是相同的。唯一不同的是,第一個模型在“棋盤”上放置“X”,而第二個模型則放置“O”。

Llama-2 和 Llama-3 的提示詞格式有所不同:

template_llama2 = f"""<s>[INST]<<SYS>>{sys_prompt1}<</SYS>>
Here is the board image:
__BOARD__\n
{game_prompt}
[/INST]"""template_llama3 = f"""<|begin_of_text|>
<|start_header_id|>system<|end_header_id|>{sys_prompt2}<|eot_id|>
<|start_header_id|>user<|end_header_id|>
Here is the board image:
__BOARD__\n
{game_prompt}
<|eot_id|>
<|start_header_id|>assistant<|end_header_id|>"""

當然,我們可以創建兩個函數方法來利用這些提示詞(prompts),其中一個函數方法針對 Llama-2 ,另一個則針對 Llama-3 。

def make_prompt_llama2(board: List) -> str:""" Make Llama-2 prompt """return template_llama2.replace("__BOARD__", board_to_string(board))def make_prompt_llama3(board: List) -> str:""" Make Llama-3 prompt """return template_llama3.replace("__BOARD__", board_to_string(board))

03 Coding the Game

我們已經為構建該井字游戲(Tic-Tac-Toe)準備好了所有的提示詞信息,接下來該進入此游戲的編碼階段了。在某一個提示詞中,我要求模型以 JSON 格式提供模型響應。在實際操作中,模型可以回答這個問題:

My next move would be to place my X in the top-right corner, on cell (3, 1).
{
"ROW": 3,
"COLUMN": 1
}

現在,我們開始著手設計一個函數方法,用于從這類字符串中抽取出 JSON 數據:

def extract_json(response: str) -> Optional[dict]:""" Extract dictionary from a response string """try:# Models sometimes to a mistake, fix: {ROW: 1, COLUMN: 2} => {"ROW": 1, "COLUMN": 2}response = response.replace('ROW:', '"ROW":').replace('COLUMN:', '"COLUMN":')# Extract json from a responsepos_end = response.rfind("}")pos_start = response.rfind("{")return json.loads(response[pos_start:pos_end+1])except Exception as exp:print(f"extract_json::cannot parse output: {exp}")return None

結果發現,LLaMA-2 生成的模型響應并非總是有效的 JSON 格式;它經常會生成類似 “{ROW: 3, COLUMN: 3}” 這樣的模型響應。如上述代碼塊所示,在這種情況下,我會補全字符串中的缺失的引號,確保其格式正確。

獲得棋盤的行數和列數后,我們就能對該棋盤進行更新了:

def make_move(board_data: List, move: Optional[dict], symb: str):""" Update board with a new symbol """row, col = int(move["ROW"]), int(move["COLUMN"])if 1 <= row <= 3 and 1 <= col <= 3:if board_data[row - 1][col - 1] == "E":board_data[row - 1][col - 1] = symbelse:print(f"Wrong move: cell {row}:{col} is not empty")else:print("Wrong move: incorrect index")

在更新棋盤狀態后,下一步應當判斷游戲是否達到結束條件。

def check_for_end_game(board_data: List) -> bool:""" Check if there are no empty cells available """return board_to_string(board_data).find("E") == -1def check_for_win(board_data: List) -> bool:""" Check if the game is over """# Check Horizontal and Vertical linesfor ind in range(3):if board_data[ind][0] == board_data[ind][1] == board_data[ind][2] and board_data[ind][0] != "E":print(f"{board_data[ind][0]} win!")return Trueif board_data[0][ind] == board_data[1][ind] == board_data[2][ind] and board_data[0][ind] != "E":print(f"{board_data[0][ind]} win!")return True# Check Diagonalsif board_data[0][0] == board_data[1][1] == board_data[2][2] and board_data[1][1] != "E" or \board_data[2][0] == board_data[1][1] == board_data[0][2] and board_data[1][1] != "E":print(f"{board_data[1][1]} win!")return Truereturn False

在此代碼邏輯中,會循環檢查棋盤的水平線、垂直線和對角線,判斷是否出現勝利的一方。也許可能存在更為簡潔的解法,但當前這種方法足以應對目前的需求。

現在,所有必要組件都已準備完畢。接下來,我們將這些組件整合在一起:

num_wins1, num_wins2 = 0, 0
times_1, times_2 = [], []def run_game():""" Run a game between two models """board = [["E", "E", "E"],["E", "E", "E"],["E", "E", "E"]]moves_limit = 20for step in range(moves_limit):print(f"Step {step+1}")# Move: Model-1t_start = time.monotonic()prompt = make_prompt_llama2(board)result_str = llm_make_move(llama2, prompt)times_1.append(time.monotonic() - t_start)new_data = extract_json(result_str)if new_data is not None:make_move(board, new_data, symb="X")if check_for_win(board):print('**Model 1 Won**')num_wins1 += 1breakif check_for_end_game(board):break# Move: Model-2t_start = time.monotonic()prompt = make_prompt_llama3(board)result_str = llm_make_move(llama3, prompt)times_2.append(time.monotonic() - t_start)new_data = extract_json(result_str)if new_data is not None:make_move(board, new_data, symb="O")if check_for_win(board):print('**Model 2 Won**')num_wins2 += 1breakif check_for_end_game(board):breakprint()

同時,我還記錄了每個步驟的執行耗時,以及各個模型在游戲中的獲勝次數。

04 Results

說到實驗結果,確實很有趣。

對于參數規模為 7B 和 8B 的模型,完成井字游戲似乎比較有挑戰性。7B 的 Llama-2 模型雖然對游戲規則有所認知,但它卻沒能準確理解棋盤坐標的含義,導致常常將“X”標記置于不當之處。

下面是一些具體的 Prompt 與模型響應示例:

>>> Prompt:<s>[INST]<<SYS>>You play a tic-tac-toe game. You make a move by placing X, 
your opponent plays by placing O. Empty cells are marked with E.
You can place X only to the empty cell.<</SYS>>
Here is the board image:
X X O
X O E
E E EWhat is your next move? Think in steps. 
Each row and column should be in range 1..3. 
Write the answer in JSON as {"ROW": ROW, "COLUMN": COLUMN}.
[/INST]>>> Response:Since there are no empty cells on the board, I will place my X in the 
center cell: { "ROW": 2, "COLUMN": 1 }.

根據上文的響應內容,我們可以看到,這段模型響應中存在多個錯誤。首先,棋盤上還有許多空位可選;其次,坐標 (2,1) 并不是棋盤的中心;最后,給出的殘局中,初始狀態那個位置本身就有棋子,并非空缺。

相比之下,參數規模為 70B 的 LLaMA-2 模型整體表現更佳,然而它也并非完美無瑕,依舊存在不少錯誤。以下為一個極具代表性的 prompt 與模型響應案例:

>>> Prompt:<s>[INST]<<SYS>>You play a tic-tac-toe game. You make a move by placing X, 
your opponent plays by placing O. Empty cells are marked with E.
You can place X only to the empty cell.<</SYS>>
Here is the board image:
O E E
E X E
E E E...>>> Response:My next move would be to place my X in the center cell, which is empty.
Here is the updated board:O E E
E X X
E E EJSON representation of my move: {"ROW": 2, "COLUMN": 2}

可以看到,參數規格為 70B 的模型確實找到了“中心”位置,但相關“棋子”?的位置放置決策卻是錯的;該模型似乎并未“意識到”中間的格子其實已經被占用了。該模型甚至嘗試重新“描繪”棋盤,但這番“修改”同樣也是錯誤的。

令人啼笑皆非的是,ChatGPT 3.5 面對同一問題也給出了錯誤解答,同樣得出了中心位置為 {“ROW”: 2, “COLUMN”: 2} 的結論。不過,LLaMA-3 70B 卻成功避免了這個陷阱。即便如此,它還是會犯類似的錯誤,偶爾會在已經有“棋子”的格子里再次放置“棋子”。遺憾的是,我沒有統計每款模型的具體錯誤次數,這是一個值得后續關注的改進點。

如果用柱狀圖來展示,7B 和 8B 模型的表現數據大致如下:

在這里插入圖片描述

Game score for 7B and 8B models, Image by author

結果顯而易見:Llama-3 以 10:0 的大比分獲勝!

同時,我們可以觀察到兩組模型在搭載 16 GB NVIDIA T4 GPU 的設備上的推理耗時情況:

在這里插入圖片描述
在這里插入圖片描述

Inference time for 7B and 8B models, Image by author

略有不足的是,Llama-3 的運行速度相比前一代模型略慢(分別為 2.5 秒和 4.3 秒)。然而實際上,4.3 秒的響應時間已經足夠優秀了,因為大多數情況下會采用流式處理(streaming),并且用戶通常也不會期待立刻獲得即時回答。

至于參數規格為 70B 的 Llama-2 模型,它的表現更佳,能夠勝出兩次,但即便如此,在絕大多數情況下,Llama-3 仍然占據了上風。最終,在推理速度這方面,Llama-3 以 8:2 的比分獲勝!

在這里插入圖片描述

Game score for 70B models, Image by author

使用 CPU 進行大模型的推理運算時,由于 CPU 的計算能力和并行處理能力相對有限,其推理速度自然不會很快:

在這里插入圖片描述
Inference time, Image by author

完成十局游戲大約會耗費一個小時。雖然這個速度對于生產環境來說并不理想,但在測試階段還可以吧。有一點很有趣,Llama-cpp 采用了一種內存映射文件(memory-mapped file)的方式來加載模型,即便同時處理兩個 70B 參數級別的模型,其內存占用也控制在了 12GB 以內。這就表明,在僅配備 16GB RAM 的個人電腦上,我們同樣能夠順利地測試兩個 70B 模型(可惜這一招在 GPU 上行不通)。

05 Conclusion

在本文中,我安排兩組語言模型進行了一場別開生面的井字游戲對戰。有趣的是,這個看似簡單的“基準測試”實際上極具挑戰性。其考驗的不僅僅是模型對游戲規則的掌握,還涉及到了坐標系統以及使用字符串形式表達“空間”和“抽象思維”的能力,以此模擬二維棋盤。

從比賽結果來看,LLaMA-3 明顯是贏家。顯然,這款模型的表現更為出色,但我必須承認,兩款模型都在游戲中犯了很多錯誤。這一現象引人深思,暗示著即便是當前的大語言模型,在面對這個小巧卻非正式的“基準測試”時也會感到棘手,本文提出的 “Tic-Tac-Toe Battle” 基準測試無疑可為未來其他大模型的測試提供參考。

文中鏈接

[1]https://ai.meta.com/blog/meta-llama-3/

[2]https://huggingface.co/meta-llama/Meta-Llama-3-70B-Instruct

[3]GitHub - abetlen/llama-cpp-python: Python bindings for llama.cpp

Thanks for reading!

————

Dmitrii Eliuseev

Python/IoT developer and data engineer, data science and electronics enthusiast

https://www.linkedin.com/in/dmitrii-eliuseev/

原文鏈接:

https://towardsdatascience.com/llama-2-vs-llama-3-a-tic-tac-toe-battle-between-models-7301962ca65d

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

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

相關文章

【JavaScript腳本宇宙】無處不在的JavaScript庫:解析音視頻處理與實時通信技術

JavaScript庫大揭秘&#xff1a;音視頻、互動體驗與實時通信 前言 在當今互聯網時代&#xff0c;JavaScript已經成為前端開發中不可或缺的一部分。隨著Web技術的不斷發展&#xff0c;出現了許多優秀的JavaScript庫&#xff0c;為開發者提供了豐富的工具和資源。本文將介紹幾個…

STM32智能機器人手臂控制系統教程

目錄 引言環境準備智能機器人手臂控制系統基礎代碼實現&#xff1a;實現智能機器人手臂控制系統 4.1 數據采集模塊 4.2 數據處理與控制算法 4.3 通信與網絡系統實現 4.4 用戶界面與數據可視化應用場景&#xff1a;機器人手臂管理與優化問題解決方案與優化收尾與總結 1. 引言 …

Linux系統中磁盤管理LVM與掛載

Linux系統中磁盤管理LVM與掛載 本文以屬于Linux系統基本概念&#xff0c;如果以查找教程教程&#xff0c;解決問題為主&#xff0c;只需要查看本文后半部分。如需要系統性學習請查看本文前半部分。 本文操作極容易導致主機無法自動重啟&#xff0c;請慎重操作。操作前務必要進…

火熱夏季:浦語*書生InternLM大模型實戰闖關-入門島之Linux基礎知識

一、ssh鏈接與端口映射并運行hello_wold.py 1.創建開發機 InternStudio創建開發機 2.進入開發機 3.Ssh鏈接開發機 powerShell終端ssh鏈接開發機。 4.創建一個hello_world.py文件web demo 5.運行web demo 6.端口映射 7.本地瀏覽器打開web 二、 VSCODE 遠程連接開發機并創建一個…

【最強八股文 -- 計算機網絡】【快速版】TCP 與 UDP 頭部格式

目標端口和源端口: 應該把報文發給哪個進程包長度: UDP 首部的長度跟數據的長度之和校驗和: 為了提供可靠的 UDP 首部和數據而設計&#xff0c;接收方使用檢驗和來檢查該報文段中是否出現差錯 源端口號和目的端口號: 用于多路復用/分解來自或送到上層應用的數據。告訴主機報文段…

[機器學習]-人工智能對程序員的深遠影響——案例分析

機器學習和人工智能對未來程序員的深遠影響 目錄 機器學習和人工智能對未來程序員的深遠影響1. **自動化編碼任務**1.1 代碼生成1.2 自動調試1.3 測試自動化 2. **提升開發效率**2.1 智能建議2.2 項目管理 3. **改變編程范式**3.1 數據驅動開發 4. **職業發展的新機遇**4.1 AI工…

數字統計

import java.util.Scanner;// 注意類名必須為 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的區別// 注意 while 處理多個 caseint a in.nextInt();i…

基于深度學習的點云平滑

基于深度學習的點云平滑是一種利用深度學習模型處理和優化三維點云數據以消除噪聲并提升平滑度的方法。該技術在自動駕駛、機器人導航、3D重建和計算機圖形學等領域有著廣泛應用。以下是關于這一領域的系統介紹&#xff1a; 1. 任務和目標 點云平滑的主要任務是從帶有噪聲和粗…

【計算機畢業設計】基于Springboot的足球青訓俱樂部管理系統【源碼+lw+部署文檔】

包含論文源碼的壓縮包較大&#xff0c;請私信或者加我的綠色小軟件獲取 免責聲明&#xff1a;資料部分來源于合法的互聯網渠道收集和整理&#xff0c;部分自己學習積累成果&#xff0c;供大家學習參考與交流。收取的費用僅用于收集和整理資料耗費時間的酬勞。 本人尊重原創作者…

Day66 代碼隨想錄打卡|回溯算法篇---分割回文串

題目&#xff08;leecode T131&#xff09;&#xff1a; 給你一個字符串 s&#xff0c;請你將 s 分割成一些子串&#xff0c;使每個子串都是 回文串。返回 s 所有可能的分割方案。 方法&#xff1a;本題是一個分割回文串的問題&#xff0c;是回溯算法的另一類問題。 針對一個字…

前端面試題日常練-day82 【面試題】

題目 希望這些選擇題能夠幫助您進行前端面試的準備&#xff0c;答案在文末 在Sass中&#xff0c;以下哪個功能用于創建一個混合器&#xff08;Mixin&#xff09;&#xff1f; a) include b) loop c) function d) component Sass中的嵌套規則可以幫助實現以下哪個目的&#xf…

英偉達今年在華銷售額預計將達120億美元、MiniMax創始人:三年后才會出現“殺手級”AI應用

ChatGPT狂飆160天&#xff0c;世界已經不是之前的樣子。 更多資源歡迎關注 1、英偉達今年在華銷售額預計將達120億美元 芯片咨詢公司SemiAnalysis報告預估&#xff0c;今年英偉達有望在中國銷售價值約120億美元的人工智能芯片。黃仁勛曾表示&#xff0c;希望借助新的芯片使得…

【算法】十進制轉換為二進制

目的&#xff1a;將十進制轉換為二進制 思路&#xff1a; 首先我們手算的情況是通過求余數算出進制數&#xff0c;同樣代碼也是通過做除法和求余數的方式&#xff0c;除法是得出下一次的被除數&#xff0c;而求余數是得到進制數 代碼&#xff1a; #include<stdio.h>/…

python基礎語法筆記(有C語言基礎之后)

input()用于輸入&#xff0c;其有返回值&#xff08;即用戶輸入的值&#xff09;&#xff0c;默認返回字符串。括號里可放提示語句 一行代碼若想分為多行來寫&#xff0c;需要在每一行的末尾加上“\” 單個“/”表示數學中的除法&#xff0c;不會取整。“//”才會向下取整。 …

Qt觸發paintEvent事件

常見情況下&#xff0c;paintEvent會在以下幾種情況下被觸發&#xff1a; 窗口初始化和顯示&#xff1a; 當窗口首次被創建、顯示或者窗口被覆蓋、最小化后再恢復時&#xff0c;paintEvent會被觸發以繪制窗口的內容。 部件大小或位置變化&#xff1a; 如果窗口或部件的大小或位…

【D3.js in Action 3 精譯】1.3 D3 視角下的數據可視化最佳實踐(上)

當前內容所在位置 第一部分 D3.js 基礎知識 第一章 D3.js 簡介 1.1 何為 D3.js&#xff1f;1.2 D3 生態系統——入門須知 1.2.1 HTML 與 DOM1.2.2 SVG - 可縮放矢量圖形1.2.3 Canvas 與 WebGL1.2.4 CSS1.2.5 JavaScript1.2.6 Node 與 JavaScript 框架1.2.7 Observable 記事本 1…

Redis 運維面試題

為了做好大家面試路上的助攻手&#xff0c;對于 Redis 這塊心里還沒底的同學&#xff0c;特整理 40 道Redis常見面試題&#xff0c;讓你面試不慌&#xff0c;爭取 Offer 拿到手軟&#xff01; 1、什么是 Redis&#xff1f; Redis 是完全開源免費的&#xff0c;遵守 BSD 協議&am…

C++的線程管理

C的線程管理 線程類&#xff08;Thread&#xff09;線程構造器約定構造器初始化構造器復制構造器移動構造器 多線程atomiccondition_variable應用實列 futurepromise應用實列 future應用實列 線程類&#xff08;Thread&#xff09; 執行線程是一個指令序列&#xff0c;它可以在…

Canvas:實現在線畫板操作

想象一下&#xff0c;用幾行代碼就能創造出如此逼真的圖像和動畫&#xff0c;仿佛將藝術與科技完美融合&#xff0c;前端開發的Canvas技術正是這個數字化時代中最具魔力的一環&#xff0c;它不僅僅是網頁的一部分&#xff0c;更是一個無限創意的畫布&#xff0c;一個讓你的想象…

python網絡爬蟲之Urllib

概述 urllib的request模塊提供了最基本的構造HTTP請求的方法&#xff0c;使用它可以方便地實現請求的發送并得到響應&#xff0c;同時它還帶有處理授權驗證&#xff08;authentication&#xff09;、重定向&#xff08;redirection&#xff09;、瀏覽器Cookies以及其他內容。 …