HttpClient工具类编写

HttpClient

介绍

HttpClient是Apache Jakarta Common下的一个子项目,它提供了一个高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包。它支持HTTP协议最新的版本和建议,并实现了Http1.0和Http1.1协议。

HttpClient具有可扩展的面向对象的结构,实现了Http全部的方法,包括GET、POST、PUT、DELETE、HEAD、OPTIONS以及TRACE。它支持HTTPS协议,并允许通过Http代理建立透明的连接,以及利用CONNECT方法建立隧道的https连接。此外,它还支持多种认证方案,如Basic、Digest、NTLMv1、NTLMv2、NTLM2 Session以及SNPNEGO/Kerberos,并允许使用插件式的自定义认证方案。

在项目中,HttpClient的使用场景广泛,如爬虫、多系统之间的接口交互等。在分布式项目中,前端系统需要调用后台的数据并初始化时,可以使用HttpClient进行通信。

在使用HttpClient时,通常需要导入相关的依赖库,并根据具体需求配置HttpClient的行为,如设置连接超时、读取超时等。然后,可以使用HttpClient发送GET、POST等请求,并处理返回的响应。

在SpringBoot后端项目开发时,什么时候需要HttpClient?

调用第三方服务的时候

构造HTTP请求

HttpClient的maven坐标:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.13</version>
</dependency>

其实阿里云oss已经依赖了httpclient,所以无需再引入这个包

HttpClient的核心API:

  • HttpClient(HttpClient对象接口):Http客户端对象类型,使用该类型对象可发起Http请求。

  • HttpClients:可认为是构建器,可创建HttpClient对象。

  • CloseableHttpClient(HttpClient对象实现类):实现类,实现了HttpClient接口。

  • HttpGet(Http请求对象):Get方式请求类型。

  • HttpPost(Http请求对象):Post方式请求类型。

HttpClient发送请求步骤:

  • 创建HttpClient对象

  • 创建Http请求对象

  • 调用HttpClient的execute方法发送请求

 GET请求

实现步骤:

  1. 创建HttpClient对象

  2. 创建请求对象

  3. 发送请求,接受响应结果

  4. 解析结果

  5. 关闭资源

package com.sky.test;
​
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
​
@SpringBootTest
public class HttpClientTest {
​
    /**
     * 测试通过httpclient发送GET方式的请求
     */
    @Test
    public void testGET() throws Exception{
        //创建httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
​
        //创建请求对象
        HttpGet httpGet = new HttpGet("http://localhost:8080/user/shop/status");
​
        //发送请求,接受响应结果
        CloseableHttpResponse response = httpClient.execute(httpGet);
​
        //获取服务端返回的状态码
        int statusCode = response.getStatusLine().getStatusCode();
        System.out.println("服务端返回的状态码为:" + statusCode);
​
        HttpEntity entity = response.getEntity();
        String body = EntityUtils.toString(entity);
        System.out.println("服务端返回的数据为:" + body);
​
        //关闭资源
        response.close();
        httpClient.close();
    }
}

在访问http://localhost:8080/user/shop/status请求时,需要提前启动项目。

注意:

  • 创建HttpClient对象需要调用HttpClients.createDefault()方法,创建一个CloseableHttpClient对象
  • 创建请求对象:HttpGet httpGet = new HttpGet("请求url");
  • 利用HttpCliet对象执行execute请求对象,得到响应结果response:CloseableHttpResponse response = httpClient.execute(httpGet);
  • 解析响应结果:

            int statusCode = response.getStatusLine().getStatusCode();
            System.out.println("服务端返回的状态码为:" + statusCode);

            HttpEntity entity = response.getEntity();
            String body = EntityUtils.toString(entity);
            System.out.println("服务端返回的数据为:" + body);

  • 关闭资源:

        response.close();
        httpClient.close();

Post请求

在HttpClientTest中添加POST方式请求方法,相比GET请求来说,POST请求若携带参数需要封装请求体对象,并将该对象设置在请求对象中。

实现步骤:

  1. 创建HttpClient对象

  2. 创建请求对象

  3. 发送请求,接收响应结果

  4. 解析响应结果

  5. 关闭资源

	/**
     * 测试通过httpclient发送POST方式的请求
     */
    @Test
    public void testPOST() throws Exception{
        // 创建httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        //创建请求对象
        HttpPost httpPost = new HttpPost("http://localhost:8080/admin/employee/login");

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("username","admin");
        jsonObject.put("password","123456");

        StringEntity entity = new StringEntity(jsonObject.toString());
        //指定请求编码方式
        entity.setContentEncoding("utf-8");
        //数据格式
        entity.setContentType("application/json");
        httpPost.setEntity(entity);

        //发送请求
        CloseableHttpResponse response = httpClient.execute(httpPost);

        //解析返回结果
        int statusCode = response.getStatusLine().getStatusCode();
        System.out.println("响应码为:" + statusCode);

        HttpEntity entity1 = response.getEntity();
        String body = EntityUtils.toString(entity1);
        System.out.println("响应数据为:" + body);

        //关闭资源
        response.close();
        httpClient.close();
    }

HttpPost请求对象需要利用setEntity方法补充json格式的请求体数据。

1、打包Json数据

       JSONObject jsonObject = new JSONObject();
        jsonObject.put("username","admin");
        jsonObject.put("password","123456");

        StringEntity entity = new StringEntity(jsonObject.toString());

2、设置请求编码方式和数据格式

        //指定请求编码方式
        entity.setContentEncoding("utf-8");
        //数据格式
        entity.setContentType("application/json");

3、setEntity打包Json数据

httpPost.setEntity(entity);

4、利用HttpClient对象的execute方法发送请求
        CloseableHttpResponse response = httpClient.execute(httpPost);

编写HttpClient工具类

/**
 * Http工具类
 */
public class HttpClientUtil {

    static final  int TIMEOUT_MSEC = 5 * 1000;

    /**
     * 发送GET方式请求
     * @param url
     * @param paramMap
     * @return
     */
    public static String doGet(String url,Map<String,String> paramMap){
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        String result = "";
        CloseableHttpResponse response = null;

        try{
            URIBuilder builder = new URIBuilder(url);
            if(paramMap != null){
                for (String key : paramMap.keySet()) {
                    builder.addParameter(key,paramMap.get(key));
                }
            }
            URI uri = builder.build();

            //创建GET请求
            HttpGet httpGet = new HttpGet(uri);

            //发送请求
            response = httpClient.execute(httpGet);

            //判断响应状态
            if(response.getStatusLine().getStatusCode() == 200){
                result = EntityUtils.toString(response.getEntity(),"UTF-8");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                response.close();
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result;
    }

    /**
     * 发送POST方式请求
     * @param url
     * @param paramMap
     * @return
     * @throws IOException
     */
    public static String doPost(String url, Map<String, String> paramMap) throws IOException {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";

        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);

            // 创建参数列表
            if (paramMap != null) {
                List<NameValuePair> paramList = new ArrayList();
                for (Map.Entry<String, String> param : paramMap.entrySet()) {
                    paramList.add(new BasicNameValuePair(param.getKey(), param.getValue()));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
                httpPost.setEntity(entity);
            }

            httpPost.setConfig(builderRequestConfig());

            // 执行http请求
            response = httpClient.execute(httpPost);

            resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
        } catch (Exception e) {
            throw e;
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }

    /**
     * 发送POST方式请求
     * @param url
     * @param paramMap
     * @return
     * @throws IOException
     */
    public static String doPost4Json(String url, Map<String, String> paramMap) throws IOException {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";

        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);

            if (paramMap != null) {
                //构造json格式数据
                JSONObject jsonObject = new JSONObject();
                for (Map.Entry<String, String> param : paramMap.entrySet()) {
                    jsonObject.put(param.getKey(),param.getValue());
                }
                StringEntity entity = new StringEntity(jsonObject.toString(),"utf-8");
                //设置请求编码
                entity.setContentEncoding("utf-8");
                //设置数据类型
                entity.setContentType("application/json");
                httpPost.setEntity(entity);
            }

            httpPost.setConfig(builderRequestConfig());

            // 执行http请求
            response = httpClient.execute(httpPost);

            resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
        } catch (Exception e) {
            throw e;
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }
    private static RequestConfig builderRequestConfig() {
        return RequestConfig.custom()
                .setConnectTimeout(TIMEOUT_MSEC)
                .setConnectionRequestTimeout(TIMEOUT_MSEC)
                .setSocketTimeout(TIMEOUT_MSEC).build();
    }

}

1. doGet(String url, Map<String,String> paramMap)

输入:

  • url: 要请求的URL地址。
  • paramMap: 一个包含请求参数的 Map 对象,键和值都是 String 类型。

输出:

  • 返回一个 String 类型的结果,表示 HTTP 响应的正文内容。

功能:

  • 该方法用于构造一个 HTTP GET 请求。它首先创建一个 HttpClient 对象,然后使用 URIBuilder 来添加请求参数。如果响应状态码为200,它将响应正文转换为字符串并返回。

2. doPost(String url, Map<String, String> paramMap) throws IOException

输入:

  • url: 要请求的URL地址。
  • paramMap: 一个包含请求参数的 Map 对象。

输出:

  • 返回一个 String 类型的结果,表示 HTTP 响应的正文内容。

功能:

  • 该方法用于构造一个 HTTP POST 请求,请求参数以表单形式发送。它创建一个 HttpPost 对象,并将参数作为 UrlEncodedFormEntity 设置到请求中。然后发送请求并返回响应正文。

3. doPost4Json(String url, Map<String, String> paramMap) throws IOException

输入:

  • url: 要请求的URL地址。
  • paramMap: 一个包含请求参数的 Map 对象。

输出:

  • 返回一个 String 类型的结果,表示 HTTP 响应的正文内容。

功能:

  • 该方法用于构造一个 HTTP POST 请求,请求参数以 JSON 格式发送。它创建一个 HttpPost 对象,并将参数构造为 JSON 对象,然后设置到请求的 StringEntity 中。请求的 Content-Type 被设置为 application/json,然后发送请求并返回响应正文。

4. builderRequestConfig()

输入:

  • 无。

输出:

  • 返回一个 RequestConfig 对象。

功能:

  • 这是一个私有方法,用于构建 RequestConfig 对象,它设置了连接超时、请求超时和套接字超时的默认值。

使用HttpClient工具类

以下是三个示例,展示如何使用 HttpClientUtil 类提供的前三个方法构造 HTTP 请求,并分析响应结果:

示例 1: 使用 doGet 方法发送 GET 请求

假设我们想要从 http://example.com/api/data 获取一些数据,并且有一些查询参数。

import java.util.HashMap;
import java.util.Map;

public class HttpClientUtilExample {
    public static void main(String[] args) {
        // 准备请求参数
        Map<String, String> params = new HashMap<>();
        params.put("param1", "value1");
        params.put("param2", "value2");

        // 发送 GET 请求
        String result = HttpClientUtil.doGet("http://example.com/api/data", params);

        // 分析响应结果
        if (result != null && !result.isEmpty()) {
            System.out.println("Response: " + result);
            // 这里可以根据需要解析 JSON 或 XML 响应体
        } else {
            System.out.println("No response received or error occurred.");
        }
    }
}

示例 2: 使用 doPost 方法发送表单 POST 请求

假设我们想要向 http://example.com/api/login 发送登录请求。

public class HttpClientUtilExample {
    public static void main(String[] args) {
        // 准备登录参数
        Map<String, String> params = new HashMap<>();
        params.put("username", "user123");
        params.put("password", "pass123");

        try {
            // 发送 POST 请求
            String result = HttpClientUtil.doPost("http://example.com/api/login", params);

            // 分析响应结果
            if (result != null && !result.isEmpty()) {
                System.out.println("Login Response: " + result);
                // 根据响应内容判断登录是否成功
            } else {
                System.out.println("Login failed or error occurred.");
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("An error occurred during the POST request.");
        }
    }
}

示例 3: 使用 doPost4Json 方法发送 JSON POST 请求

假设我们想要向 http://example.com/api/register 发送注册请求,并且请求体是 JSON 格式。

public class HttpClientUtilExample {
    public static void main(String[] args) {
        // 准备登录参数
        Map<String, String> params = new HashMap<>();
        params.put("username", "user123");
        params.put("password", "pass123");

        try {
            // 发送 POST 请求
            String result = HttpClientUtil.doPost("http://example.com/api/login", params);

            // 分析响应结果
            if (result != null && !result.isEmpty()) {
                System.out.println("Login Response: " + result);
                // 根据响应内容判断登录是否成功
            } else {
                System.out.println("Login failed or error occurred.");
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("An error occurred during the POST request.");
        }
    }
}

在每个示例中,我们首先创建了一个包含请求参数的 Map 对象,然后调用相应的方法发送请求。请求完成后,我们检查响应结果是否为 null 或者为空,如果不是,则打印出响应内容。在处理 POST 请求的示例中,我们还捕获了可能发生的 IOException

doPostdoPost4JsonHttpClientUtil 类中定义的两个发送 POST 请求的方法,它们的主要区别在于发送请求体的格式不同

doPost 方法:

  • 请求体格式doPost 方法发送的请求体是标准的表单格式(application/x-www-form-urlencoded)。
  • 参数构建:它使用 UrlEncodedFormEntity 来构建请求体,这适用于传统的表单提交,其中键值对被编码为字符串,并用 & 符号分隔。
  • 适用场景:当后端服务期望接收表单数据时,使用此方法。

doPost4Json 方法:

  • 请求体格式doPost4Json 方法发送的请求体是 JSON 格式(application/json)。
  • 参数构建:它使用 JSONObject 来构建请求体,然后将 JSON 对象转换为字符串,并设置到 StringEntity 中。
  • 适用场景:当后端服务期望接收 JSON 格式的请求体时,使用此方法。

代码层面的区别:

  • doPost 方法中,参数是通过遍历 paramMap 并使用 BasicNameValuePair 对象添加到 paramList 中,然后构建 UrlEncodedFormEntity 对象。
  • doPost4Json 方法中,参数是通过遍历 paramMap 并使用 JSONObject 的 put 方法添加到 JSON 对象中,然后构建 StringEntity 对象,并设置正确的 Content-Encoding 和 Content-Type

实际使用时的考虑因素:

  • 内容类型:客户端需要根据服务器端的期望来设置正确的 Content-Type
  • 编码:对于 JSON 请求体,需要确保字符编码正确设置为 UTF-8,以避免编码问题。
  • API 约定:不同的 API 可能对请求体的格式有不同的要求,选择正确的方法来满足这些要求是非常重要的。

在实际应用中,选择使用 doPost 还是 doPost4Json 取决于你要与之交互的 API 的具体要求。通常,现代的 RESTful API 更倾向于使用 JSON 格式,因为它结构化更好、更易于解析。然而,一些旧的或特定的系统可能仍然使用传统的表单数据格式。

传统的表单格式,通常指的是 application/x-www-form-urlencoded 格式,这是一种用于 HTTP 请求的编码方式,特别是用于表单数据的提交。在 Web 开发中,这是最常见的数据提交方式之一。

特点:

  1. 键值对:数据由键值对组成,其中键(key)和值(value)由等号(=)连接。
  2. 编码:所有键和值都必须进行百分比编码(也称为 URL 编码),以确保特殊字符可以安全地传输。
  3. 分隔:键值对之间通过和号(&)分隔。
  4. 兼容性:几乎所有的服务器端语言和框架都支持这种格式,因此它具有很好的兼容性。

示例:

假设有一个表单,包含用户名和密码字段,用户填写后提交到服务器:

<form action="/submit" method="post"> <input type="text" name="username" value="user123"> <input type="password" name="password" value="pass123"> <input type="submit" value="Submit"> </form>

当用户提交这个表单时,浏览器会将数据编码成以下格式:

username=user123&password=pass123

HTTP 请求示例:

POST /submit HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded username=user123&password=pass123

与传统表单格式相比的 JSON:

  • 结构:JSON 是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。
  • 格式:JSON 数据是自描述的,由键值对组成,键是字符串,值可以是字符串、数字、数组、布尔值或其他 JSON 对象。
  • 数据类型:JSON 支持更丰富的数据类型,如数组和嵌套对象。
  • 使用场景:JSON 通常用于 API 通信,特别是 RESTful API。

JSON 请求示例:

POST /api/register HTTP/1.1 Host: example.com Content-Type: application/json; charset=utf-8 { "username": "user123", "password": "pass123" }

在现代 Web 应用和 API 开发中,JSON 格式因其结构化和易于处理的特点而变得越来越流行,尤其是在需要传输复杂数据结构时。然而,传统的表单格式由于其简单性和广泛的支持,仍然在特定场景下被广泛使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/576711.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电脑壁纸怎么设置?简单3步,让你的电脑桌面变得更合心意

电脑壁纸是我们每天在电脑上工作和娱乐时不可或缺的一部分。一张精美的电脑壁纸&#xff0c;既能提升我们的工作效率&#xff0c;也能为我们带来愉悦的心情。无论是静谧的自然风光、抽象的艺术设计&#xff0c;还是心动的明星照片&#xff0c;都可以在电脑壁纸的世界里找到自己…

HF区块链链码基础

链码生命周期 一 . 链码准备 准备文件 . 在测试目录下创建chaincode,拷贝测试链码进 chaincode目录,拷贝 set-env.sh 脚本进 scripts 目录 二. 打包链码 打包测试链码 export FABRIC_CFG_PATH${PWD}/config peer lifecycle chaincode package ./chaincode/chaincode_basic.…

Springboot 中RedisTemplate使用scan来获取所有的key底层做了哪些事情

直接上代码&#xff0c;围绕着代码来讨论 redisTemplate.execute((RedisCallback<Object>) (connection) -> {Cursor<byte[]> scan connection.scan(ScanOptions.scanOptions().count(2).match("*").build());scan.forEachRemaining((bytes) -> {…

TypeScript 中 interface 和 type 的使用#记录

一、interface&#xff1a;接口 interface A{label: string; }const aa ((aObj: A) > {console.log(aObj.label);//123return aObj.label; })aa({label: 123}) 1、可选属性 interface A{label: string;age?: number; } 2、只读属性 interface A{label: string;age?:…

【网络安全】安全事件管理处置 — windows应急响应

专栏文章索引&#xff1a;网络安全 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 目录 一、账户排查 二、windows网络排查 三、进程排查 四、windows注册表排查 五、内存分析 总结 一、账户排查 账户排查主要包含以下几个维度 登录服务器的途径弱口令可疑账号 新增…

019基于JavaWeb的在线音乐系统(含论文)

019基于JavaWeb的在线音乐系统&#xff08;含论文&#xff09; 开发环境&#xff1a; Jdk7(8)Tomcat7(8)MysqlIntelliJ IDEA(Eclipse) 数据库&#xff1a; MySQL 技术&#xff1a; JavaServletJqueryJavaScriptAjaxJSPBootstrap 适用于&#xff1a; 课程设计&#xff0c;毕…

Web-SpringBootWen

创建项目 后面因为报错&#xff0c;所以我把jdk修改成22&#xff0c;仅供参考。 定义类&#xff0c;创建方法 package com.start.springbootstart.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotati…

易基因:Nat Commun:RRBS测序揭示小鼠衰老过程中的DNA甲基化变化轨迹|研究速递

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 DNA甲基化数据可以生成非常精确的年龄预测器&#xff0c;但关于这一关键表观遗传生物标志物在生命周期中的动态变化知之甚少。关于衰老不连续方面的研究仍处于起步阶段&#xff0c;关键的…

冯唐成事心法笔记 —— 知人

系列文章目录 冯唐成事心法笔记 —— 知己 冯唐成事心法笔记 —— 知人 冯唐成事心法笔记 —— 知世 冯唐成事心法笔记 —— 知智慧 文章目录 系列文章目录PART 2 知人 人人都该懂战略人人都该懂战略第一&#xff0c;什么是战略第二&#xff0c;为什么要做战略第三&#xff0…

文本溢出 右侧对齐 左侧显示省略号

要想 把 “这是一段很长的文本&#xff0c;我们只想显示省略号前面的部分内容" 展示成”…只想显示省略号前面的部分内容“ 代码如下 <div class"ellipsis-start">这是一段很长的文本&#xff0c;我们只想显示省略号前面的部分内容</div>.ellips…

力扣118. 杨辉三角

Problem: 118. 杨辉三角 文章目录 题目描述思路复杂度Code 题目描述 思路 1.初始化状态&#xff1a;将创建的二维数组dp的第一列和主对角线上元素设为1&#xff1b; 2.状态的转移&#xff1a;从第一行、列起始&#xff0c;dp[i][j] dp[i - 1][j - 1] dp[i - 1][j] 复杂度 时…

vue3第二十五节(h()函数的应用)

1、前言&#xff1a; 为什么vue 中已经有 template 模板语法&#xff0c;以及JSX了&#xff0c;还要使用 h()渲染函数&#xff1b; vue 中选择默认使用template 静态模板分析&#xff0c;有利于DMO性能的提升&#xff0c;而且更接近真实的HTML&#xff0c;便于开发设计人员理…

Java之复制图片

从文件夹中复制图片 从这个文件夹&#xff1a; 复制到这个空的文件夹&#xff1a; 代码如下&#xff1a; import java.io.*; import java.util.Scanner;/*** 普通文件的复制*/public class TestDome10 {public static void main(String[] args) {// 输入两个路径// 从哪里(源路…

ssm智能停车场管理系统

视频演示效果: SSMvue智能停车场 摘 要 本论文主要论述了如何使用JAVA语言开发一个智能停车场管理系统&#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述智能停车…

2024多用户商城系统哪家产品好

在当今激烈的电商竞争中&#xff0c;搭建一个功能强大、性能稳定的多用户商城系统至关重要。针对这一需求&#xff0c;以下是我为您推荐的五款优秀多用户商城系统&#xff0c;它们在功能、定制性、安全性和用户体验方面均表现出色&#xff0c;为您的电商平台搭建提供了可靠的解…

C++从入门到精通——C++动态内存管理

C动态内存管理 前言一、C/C内存分布分类1分类2题目选择题sizeof 和 strlen 区别示例sizeofstrlen 二、C语言中动态内存管理方式malloc/calloc/realloc/free示例例题malloc/calloc/realloc的区别malloc的实现原理 三、C内存管理方式new/delete操作内置类型new和delete操作自定义…

底层逻辑(1) 是非对错

底层逻辑(1) 是非对错 关于本书 这本书的副标题叫做&#xff1a;看清这个世界的底牌。让我想起电影《教父》中的一句名言&#xff1a;花半秒钟就看透事物本质的人&#xff0c;和花一辈子都看不清事物本质的人&#xff0c;注定是截然不同的命运。 如果你看过梅多丝的《系统之美…

Lagent AgentLego 智能体应用搭建-作业六

本次课程由Lagent&AgentLego 核心贡献者樊奇老师讲解【Lagent & AgentLego 智能体应用搭建】课程。分别是&#xff1a; Agent 理论及 Lagent&AgentLego 开源产品介绍Lagent 调用已有 Arxiv 论文搜索工具实战Lagent 新增自定义工具实战&#xff08;以查询天气的工具…

不对称催化(三)- 动态动力学拆分动态动力学不对称转化

一、动力学拆分的基本概念&#xff1a; 动力学拆分的最大理论产率为50%&#xff0c;通过的差异可以将两个对映异构体转化为不同构型的产物&#xff0c;通常情况下使用两个不同反应路径来实现。但是化学家们提供了一个更加实用的方法&#xff0c;通过底物的构型变化实现高于50%的…

【Leetcode】377. 组合总和 Ⅳ

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517; 给你一个由 不同 整数组成的数组 n u m s nums nums&#xff0c;和一个目标整数 t a r g e t target target 。请你从 n u m s nums nums 中找出并返回总和为 t a r g e t targ…