- Cursor與Copilot開發(fā)實戰(zhàn)
- 未來智能實驗室 代晶編著
- 4888字
- 2025-07-11 16:36:24
1.4 初步實踐案例
本節(jié)將通過兩個具體的實踐案例,展示在實際開發(fā)中如何使用Cursor和Copilot提升開發(fā)效率。第一個案例將介紹如何使用Cursor輔助編寫一個基于鏈表的股票交易系統(tǒng),通過自動生成代碼片段,簡化數(shù)據(jù)結(jié)構(gòu)的設(shè)計與實現(xiàn)。第二個案例將展示如何利用Copilot編寫一個Windows端自動截圖應(yīng)用程序,通過智能提示和代碼補全,極大地加速開發(fā)過程。通過這些實踐,讀者將能夠更直觀地理解AI輔助編程工具如何在不同類型的開發(fā)任務(wù)中提供幫助,并了解如何有效地與AI協(xié)作進行項目開發(fā)。
1.4.1 實戰(zhàn):用Cursor輔助編寫基于鏈表的股票交易系統(tǒng)
【例1-12】使用Cursor輔助編寫一個基于鏈表的股票交易系統(tǒng)。
該系統(tǒng)包含的主要模塊有股票信息管理、交易記錄管理及訂單管理。通過Cursor的智能提示和代碼補全功能,可以大大提高開發(fā)效率,減少手動編碼的時間。
1.需求分析與功能設(shè)計
首先,需要確定股票交易系統(tǒng)的基本功能和數(shù)據(jù)結(jié)構(gòu)。該系統(tǒng)的基本功能包括以下幾項。
● 股票信息管理:存儲每只股票的基本信息,如股票代碼、股票名稱和當前價格。
● 訂單管理:管理買入和賣出的股票交易記錄。
● 交易記錄:記錄每筆交易的具體信息,包括交易時間、股票代碼、數(shù)量和交易價格。
為了滿足這些需求,系統(tǒng)中的數(shù)據(jù)結(jié)構(gòu)采用鏈表形式,其中每個節(jié)點對應(yīng)一條股票交易記錄。這樣一來,股票交易就可以在鏈表中靈活地插入和刪除,并且對不同股票的交易管理也變得更加方便。
2.使用Cursor輔助生成代碼
(1)定義數(shù)據(jù)結(jié)構(gòu)
首先,通過Cursor創(chuàng)建鏈表數(shù)據(jù)結(jié)構(gòu)。輸入Create a linked list to store stock trade information后,Cursor就自動生成了以下代碼框架:
public class StockTrade { private String stockCode; private String stockName; private double price; private int quantity; private StockTrade next; public StockTrade(String stockCode, String stockName, double price, int quantity) { this.stockCode = stockCode; this.stockName = stockName; this.price = price; this.quantity = quantity; this.next = null; } public void displayTrade() { System.out.println("Stock: " + stockName + " (" + stockCode + ")"); System.out.println("Price: " + price + " | Quantity: " + quantity); } } public class StockTradeList { private StockTrade head; public StockTradeList() { head = null; } public void addTrade(String stockCode, String stockName, double price, int quantity) { StockTrade newTrade = new StockTrade(stockCode, stockName, price, quantity); if (head == null) { head = newTrade; } else { StockTrade current = head; while (current.next != null) { current = current.next; } current.next = newTrade; } } public void displayAllTrades() { StockTrade current = head; while (current != null) { current.displayTrade(); current = current.next; } } }
? 理解代碼并梳理思路
StockTrade類代表一條股票交易記錄,包含股票代碼、名稱、價格、數(shù)量及指向下一個節(jié)點的指針next。
StockTradeList類管理股票交易記錄的鏈表,支持添加新交易和展示所有交易記錄。
(2)訂單管理功能
接下來,Cursor幫助生成了訂單管理模塊。在交易系統(tǒng)中,每個交易都有唯一的標識符(訂單ID),用于識別交易。輸入Generate methods for adding, removing, and updating trades后,Cursor自動生成了以下代碼:
public class StockTradeList { private StockTrade head; public StockTradeList() { head = null; } public void addTrade(String stockCode, String stockName, double price, int quantity) { StockTrade newTrade = new StockTrade(stockCode, stockName, price, quantity); if (head == null) { head = newTrade; } else { StockTrade current = head; while (current.next != null) { current = current.next; } current.next = newTrade; } } public void removeTrade(String stockCode) { if (head == null) return; if (head.stockCode.equals(stockCode)) { head = head.next; return; } StockTrade current = head; while (current.next != null && !current.next.stockCode.equals(stockCode)) { current = current.next; } if (current.next != null) { current.next = current.next.next; } } public void updateTrade(String stockCode, double newPrice, int newQuantity) { StockTrade current = head; while (current != null) { if (current.stockCode.equals(stockCode)) { current.price = newPrice; current.quantity = newQuantity; return; } current = current.next; } } public void displayAllTrades() { StockTrade current = head; while (current != null) { current.displayTrade(); current = current.next; } } }
? 理解代碼并梳理思路
removeTrade()方法實現(xiàn)了從鏈表中刪除特定股票交易記錄的功能。具體來說,就是根據(jù)股票代碼查找交易記錄,如果找到對應(yīng)的記錄,則刪除對應(yīng)的節(jié)點。
updateTrade()方法用于更新特定股票的交易信息。具體來說,就是根據(jù)股票代碼查找記錄,并更新股票的價格和數(shù)量。
(3)交易操作示例
開發(fā)者可以通過調(diào)用addTrade()、removeTrade()、updateTrade()等方法來模擬股票交易操作。以下是一個簡單的操作示例:
public class Main { public static void main(String[] args) { StockTradeList tradeList = new StockTradeList(); // 添加交易記錄 tradeList.addTrade("AAPL", "Apple Inc.", 150.00, 100); tradeList.addTrade("GOOGL", "Google LLC", 2800.00, 50); // 顯示所有交易記錄 System.out.println("All Trades:"); tradeList.displayAllTrades(); // 更新交易記錄 tradeList.updateTrade("AAPL", 155.00, 120); // 刪除交易記錄 tradeList.removeTrade("GOOGL"); // 顯示更新后的交易記錄 System.out.println("\nUpdated Trades:"); tradeList.displayAllTrades(); } }
? 理解代碼并梳理思路
該代碼示例首先添加了兩條股票交易記錄,然后通過updateTrade()方法更新Apple股票的價格和數(shù)量,接著使用removeTrade()方法刪除Google股票的交易記錄。最終,通過displayAllTrades()方法輸出所有更新后的交易記錄。
3.使用Cursor優(yōu)化代碼
使用Cursor時,開發(fā)者還可以通過代碼提示和代碼補全功能來優(yōu)化代碼。例如,在updateTrade()和removeTrade()方法中,開發(fā)者可能會希望增加異常處理機制,以防止在鏈表為空或沒有找到指定交易記錄的情況下程序出現(xiàn)錯誤。Cursor會根據(jù)輸入的上下文提示生成相應(yīng)的代碼:
public void updateTrade(String stockCode, double newPrice, int newQuantity) { StockTrade current = head; boolean found = false; while (current != null) { if (current.stockCode.equals(stockCode)) { current.price = newPrice; current.quantity = newQuantity; found = true; break; } current = current.next; } if (!found) { throw new IllegalArgumentException("Trade not found for stock: " + stockCode); } } public void removeTrade(String stockCode) { if (head == null) throw new IllegalStateException("Trade list is empty"); if (head.stockCode.equals(stockCode)) { head = head.next; return; } StockTrade current = head; while (current.next != null && !current.next.stockCode.equals(stockCode)) { current = current.next; } if (current.next == null) { throw new IllegalArgumentException("Trade not found for stock: " + stockCode); } current.next = current.next.next; }
? 理解代碼并梳理思路
在updateTrade()和removeTrade()方法中,增加了異常處理,從而確保當鏈表為空或沒有找到指定的交易記錄時能夠拋出適當?shù)腻e誤。
4.系統(tǒng)測試
為了對這個基于鏈表的股票交易系統(tǒng)進行測試,我們需要編寫測試函數(shù),檢查添加、更新、刪除、顯示等操作是否能如預期的那樣正常工作。以下是測試函數(shù)的實現(xiàn)以及測試結(jié)果的輸出:
public class StockTradeTest { public static void main(String[] args) { StockTradeList tradeList = new StockTradeList(); // 測試1:添加交易記錄 System.out.println("Test 1: Add Trades"); tradeList.addTrade("AAPL", "Apple Inc.", 150.00, 100); tradeList.addTrade("GOOGL", "Google LLC", 2800.00, 50); tradeList.displayAllTrades(); // 測試2:更新交易記錄 System.out.println("\nTest 2: Update Trade (AAPL)"); tradeList.updateTrade("AAPL", 155.00, 120); tradeList.displayAllTrades(); // 測試3:刪除交易記錄 System.out.println("\nTest 3: Remove Trade (GOOGL)"); tradeList.removeTrade("GOOGL"); tradeList.displayAllTrades(); // 測試4:嘗試刪除不存在的交易記錄 System.out.println("\nTest 4: Try to Remove Non-existent Trade (AMZN)"); try { tradeList.removeTrade("AMZN"); } catch (IllegalArgumentException e) { System.out.println("Exception: " + e.getMessage()); } // 測試5:嘗試更新不存在的交易記錄 System.out.println("\nTest 5: Try to Update Non-existent Trade (MSFT)"); try { tradeList.updateTrade("MSFT", 300.00, 100); } catch (IllegalArgumentException e) { System.out.println("Exception: " + e.getMessage()); } } }
測試結(jié)果如下:
Test 1: Add Trades Stock: Apple Inc. (AAPL) Price: 150.0 | Quantity: 100 Stock: Google LLC (GOOGL) Price: 2800.0 | Quantity: 50 Test 2: Update Trade (AAPL) Stock: Apple Inc. (AAPL) Price: 155.0 | Quantity: 120 Stock: Google LLC (GOOGL) Price: 2800.0 | Quantity: 50 Test 3: Remove Trade (GOOGL) Stock: Apple Inc. (AAPL) Price: 155.0 | Quantity: 120 Test 4: Try to Remove Non-existent Trade (AMZN) Exception: Trade not found for stock: AMZN Test 5: Try to Update Non-existent Trade (MSFT) Exception: Trade not found for stock: MSFT
關(guān)于上述測試的解釋和說明如下。
● 在“Test 1: Add Trades”中添加了兩筆交易記錄,一筆是Apple股票的,另一筆是Google股票的。系統(tǒng)成功顯示了這兩條記錄。
● 在“Test 2: Update Trade (AAPL)”中更新了Apple股票的交易信息(價格和數(shù)量)。更新后,Apple股票的信息被正確修改并顯示。
● 在“Test 3: Remove Trade (GOOGL)”中成功刪除了Google股票的交易記錄,只剩下Apple股票的交易記錄。
● 在“Test 4: Try to Remove Non-existent Trade (AMZN)”中嘗試刪除一條不存在的交易記錄(Amazon股票的交易記錄)。此時系統(tǒng)拋出了IllegalArgumentException,并顯示了對應(yīng)的錯誤消息“Trade not found for stock: AMZN”。
● 在“Test 5: Try to Update Non-existent Trade (MSFT)”中嘗試更新一條不存在的交易記錄(Microsoft股票的交易記錄)。系統(tǒng)也拋出了IllegalArgumentException,并顯示了對應(yīng)的錯誤消息“Trade not found for stock: MSFT”。
這些測試驗證了該股票交易系統(tǒng)的基本功能,如交易記錄的添加、更新、刪除操作能否正常工作。測試結(jié)果表明,系統(tǒng)能夠正確處理正常操作和異常情況(如刪除或更新不存在的交易記錄)。
總的來說,開發(fā)者通過使用Cursor輔助編寫基于鏈表的股票交易系統(tǒng),能夠快速生成數(shù)據(jù)結(jié)構(gòu)、操作方法和邏輯流程。此外,通過Cursor提供的代碼補全和代碼提示功能,開發(fā)者不僅能夠高效地完成常規(guī)的增、刪、改、查操作,還能憑借對生成的代碼的進一步理解,對其進行調(diào)整,從而提升代碼的性能、可讀性和健壯性。
表1-1展示了在實際使用Cursor的過程中,一些常用的快捷鍵以及對應(yīng)的功能描述。
表1-1 Cursor快捷鍵及功能描述

一般情況下,Cursor常用的快捷鍵有如下4個,建議讀者重點記憶。
● Tab:用于自動填充。Tab鍵的使用場景主要分為兩種:從頭開始編寫代碼或修改已有代碼。此外,也可以選中整個文件的代碼,按下Tab鍵,讓Cursor生成詳細的代碼注釋。
● Ctrl+K:用于編輯代碼。選中已有代碼后,按下Ctrl+K快捷鍵喚出編輯框,隨后選擇模型并輸入需求即可開始編輯代碼。編輯完成后,可單擊Accept或Reject接受或拒絕修改,也可以單擊代碼行最右側(cè),接受或拒絕對單行代碼的修改。
● Ctrl+L:可以回答用戶關(guān)于代碼和整個項目的問題,也具備編輯代碼的功能。該快捷鍵支持針對選中代碼、整個代碼文件和整個項目進行智能回答,功能強大、實用性極高。
● Ctrl+I:用于跨文件編輯整個項目的代碼。該快捷鍵專門為項目級開發(fā)設(shè)計,可以通過和模型對話的方式開發(fā)整個項目,互動過程與聊天類似。在會話中,它可以幫助用戶完成創(chuàng)建文件、刪除文件,以及同時編輯多個文件等操作。
1.4.2 實戰(zhàn):用Cursor與Copilot輔助編寫Windows桌面自動截圖應(yīng)用程序
【例1-13】使用Copilot編寫一個適用于Windows桌面環(huán)境的自動截圖應(yīng)用程序,并通過Cursor輔助優(yōu)化代碼結(jié)構(gòu)、調(diào)試工作流程。
本例將使用C++進行開發(fā),并結(jié)合Windows API實現(xiàn)截圖功能,重點介紹如何高效地利用Cursor在復雜的Windows桌面開發(fā)中實現(xiàn)自動化操作。
要開發(fā)的應(yīng)用程序的功能需求如下。
● 自動捕獲整個屏幕并保存為圖片文件。
● 支持指定區(qū)域的截圖功能。
● 用戶可通過簡單的快捷鍵觸發(fā)截圖操作。
該應(yīng)用程序架構(gòu)設(shè)計的核心模塊如下。
● 屏幕捕獲模塊:使用Windows API實現(xiàn)屏幕截圖功能。
● 文件保存模塊:將截圖保存為本地圖片文件。
● 快捷鍵監(jiān)聽模塊:捕捉用戶的快捷鍵輸入,觸發(fā)截圖操作。
首先,在Cursor中創(chuàng)建一個新項目,并設(shè)置支持C++開發(fā)的環(huán)境,確保已安裝VS Code或JetBrains IDE,并已集成Copilot插件。在Cursor中輸入功能需求提示,如Create a Windows desktop application for screen capturing using C++,即可生成代碼框架。
隨后,在Copilot中輸入以下提示:Create a C++ program that captures the entire screen and saves it as a BMP file using Windows API,即可生成項目的初始代碼框架。Copilot生成了以下基礎(chǔ)代碼:
#include <windows.h> #include <iostream> #include <string> // Function to capture the screen and save as BMP file void CaptureScreen(const std::string& fileName) { // Get the device context of the screen HDC hScreenDC = GetDC(NULL); HDC hMemoryDC = CreateCompatibleDC(hScreenDC); // Get the width and height of the screen int width = GetDeviceCaps(hScreenDC, HORZRES); int height = GetDeviceCaps(hScreenDC, VERTRES); // Create a compatible bitmap from the screen DC HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height); // Select the bitmap into the memory DC HGDIOBJ oldBitmap = SelectObject(hMemoryDC, hBitmap); // Copy the screen contents into the memory DC BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY); // Save the bitmap to file BITMAPFILEHEADER fileHeader; BITMAPINFOHEADER infoHeader; memset(&fileHeader, 0, sizeof(fileHeader)); memset(&infoHeader, 0, sizeof(infoHeader)); fileHeader.bfType = 0x4D42; fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); fileHeader.bfSize = fileHeader.bfOffBits + (width * height * 4); infoHeader.biSize = sizeof(BITMAPINFOHEADER); infoHeader.biWidth = width; infoHeader.biHeight = -height; // Negative to ensure top-down bitmap infoHeader.biPlanes = 1; infoHeader.biBitCount = 32; infoHeader.biCompression = BI_RGB; FILE* file = fopen(fileName.c_str(), "wb"); fwrite(&fileHeader, sizeof(fileHeader), 1, file); fwrite(&infoHeader, sizeof(infoHeader), 1, file); BITMAPINFO bmpInfo; bmpInfo.bmiHeader = infoHeader; BYTE* bitmapData = new BYTE[width * height * 4]; GetDIBits(hMemoryDC, hBitmap, 0, height, bitmapData, &bmpInfo, DIB_RGB_COLORS); fwrite(bitmapData, width * height * 4, 1, file); delete[] bitmapData; fclose(file); // Clean up SelectObject(hMemoryDC, oldBitmap); DeleteObject(hBitmap); DeleteDC(hMemoryDC); ReleaseDC(NULL, hScreenDC); } int main() { std::string fileName = "screenshot.bmp"; CaptureScreen(fileName); std::cout << "Screenshot saved as " << fileName << std::endl; return 0; }
對上述代碼的分析與性能評估如下。
● 屏幕捕獲:利用BitBlt()函數(shù)實現(xiàn)屏幕內(nèi)容的復制。
● 保存文件:通過BITMAPFILEHEADER和BITMAPINFOHEADER結(jié)構(gòu),將屏幕內(nèi)容保存為BMP文件。
● 清理資源:釋放內(nèi)存DC、設(shè)備上下文和位圖資源。
接下來,我們繼續(xù)擴展該應(yīng)用程序的功能,使其支持通過快捷鍵觸發(fā)截圖操作。通過向Cursor發(fā)送相應(yīng)的提示,我們能夠快速生成以下代碼:
#include <thread> // Global variable to track screenshot key bool isRunning = true; void ListenForHotkey() { while (isRunning) { if (GetAsyncKeyState(VK_F12)) { // F12 for screenshot std::string fileName = "screenshot.bmp"; CaptureScreen(fileName); std::cout << "Screenshot saved as " << fileName << std::endl; Sleep(500); // Avoid multiple triggers } } } int main() { std::cout << "Press F12 to take a screenshot. Press ESC to exit." << std::endl; // Start hotkey listener in a separate thread std::thread hotkeyThread(ListenForHotkey); // Exit on ESC while (isRunning) { if (GetAsyncKeyState(VK_ESCAPE)) { isRunning = false; } Sleep(100); } // Wait for the listener thread to finish hotkeyThread.join(); return 0; }
經(jīng)過進一步擴展,我們實現(xiàn)了以下功能。
● 快捷鍵監(jiān)聽:通過GetAsyncKeyState方法監(jiān)聽用戶按鍵(F12)。
● 多線程:利用std::thread實現(xiàn)非阻塞的熱鍵監(jiān)聽。
在上述開發(fā)完成后,我們需要對該自動截圖應(yīng)用程序進行全面測試與調(diào)試,這是確保其穩(wěn)定性和正確性的重要步驟。以下是具體的測試與調(diào)試過程,以及如何使用Cursor輔助生成并優(yōu)化代碼。
在Cursor中輸入以下提示語可以生成測試邏輯。
● Write a C++ unit test to validate the screen capture functionality.
● Create a debug mode to log errors during screenshot capture.
● Add a test to ensure the file is saved and not corrupted.
Cursor還能生成可用于輔助分析的代碼,借助這些代碼,開發(fā)者可以測試該自動截圖應(yīng)用程序是否能夠正確捕獲和保存屏幕截圖。
● 輸入提示“Create a function to check if a file exists in C++”后,Cursor自動生成了fileExists()函數(shù),該函數(shù)可用于檢測文件是否存在。
● 輸入提示“Write a test case for the CaptureScreen function”后,Cursor自動生成了基礎(chǔ)的單元測試框架,其中包含相應(yīng)的斷言語句。
通過上述兩個步驟,我們可以確保生成的BMP文件不為空并且具有正確的文件頭格式,以下是具體的測試代碼:
#include <cassert> #include <fstream> // Function to validate if a file exists bool fileExists(const std::string& fileName) { std::ifstream file(fileName); return file.good(); } // Unit test for CaptureScreen function void testCaptureScreen() { std::string testFile = "test_screenshot.bmp"; // Capture screen and save to test file CaptureScreen(testFile); // Assert file exists assert(fileExists(testFile) && "Screenshot file was not created"); // Cleanup std::remove(testFile.c_str()); std::cout << "Test 1 Passed: Screenshot file created successfully.\n"; }
接下來,我們通過Cursor繼續(xù)生成可用于輔助分析的代碼。
輸入提示“Write a test case to validate BMP file integrity”后,Cursor生成了用于檢查文件頭的代碼:
void testFileIntegrity() { std::string testFile = "test_screenshot.bmp"; // Capture screen and save to test file CaptureScreen(testFile); // Open the file and validate the BMP header std::ifstream file(testFile, std::ios::binary); assert(file.good() && "Failed to open screenshot file"); char header[2]; file.read(header, 2); assert(header[0] == 'B' && header[1] == 'M' && "File is not a valid BMP"); file.close(); // Cleanup std::remove(testFile.c_str()); std::cout << "Test 2 Passed: Screenshot file integrity verified.\n"; }
此外,我們還需要測試在異常情況下,程序是否能夠準確地處理錯誤,例如屏幕設(shè)備不可用的情況。我們可以輸入提示“Add exception handling to the CaptureScreen function”,這時Cursor自動生成了捕獲和處理異常的框架代碼,如下所示:
void testErrorHandling() { try { // Simulate an error by passing an invalid filename CaptureScreen(""); } catch (const std::exception& e) { std::cout << "Test 3 Passed: Exception caught - " << e.what() << "\n"; return; } assert(false && "Exception was not thrown for invalid input"); }
在Cursor中輸入提示“Add a logging system to track errors during screen capture”,Cursor可以生成以下代碼:
#include <fstream> // Simple logger to track errors void logError(const std::string& errorMessage) { std::ofstream logFile("error_log.txt", std::ios::app); logFile << "Error: " << errorMessage << "\n"; logFile.close(); }
以上提示的目的是為現(xiàn)有的屏幕捕獲功能加入日志記錄系統(tǒng),以便在出現(xiàn)錯誤時能夠及時捕捉并記錄詳細信息,這為后續(xù)的調(diào)試工作以及問題追蹤提供了更全面的支持。通過引導AI生成具有日志功能的代碼,開發(fā)者可以在不手動編寫煩瑣的錯誤處理邏輯的前提下,快速構(gòu)建具備健壯性與可維護性的系統(tǒng)模塊。
在捕獲屏幕或保存文件時加入日志記錄的功能,可以通過以下代碼實現(xiàn):
void CaptureScreen(const std::string& fileName) { if (fileName.empty()) { logError("Invalid file name provided"); throw std::invalid_argument("File name cannot be empty"); } // Existing screen capture code... }
借助Cursor生成的代碼進入調(diào)試模式,通過輸出的詳細信息來排查問題,調(diào)試代碼如下:
void debugInfo(const std::string& message) { std::cout << "[DEBUG]: " << message << std::endl; } void CaptureScreenDebug(const std::string& fileName) { debugInfo("Starting screen capture..."); try { CaptureScreen(fileName); debugInfo("Screen capture completed successfully."); } catch (const std::exception& e) { debugInfo(std::string("Error during screen capture: ") + e.what()); } }
在主函數(shù)中調(diào)用測試代碼,并查看測試結(jié)果:
int main() { std::cout << "Running tests...\n"; testCaptureScreen(); testFileIntegrity(); testErrorHandling(); std::cout << "All tests passed.\n"; return 0; }
測試結(jié)果如下:
Running tests... Test 1 Passed: Screenshot file created successfully. Test 2 Passed: Screenshot file integrity verified. Test 3 Passed: Exception caught - File name cannot be empty All tests passed.
通過Cursor生成的輔助代碼和調(diào)試邏輯,開發(fā)者能夠快速驗證自動截圖應(yīng)用程序功能的正確性,并及時定位和修復潛在的問題。Cursor不僅提供了高效的代碼生成工具,還能夠幫助開發(fā)者優(yōu)化調(diào)試過程,使開發(fā)過程更加高效、有序。
Copilot的功能總結(jié)如表1-2所示。
表1-2 Copilot功能總結(jié)

- SPSS數(shù)據(jù)挖掘與案例分析應(yīng)用實踐
- Java應(yīng)用與實戰(zhàn)
- ReSharper Essentials
- The Modern C++ Challenge
- Java 開發(fā)從入門到精通(第2版)
- Delphi程序設(shè)計基礎(chǔ):教程、實驗、習題
- 無代碼編程:用云表搭建企業(yè)數(shù)字化管理平臺
- Java入門很輕松(微課超值版)
- 青少年P(guān)ython編程入門
- Hands-On Natural Language Processing with Python
- Learning Probabilistic Graphical Models in R
- 深度學習:Java語言實現(xiàn)
- ElasticSearch Cookbook(Second Edition)
- 移動互聯(lián)網(wǎng)軟件開發(fā)實驗指導
- Python機器學習之金融風險管理