openGL學習(基本窗口)

學習路線?

學習 OpenGL 需要掌握一系列基礎知識和技能,這些內容涵蓋了計算機圖形學的基本概念、編程語言、數學知識以及 OpenGL 的具體 API 使用。以下是學習 OpenGL 所需的主要知識點:

1.?計算機圖形學基礎

  • 圖形學概念:了解圖形學的基本概念,如像素、分辨率、顏色模型(RGB、RGBA)、光柵化、光柵圖形等。

  • 圖形管線:理解圖形渲染管線的工作原理,包括頂點處理、光柵化、片段處理等階段。

  • 圖形對象:熟悉常見的圖形對象,如點、線、多邊形、紋理、光照等。

2.?數學基礎

  • 線性代數

    • 向量:向量的基本運算(加法、減法、點積、叉積)。

    • 矩陣:矩陣的基本運算(乘法、逆矩陣、轉置)。

    • 變換:平移、旋轉、縮放等變換的矩陣表示。

  • 幾何知識

    • 坐標系:理解世界坐標系、物體坐標系、視圖坐標系、屏幕坐標系等。

    • 投影:正交投影和透視投影的概念及實現。

  • 光柵化算法

    • 直線繪制算法:如 Bresenham 算法。

    • 多邊形填充算法:如掃描線填充算法。

3.?編程語言

  • C/C++:OpenGL 主要使用 C/C++ 進行編程,因此需要熟練掌握 C/C++ 的基本語法和編程技巧。

  • GLSL(OpenGL Shading Language):用于編寫著色器程序,包括頂點著色器、片段著色器等。

4.?OpenGL API

  • OpenGL 基礎

    • 初始化:創建窗口、初始化 OpenGL 上下文(可以使用 GLFW 等庫)。

    • 狀態管理:了解 OpenGL 的狀態機模型,如何設置和查詢狀態。

    • 緩沖區對象:如頂點緩沖區對象(VBO)、頂點數組對象(VAO)、幀緩沖區對象(FBO)等。

  • 著色器編程

    • 著色器類型:頂點著色器、片段著色器、幾何著色器等。

    • 著色器程序:編寫、編譯、鏈接著色器程序。

    • 變量傳遞:如何將數據從 CPU 傳遞到 GPU(如 uniform 變量、attribute 變量)。

  • 渲染技術

    • 基本渲染:繪制點、線、三角形等基本圖形。

    • 紋理映射:加載和應用紋理,理解紋理坐標、紋理過濾、紋理環繞等概念。

    • 光照:理解光照模型(如 Phong 照明模型),實現平行光、點光源、環境光等。

    • 陰影:實現陰影映射等高級光照效果。

  • 高級技術

    • 曲面細分:使用曲面細分著色器生成更平滑的曲面。

    • 計算著色器:用于通用計算任務。

    • 多視口渲染:在多個視口同時渲染不同的場景。

    • 后處理效果:如模糊、HDR、抗鋸齒等。

5.?輔助工具和庫

  • GLFW:用于創建窗口和處理輸入。

  • GLAD:用于加載 OpenGL 函數指針。

  • GLM(OpenGL Mathematics):用于處理數學運算,如向量和矩陣運算。

  • FreeGLUT:用于創建窗口和處理輸入(與 GLFW 類似)。

  • Assimp:用于加載 3D 模型文件。

  • SOIL:用于加載紋理文件。

6.?調試和優化

  • 調試工具:使用調試工具(如 RenderDoc、gDEBugger)來調試 OpenGL 程序。

  • 性能優化:了解常見的性能瓶頸(如 CPU/GPU 瓶頸、內存帶寬瓶頸)和優化方法。

7.?實踐項目

  • 小型項目:從簡單的項目開始,如繪制一個旋轉的立方體。

  • 復雜項目:逐步實現更復雜的場景,如加載 3D 模型、實現簡單的游戲引擎等。

學習資源推薦

  • 書籍

    • 《OpenGL SuperBible》:適合初學者和進階學習者。

    • 《OpenGL Programming Guide》(紅寶書):經典教材。

  • 在線教程

    • LearnOpenGL:非常詳細的 OpenGL 教程,適合初學者。

    • OpenGL Tutorial:包含豐富的示例和代碼。

  • 視頻教程

    • YouTube 上有許多 OpenGL 教程,如 The Cherno 的 OpenGL 系列。

初試OpenGL

1.首先需要編譯glfw-3.4的動態庫,和glad庫,使用vs2021進行程序編寫。

#include <iostream>
//#include "thrirdParty/include/GLFW/glfw3.h"
#include "glad/glad.h"   //需要先引用glad的頭文件。
#include "GLFW/glfw3.h"using namespace std;
/*
* 創建glfw的窗體系統
*/
int main(int argc,char**argv)
{cout << "===================================" << endl;//1. 初始化GLFW基本環境glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);//啟用核心模式(非立即渲染模式)glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// 2. 創建窗體對象GLFWwindow* win = glfwCreateWindow(800, 600, "OpenGlStudy", NULL, NULL);//設置窗體對象為Opengl的繪制舞臺glfwMakeContextCurrent(win);// // 3. 執行窗體循環// while (!glfwWindowShouldClose(win)){//接受并且分發窗體消息//檢查消息隊列是否有需要處理的鼠標,鍵盤等信息//如果有的話就將消息批量處理,清空隊列。glfwPollEvents();}// 4. 退出程序前做相關清理glfwTerminate();cout << "===================================" << endl;return 0;
}

?CMakeLists.txt

cmake_minimum_required(VERSION 3.12)project(OpenGL_Lecture)set(CMAKE_CXX_STANDARD 11)include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/thrirdParty/include
)
link_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/thrirdParty/lib)
add_executable(openglStudy "main.cpp" "glad.c")target_link_libraries(openglStudy glfw3.lib)

?事件響應

#include <iostream>
//#include "thrirdParty/include/GLFW/glfw3.h"
#include "glad/glad.h"   //需要先引用glad的頭文件。
#include "GLFW/glfw3.h"using namespace std;
/*
* 創建glfw的窗體系統
* 加入窗體變化的事件回調
*/void frameBufferSizeCallback(GLFWwindow* win, int width, int height)
{std::cout << "窗體的最新大小為:" << width << "高度為:" << height << std::endl;}void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods){// key 字母按鍵碼 // scancode 物理按鍵碼		 // action:0抬起1按下2長按// mods:是否有shift(1)或ctrl(2) cout << "key = " << key << " scancode = " << scancode << " action = " << action << " mods = " << mods << endl;if (key == GLFW_KEY_W){//按下了w}else if (action == GLFW_PRESS){//按下了}else if (action == GLFW_RELEASE){//抬起}}int main(int argc,char**argv)
{cout << "===================================" << endl;//1. 初始化GLFW基本環境glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);//啟用核心模式(非立即渲染模式)glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// 2. 創建窗體對象GLFWwindow* win = glfwCreateWindow(800, 600, "OpenGlStudy", NULL, NULL);//設置窗體對象為Opengl的繪制舞臺glfwMakeContextCurrent(win);//設置監聽幀緩沖窗口大小回調函數。glfwSetFramebufferSizeCallback(win, frameBufferSizeCallback);glfwSetKeyCallback(win, keyCallback);// // 3. 執行窗體循環// while (!glfwWindowShouldClose(win)){//接受并且分發窗體消息//檢查消息隊列是否有需要處理的鼠標,鍵盤等信息//如果有的話就將消息批量處理,清空隊列。glfwPollEvents();}// 4. 退出程序前做相關清理glfwTerminate();cout << "===================================" << endl;return 0;
}

函數加載

Opengl運行環境是一個巨大的狀態機,每一個函數都會改變狀態機的狀態或者觸發其執行某個行為。

OpenGL采用雙緩沖機制 ,利用兩個緩沖區進行交替展示。

#include <iostream>
//#include "thrirdParty/include/GLFW/glfw3.h"
#include "glad/glad.h"   //需要先引用glad的頭文件。
#include "GLFW/glfw3.h"using namespace std;
/*
* 創建glfw的窗體系統
* 加入窗體變化的事件回調
*/void frameBufferSizeCallback(GLFWwindow* win, int width, int height)
{std::cout << "窗體的最新大小為:" << width << "高度為:" << height << std::endl;//更新窗體的大小glViewport(0, 0, width, height);}void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods){// key 字母按鍵碼 // scancode 物理按鍵碼		 // action:0抬起1按下2長按// mods:是否有shift(1)或ctrl(2) cout << "key = " << key << " scancode = " << scancode << " action = " << action << " mods = " << mods << endl;if (key == GLFW_KEY_W){//按下了w}else if (action == GLFW_PRESS){//按下了}else if (action == GLFW_RELEASE){//抬起}}int main(int argc,char**argv)
{cout << "===================================" << endl;//1. 初始化GLFW基本環境glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);//啟用核心模式(非立即渲染模式)glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// 2. 創建窗體對象GLFWwindow* win = glfwCreateWindow(800, 600, "OpenGlStudy", NULL, NULL);//設置窗體對象為Opengl的繪制舞臺glfwMakeContextCurrent(win);//設置監聽幀緩沖窗口大小回調函數。glfwSetFramebufferSizeCallback(win, frameBufferSizeCallback);glfwSetKeyCallback(win, keyCallback);// 使用glad加載所有當前版本的OpenGL函數,加載后才能使用if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress) ) {cout << "Failed to initialize glad " << endl;}//設置OpenGL視口以及清理顏色glViewport(0,0,800,600);glClearColor(0.2f,0.3f,0.3f,1.0f);// 3. 執行窗體循環// while (!glfwWindowShouldClose(win)){//接受并且分發窗體消息glfwPollEvents();glClear(GL_COLOR_BUFFER_BIT);//渲染操作// //切換雙緩沖glfwSwapBuffers(win);}// 4. 退出程序前做相關清理glfwTerminate();cout << "===================================" << endl;return 0;
}

OpenGL函數錯誤處理

main.cpp

#include <iostream>
//#include "thrirdParty/include/GLFW/glfw3.h"
#include "glad/glad.h"   //需要先引用glad的頭文件。
#include "GLFW/glfw3.h"
#include <assert.h>
#include "wrapper/checkerror.h"using namespace std;/*
* 創建glfw的窗體系統
* 加入窗體變化的事件回調
*/void frameBufferSizeCallback(GLFWwindow* win, int width, int height)
{std::cout << "窗體的最新大小為:" << width << "高度為:" << height << std::endl;//更新窗體的大小glViewport(0, 0, width, height);}void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods){// key 字母按鍵碼 // scancode 物理按鍵碼		 // action:0抬起1按下2長按// mods:是否有shift(1)或ctrl(2) cout << "key = " << key << " scancode = " << scancode << " action = " << action << " mods = " << mods << endl;if (key == GLFW_KEY_W){//按下了w}else if (action == GLFW_PRESS){//按下了}else if (action == GLFW_RELEASE){//抬起}}int main(int argc,char**argv)
{cout << "===================================" << endl;//1. 初始化GLFW基本環境glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);//啟用核心模式(非立即渲染模式)glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// 2. 創建窗體對象GLFWwindow* win = glfwCreateWindow(800, 600, "OpenGlStudy", NULL, NULL);//設置窗體對象為Opengl的繪制舞臺glfwMakeContextCurrent(win);//設置監聽幀緩沖窗口大小回調函數。glfwSetFramebufferSizeCallback(win, frameBufferSizeCallback);glfwSetKeyCallback(win, keyCallback);// 使用glad加載所有當前版本的OpenGL函數,加載后才能使用if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress) ) {cout << "Failed to initialize glad " << endl;}//設置OpenGL視口以及清理顏色glViewport(0,0,800,600);glClearColor(0.2f,0.3f,0.3f,1.0f);// 3. 執行窗體循環// while (!glfwWindowShouldClose(win)){//接受并且分發窗體消息glfwPollEvents();GL_CALL( glClear(GL_COLOR_BUFFER_BIT) );//glClear(-1);//設置錯誤顏色不會崩潰,會出現黑色//checkError();//GL_CALL(glClear(-1) ); //渲染操作// //切換雙緩沖glfwSwapBuffers(win);}// 4. 退出程序前做相關清理glfwTerminate();cout << "===================================" << endl;return 0;
}

wrapper/checkerror.cpp

頭文件checkerror.h就是void checkError();

#include "checkerror.h"
#include "glad/glad.h"
#include <string>
#include <iostream>
#include <assert.h>using namespace std;void checkError()
{GLenum errornum = glGetError();//cout << "errornum = " << errornum << endl; //錯誤碼1281 GL_INVALID_VALUEstd::string errorstr = "";if (errornum != GL_NO_ERROR){cout << "GL有錯誤" << endl;switch (errornum){case GL_INVALID_ENUM:errorstr = "無效的枚舉 GL_INVALID_ENUM"; break;case GL_INVALID_VALUE:errorstr = "無效的值 GL_INVALID_VALUE"; break;case GL_INVALID_OPERATION:errorstr = "無效的操作 GL_INVALID_OPERATION"; break;case GL_OUT_OF_MEMORY:errorstr = "無效的內存 GL_OUT_OF_MEMORY"; break;default:errorstr = "UNKNOWN";break;}cout << "errorstr = " << errorstr << endl;assert(false); //斷言根據bool決定是否停止程序。}
}

./CMakeLists.txt

cmake_minimum_required(VERSION 3.12)project(OpenGL_Lecture)set(CMAKE_CXX_STANDARD 11)include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/thrirdParty/include
)
link_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/thrirdParty/lib)add_subdirectory(wrapper)#在項目夾加入全局的預編譯宏
add_definitions(-DCHECK_ERROR)add_executable(openglStudy "main.cpp" "glad.c" )target_link_libraries(openglStudy glfw3.lib wrapper)

wrapper/CMakeLists.txt

#遞歸將本文件夾下的所有cpp放到WRAPPER中file(GLOB_RECURSE WRAPPER ./ *.cpp)#將所有cpp文件鏈接到這個wrapper lib庫中。 默認生成靜態庫,動態庫編譯不過去
add_library(wrapper    ${WRAPPER})

Application封裝

?application.cpp

#include "application.h"
#include "application.h"
#include "application.h"#include "glad/glad.h"   //需要先引用glad的頭文件。 用于加載 OpenGL 函數指針
#include "GLFW/glfw3.h" // 用于創建窗口和處理輸入。	Application* Application::m_app = nullptr;
Application* Application::getInst()
{if (m_app == nullptr){m_app = new Application();}return m_app;
}int Application::init(const int width, const int height)
{cout << "Application::init" << endl;m_Width = width;m_Height = height;//1. 初始化GLFW基本環境glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);//啟用核心模式(非立即渲染模式)glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// 2. 創建窗體對象m_Window = glfwCreateWindow(m_Width, m_Height, "OpenGlStudy", NULL, NULL);if (m_Window == NULL){return -1;}//設置窗體對象為Opengl的繪制舞臺glfwMakeContextCurrent(m_Window);// 使用glad加載所有當前版本的OpenGL函數,加載后才能使用if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){cout << "Failed to initialize glad " << endl;return -1;}//GLFW監聽必須要使用static進行聲明。//窗口大小改變的事件glfwSetFramebufferSizeCallback(m_Window, frameBufferSizeCallback);//鍵盤的事件glfwSetKeyCallback(m_Window, keyCallback);//this就是全局Application對象glfwSetWindowUserPointer(m_Window, this);//將this暫時存在窗體中。return 0;
}int Application::update()
{if (glfwWindowShouldClose(m_Window)){return -1;}//接受并且分發窗體消息glfwPollEvents();//切換雙緩沖glfwSwapBuffers(m_Window);return 0;
}int Application::destroy()
{cout << "Application::destroy" << endl;// 4. 退出程序前做相關清理glfwTerminate();return 0;
}Application::Application()
{}void Application::frameBufferSizeCallback(GLFWwindow* win, int width, int height)
{//因為是靜態函數,所以不能調用全局唯一實例。// 靜態成員函數屬于類本身,而不是類的某個具體對象。//它不依賴于任何對象實例,因此不能訪問非靜態成員變量//(因為非靜態成員變量需要對象實例來存儲其值)。cout << "frameBufferSizeCallback " << endl;//m_resizeCallBack();// //面試題:如何在靜態成員函數中調用非靜態函數?//if(Application::getInst()->m_resizeCallBack != nullptr)//	Application::getInst()->m_resizeCallBack(width,height);Application* self  = (Application*) glfwGetWindowUserPointer(win);if(self->m_resizeCallBack != nullptr)self->m_resizeCallBack(width, height);}void Application::keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{cout << "keyCallback " << endl;Application* self = (Application*)glfwGetWindowUserPointer(window);if (self->m_keyCallBack != nullptr)self->m_keyCallBack(window, key,scancode,action,mods);}Application::~Application()
{}

application.h

#pragma once#include <iostream>#define app Application::getInst()class GLFWwindow; //提前聲明class,避免頭文件重復定義的問題.using resizeCallBack = void(*)(int width,int height);
using keyCallBack = void(*)(GLFWwindow* window,int key, int scancode, int action, int mods);using namespace std;//單例類實現class Application
{
public:~Application();static Application* getInst();void test() { cout << "test" << endl; };uint32_t getWidth() const { return m_Width; }; //const含義:不改變類中的成員uint32_t getHeight() const { return m_Height; };int init(const int width = 800, const int height = 500);int update();int destroy(); void setResizeCallBack(resizeCallBack call) { m_resizeCallBack = call; };void setkeyCallBack(keyCallBack call) { m_keyCallBack = call; };private:Application();static Application* m_app;uint32_t m_Width{ 0 }; //列表初始化uint32_t m_Height{ 0 };GLFWwindow* m_Window{ nullptr };resizeCallBack m_resizeCallBack{nullptr};keyCallBack m_keyCallBack{ nullptr };private:static void frameBufferSizeCallback(GLFWwindow*win,int width,int height);static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);};

main.cpp

#include <iostream>
//#include "thrirdParty/include/GLFW/glfw3.h" 
#include "glad/glad.h"   //需要先引用glad的頭文件。 用于加載 OpenGL 函數指針
#include "GLFW/glfw3.h" // 用于創建窗口和處理輸入。	
#include <assert.h>
#include "wrapper/checkerror.h"
#include "application/application.h"using namespace std;/*
* 創建glfw的窗體系統
* 加入窗體變化的事件回調
*/void onResize(int width,int height)
{GL_CALL(glViewport(0, 0, width, height));cout << "onResize " << endl;
}void frameBufferSizeCallback(GLFWwindow* win, int width, int height)
{std::cout << "窗體的最新大小為:" << width << "高度為:" << height << std::endl;//更新窗體的大小glViewport(0, 0, width, height);}void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods){// key 字母按鍵碼 // scancode 物理按鍵碼		 // action:0抬起1按下2長按// mods:是否有shift(1)或ctrl(2) cout << "key = " << key << " scancode = " << scancode << " action = " << action << " mods = " << mods << endl;if (key == GLFW_KEY_W){//按下了w}else if (action == GLFW_PRESS){//按下了}else if (action == GLFW_RELEASE){//抬起}}int main(int argc,char**argv)
{cout << "===================================" << endl;if (app->init(800,600) == -1){return -1;}//設置監聽幀緩沖窗口大小回調函數。//glfwSetFramebufferSizeCallback(win, frameBufferSizeCallback);//glfwSetKeyCallback(win, keyCallback);app->setResizeCallBack(onResize);app->setkeyCallBack(keyCallback);//設置OpenGL視口以及清理顏色glViewport(0,0,800,600);glClearColor(0.2f,0.3f,0.3f,1.0f);// 3. 執行窗體循環// while (app->update() == 0 ){GL_CALL( glClear(GL_COLOR_BUFFER_BIT) );//渲染操作}// 4. 退出程序前做相關清理app->destroy();cout << "===================================" << endl;return 0;
}

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

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

相關文章

無人機防護裝置技術解析

一、技術要點 1. 偵測防御系統 多頻譜復合探測 整合無線電偵測&#xff08;20MHz–6GHz頻段掃描&#xff09;、雷達探測、光電跟蹤&#xff08;可見光/紅外/激光&#xff09;技術&#xff0c;實現360無死角監測。例如神州明達系統可5公里內識別無人機信號&#xff0c;并同步…

2.2.2、CAN總線-測試模式、工作模式

目錄 1、測試模式 2、工作模式 &#xff08;1&#xff09; &#xff08;2&#xff09;SLEEP位&#xff1a; &#xff08;3&#xff09;INRQ位&#xff1a;&#xff08;Init Request&#xff09; &#xff08;4&#xff09;ACK&#xff1a;應答 &#xff08;5&#xff09;…

區塊鏈大講堂 | 分布式隱私計算友好的零知識證明協議

區塊鏈大講堂 主講人&#xff1a;上海交通大學計算機學院助理教授胡云聰 報告題目&#xff1a;分布式隱私計算友好的零知識證明協議 參與方式&#xff1a;掃描海報二維碼報名參與活動

MyBatis映射文件(XML)中參數傳遞和SQL特殊字符處理

1. 參數占位符 1.1 #{} 和 ${} 的區別 #{} 占位符 作用&#xff1a;安全傳參。MyBatis在執行SQL時&#xff0c;會把#{}替換成?&#xff0c;然后用參數值自動填充。 優點&#xff1a;可以防止SQL注入&#xff0c;推薦使用。 例子&#xff1a; select * from user wher…

C語言 數據結構 --排序 (直接插入排序,選擇排序,交換排序......)

引言&#xff1a;本章簡潔的講解一下數據結構中的幾個常見的排序 &#xff0c;作復習之用&#xff0c;后面可能會補一些其他的排序 。并給出一些小編學習中遇到的坑&#xff0c;作借鑒。 1.直接插入排序 直接插入排序是一種簡單直觀的排序算法&#xff0c;其基本思想是將一個數…

華為云發布盤古大模型 5.5 新一代昇騰 AI 云服務上線

2025 年 6 月 20 日&#xff0c;華為開發者大會 2025&#xff08;HDC 2025&#xff09;在東莞召開。華為常務董事、云計算 CEO 張平安宣布基于 CloudMatrix 384 超節點的新一代昇騰 AI 云服務全面上線&#xff0c;并發布盤古大模型 5.5&#xff0c;五大基礎模型實現技術突破&am…

Reactor Handle

handle 是 Reactor 中一個非常靈活的操作符&#xff0c;它允許你對每個源元素進行處理&#xff0c;并可以選擇性地發出零個或多個元素。它既可以用于映射&#xff08;map&#xff09;也可以用于過濾&#xff08;filter&#xff09;&#xff0c;因此可以看作是 map 和 filter 的…

C#哈希加密:原理、實現與應用

C#哈希加密&#xff1a;原理、實現與應用 在當今數字化時代&#xff0c;數據安全是每個應用程序都必須重視的問題。哈希加密作為一種重要的加密技術&#xff0c;在密碼存儲、數據完整性驗證、數字簽名等領域發揮著關鍵作用。本文將深入探討C#中哈希加密的原理、常用算法以及實…

httpbin.org是什么,有什么作用

httpbin.org 是一個開源的 HTTP 請求與響應測試服務&#xff0c;基于 Python 的 Flask 框架開發 它允許開發者發送各種 HTTP 請求&#xff0c;并返回請求的詳細信息&#xff0c;便于調試和驗證 HTTP 客戶端的行為。以下是其核心功能和作用詳解&#xff1a; 一、核心功能與作用…

mongodb生產備份工具PBM

如果你的 MongoDB 數據量特別大&#xff08;例如幾十 GB、TB 級別&#xff09;&#xff0c;普通的 mongodump/mongorestore 會顯得緩慢且資源消耗大&#xff0c;不適合生產級別大數據集。下面是當前 MongoDB 社區和企業廣泛使用的幾種備份方案對比和推薦&#xff1a; 工具是否…

【LeetCode#第167題】兩數之和Ⅱ

給你一個下標從 1 開始的整數數組 numbers &#xff0c;該數組已按 非遞減順序排列 &#xff0c;請你從數組中找出滿足相加之和等于目標數 target 的兩個數。如果設這兩個數分別是 numbers[index1] 和 numbers[index2] &#xff0c;則 1 < index1 < index2 < numbers…

Python(一)實現一個爬取微信小程序數據的爬蟲+工程化初步實踐

文章目錄 前言用Charles 抓包 iOS 微信小程序在Mac端和iOS端安裝Charles 自簽名證書Mac端iOS端 能抓到Safari瀏覽器的包但是抓不到微信小程序的包直接在iOS 上抓包的App如何抓取Android 7.0 以上/Harmony OS微信小程序包 Python 項目工程化pip 切換為國內鏡像源工程化參考腳手架…

uview ui request get / post 傳參含params和json數據的分析和使用

背景。單獨寫了controller方法去配合移動端的接口調用。但有的接口與pc端類似。于是進行了復用。但接口得復制不是。 uview js request 文檔 注意迪三個參數是header 后端接口GET方法 調用代碼截圖 瀏覽器調試 總結。 復制之前的api接口。為了方便復用底層實現。接口類型…

用 pnpm + TurboRepo,構建多項目高效開發體系

在現代前端項目日益復雜的今天&#xff0c;我們越來越多地面對一個場景&#xff1a;多個項目共享邏輯、組件和依賴&#xff0c;而維護和構建效率卻在不斷拉垮。這種情況下&#xff0c;傳統項目結構的痛點就顯現無遺。 從我親身實踐來看&#xff0c;選擇 pnpm TurboRepo 構建 …

Pytest 使用命令行參數執行指定環境的腳本—— Python 實踐

&#x1f9fe; 一、項目背景 在自動化測試中&#xff0c;我們經常需要根據不同的運行環境&#xff08;如測試環境和生產環境&#xff09;來執行測試腳本。本文將詳細介紹如何通過命令行參數來指定運行環境&#xff0c;并使用 Python 和 pytest 框架實現這一功能。 &#x1f6e…

利用可控驗證碼位數實現拒絕服務攻擊(DoS)風險與線程模型分析

一、背景介紹&#xff1a;驗證碼接口中的潛在 DoS 漏洞 在滲透測試過程中&#xff0c;常見驗證碼接口支持傳入“驗證碼位數”參數&#xff0c;表面看是業務可配置&#xff0c;實則若未做上限控制&#xff0c;極易成為資源消耗型 DoS 攻擊入口。 &#x1f9ea; 測試場景&#…

Spring Cloud Feign 整合 Sentinel 實現服務降級與熔斷保護

Spring Cloud Feign 整合 Sentinel 實現服務降級與熔斷保護 在微服務架構中&#xff0c;服務之間的調用往往依賴 Feign&#xff0c;而服務調用的穩定性又至關重要。本文將介紹如何將 Feign 與 Sentinel 結合使用&#xff0c;實現服務的容錯保護&#xff08;如降級與熔斷&#…

寵物醫院系統的設計與實現(springBoot版)

一、開題報告 一、本選題研究的意義和背景&#xff08;理論與現實意義&#xff09;&#xff1a; 背景&#xff1a;隨著人們生活水平的提高&#xff0c;寵物飼養愈發普遍&#xff0c;寵物醫院的需求也日益增長。掛號方式主要依賴現場掛號&#xff0c;導致寵物主人需要長時間排隊…

SOCKSv5 協議通信的完整階段與報文格式詳解

SOCKSv5 協議的通信通常分為以下幾個主要階段&#xff1a; 方法協商階段 (Method Negotiation)方法依賴的子協商階段 (Method-Dependent Sub-negotiation) - 本例為用戶名/密碼認證請求發送階段 (Request Sending)請求回復階段 (Request Reply)數據傳輸階段 (Data Transfer) …

??Git提交代碼Commit消息企業級規范

??Git Commit 類型完整指南?? 類型用途示例??feat??新增功能&#xff08;面向用戶的功能性變更&#xff09;git commit -m "feat: 添加用戶登錄功能"??fix??修復 Bug&#xff08;解決代碼中的問題&#xff09;git commit -m "fix: 修復首頁加載崩潰…