OSS-服務端簽名Web端直傳+STS獲取臨時憑證+POST簽名v4版本開發過程中的細節

這里寫自定義目錄標題

  • 配置OSS
  • 服務端代碼
    • 初始化STS Client
    • 獲取STS臨時憑證
    • 創建policy計算SigningKey
      • OSSUtil.java
      • STSPolicyDTO.java
    • 提供接口
  • Apifox模擬Web端文件直傳

本文主要結合服務端STS獲取臨時憑證(簽名)直傳官方文檔對開發中比較容易出錯的地方加以提醒;建議主要還是以官方文檔為主。本文中的代碼幾乎就是官方給的代碼示例。
閱讀前請先比對OSS版本,這可能關系到本文中列舉的坑是否能解決你的問題

		<dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.17.4</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>sts20150401</artifactId><version>1.1.6</version></dependency>

只不過重要的OSS基本參數官方建議給到環境變量中;本文直接將重要的OSS基礎信息給到了Spring主配置文件中(方便后期遷移到Nacos的配置中心管理),知道了這一點,在接下來代碼閱讀的過程中看到如下的代碼片段也就不陌生了。
在這里插入圖片描述
接下來也將OSS基本參數封裝成AliOSSProp的代碼順手貼出來

/*** oss的基礎信息* prefix = "alibaba.oss"表示Spring、Springboot主配置文件中以alibaba.oss打頭的自定義參數值,都將一 一映射到當前類的屬性上*/
@ConfigurationProperties(prefix = "alibaba.oss")
@Component
@Getter
@Setter
public class AliOSSProp {private String accessKeyId;private String secretAccessKey;/*** 確保獲取臨時訪問憑證時Endpoint使用STS域名,例如String endpoint = "sts.cn-hangzhou.aliyuncs.com"。* 更多信息,請參見步驟五:獲取臨時訪問憑證。* https://help.aliyun.com/document_detail/100624.html?spm=api-workbench.Troubleshoot.0.0.5ba77185ILElOT#section-5xa-zdn-s0q*/private String endpoint;private String bucket;/*** RAM 訪問控制/身份管理/角色/ARN屬性值*/private String roleArn;private String region;
}

在這里插入圖片描述

配置OSS

這個在官方文檔中有很詳細的教程,不多贅述

服務端代碼

服務端最主要的事情:使用STS生成一個臨時的憑證給客戶端使用;客戶端拿到該臨時憑證就可以直接將文件上傳至OSS

初始化STS Client

這里有個點需要注意:endpoint 需要添加sts.前綴,
考慮到STS Client只需要初始化一次,所以將其注冊為一個Bean


@Beanpublic com.aliyun.sts20150401.Client ossStsClient() throws Exception {// 工程代碼泄露可能會導致 AccessKey 泄露,并威脅賬號下所有資源的安全性。以下代碼示例僅供參考。com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()// 必填,請確保代碼運行環境設置了環境變量 OSS_ACCESS_KEY_ID。.setAccessKeyId(aliOSSProp.getAccessKeyId())// 必填,請確保代碼運行環境設置了環境變量 OSS_ACCESS_KEY_SECRET。.setAccessKeySecret(aliOSSProp.getSecretAccessKey());// Endpoint 請參考 https://api.aliyun.com/product/Sts// 確保獲取臨時訪問憑證時Endpoint使用STS域名config.endpoint = "sts."+aliOSSProp.getEndpoint();return new com.aliyun.sts20150401.Client(config);}

獲取STS臨時憑證

這部分沒有什么需要注意的點,可以完全照搬

import com.aliyun.sts20150401.models.AssumeRoleResponseBody;
import com.aliyun.oss.OSSException;/*** 獲取STS臨時憑證* @return AssumeRoleResponseBodyCredentials 對象*/private AssumeRoleResponseBody.AssumeRoleResponseBodyCredentials getCredential(){com.aliyun.sts20150401.models.AssumeRoleRequest assumeRoleRequest = new com.aliyun.sts20150401.models.AssumeRoleRequest()// 必填,請確保代碼運行環境設置了環境變量 OSS_STS_ROLE_ARN.setRoleArn(aliOSSProp.getRoleArn()).setRoleSessionName("idooyRoleSessionName");// 自定義會話名稱com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();try {// 復制代碼運行請自行打印 API 的返回值com.aliyun.sts20150401.models.AssumeRoleResponse response = ossStsClient.assumeRoleWithOptions(assumeRoleRequest, runtime);// credentials里包含了后續要用到的AccessKeyId、AccessKeySecret和SecurityToken。return response.body.credentials;} catch (TeaException error) {// 此處僅做打印展示,請謹慎對待異常處理,在工程項目中切勿直接忽略異常。// log.error("STS方式獲取臨時憑證失敗原因===》{}",error.getMessage());throw new OSSException("STS方式獲取臨時憑證失敗原因===》"+error.getMessage());} catch (Exception e) {throw new OSSException(e.getMessage());}}

創建policy計算SigningKey

這部分的代碼很長,但是注釋很清晰;當然也不需要完全搞懂,照搬就好。

  • 這部分代碼中的魔法值(String字面量)要小心,別無意間給修改或者給粘錯了
  • 這部分使用了三種日期格式,分別是:“yyyyMMdd’T’HHmmss’Z’”、“yyyyMMdd”、“yyyy-MM-dd’T’HH:mm:ss.SSS’Z’”。注意區分
  • uploadDir 變量值請自定義修改
  • 官方直接將結果塞進了map中,本文將其封裝為了一個DTO對象
@Resourceprivate com.aliyun.sts20150401.Client ossStsClient;/***     指定過期時間,單位為秒。*/private static final Long EXPIRE_TIME = 3600L;private static final String TIME_FORMAT_PATTERN_1 = "yyyyMMdd'T'HHmmss'Z'";/*** 定義日期時間格式*/private static final String TIME_FORMAT_PATTERN_2 = "yyyyMMdd";@ResourceAliOSSProp aliOSSProp;/*** 還是“服務端驗簽web端直傳的方式”只不過采用了更加安全的STS方式* @return*/@Overridepublic STSPolicyDTO getSTSUploadPolicy() throws JsonProcessingException {String host = "https://" + aliOSSProp.getBucket() + "." + aliOSSProp.getEndpoint();// 設置上傳到OSS文件的前綴,可置空此項。置空后,文件將上傳至Bucket的根目錄下;每一天產生一個文件夾// brand/是自定義目錄String uploadDir = "brand/"+LocalDate.now();String region = aliOSSProp.getRegion();// 臨時的憑證信息AssumeRoleResponseBody.AssumeRoleResponseBodyCredentials credential = getCredential();String accessKeyId =  credential.getAccessKeyId();String accessKeySecret =  credential.getAccessKeySecret();String securityToken =  credential.getSecurityToken();//獲取x-oss-credential里的date,當前日期,格式為yyyyMMddZonedDateTime today = ZonedDateTime.now().withZoneSameInstant(ZoneOffset.UTC);DateTimeFormatter formatter = DateTimeFormatter.ofPattern(TIME_FORMAT_PATTERN_2);String date = today.format(formatter);//獲取x-oss-dateZonedDateTime now = ZonedDateTime.now().withZoneSameInstant(ZoneOffset.UTC);DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern(TIME_FORMAT_PATTERN_1);String x_oss_date = now.format(formatter2);// 步驟1:創建policy。String x_oss_credential = accessKeyId + "/" + date + "/" + region + "/oss/aliyun_v4_request";ObjectMapper mapper = new ObjectMapper();Map<String, Object> policy = new HashMap<>();policy.put("expiration", OSSUtil.generateExpiration(EXPIRE_TIME));List<Object> conditions = new ArrayList<>();Map<String, String> bucketCondition = new HashMap<>();bucketCondition.put("bucket", aliOSSProp.getBucket());conditions.add(bucketCondition);Map<String, String> securityTokenCondition = new HashMap<>();securityTokenCondition.put("x-oss-security-token", securityToken);conditions.add(securityTokenCondition);Map<String, String> signatureVersionCondition = new HashMap<>();signatureVersionCondition.put("x-oss-signature-version", "OSS4-HMAC-SHA256");conditions.add(signatureVersionCondition);Map<String, String> credentialCondition = new HashMap<>();credentialCondition.put("x-oss-credential", x_oss_credential); // 替換為實際的 access key idconditions.add(credentialCondition);Map<String, String> dateCondition = new HashMap<>();dateCondition.put("x-oss-date", x_oss_date);conditions.add(dateCondition);conditions.add(Arrays.asList("content-length-range", 1, 10240000));conditions.add(Arrays.asList("eq", "$success_action_status", "200"));conditions.add(Arrays.asList("starts-with", "$key", uploadDir));policy.put("conditions", conditions);String jsonPolicy = mapper.writeValueAsString(policy);// 步驟2:構造待簽名字符串(StringToSign)。// String stringToSign = new String(Base64.encodeBase64(jsonPolicy.getBytes()));String stringToSign = cn.hutool.core.codec.Base64.encode(jsonPolicy.getBytes());// System.out.println("stringToSign: " + stringToSign);// 步驟3:計算SigningKey。byte[] dateKey = OSSUtil.getHmacSHA256(("aliyun_v4" + accessKeySecret).getBytes(), date);byte[] dateRegionKey = OSSUtil.getHmacSHA256(dateKey, region);byte[] dateRegionServiceKey = OSSUtil.getHmacSHA256(dateRegionKey, "oss");byte[] signingKey = OSSUtil.getHmacSHA256(dateRegionServiceKey, "aliyun_v4_request");// System.out.println("signingKey: " + BinaryUtil.toBase64String(signingKey));// 步驟4:計算Signature。byte[] result = OSSUtil.getHmacSHA256(signingKey, stringToSign);String signature = BinaryUtil.toHex(result);return new STSPolicyDTO().setPolicy(stringToSign).setX_oss_credential(x_oss_credential).setX_oss_date(x_oss_date).setSignature(signature).setSecurity_token(securityToken).setDir(uploadDir).setHost(host);}

OSSUtil.java

public class OSSUtil {private OSSUtil() {}/*** 定義日期時間格式,例如2023-12-03T13:00:00.000Z*/public static final String TIME_FORMAT_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";public static byte[] getHmacSHA256(byte[] key, String data) {try {// 初始化HMAC密鑰規格,指定算法為HMAC-SHA256并使用提供的密鑰。SecretKeySpec secretKeySpec = new SecretKeySpec(key, "HmacSHA256");// 獲取Mac實例,并通過getInstance方法指定使用HMAC-SHA256算法。Mac mac = Mac.getInstance("HmacSHA256");// 使用密鑰初始化Mac對象。mac.init(secretKeySpec);// 執行HMAC計算,通過doFinal方法接收需要計算的數據并返回計算結果的數組。byte[] hmacBytes = mac.doFinal(data.getBytes());return hmacBytes;} catch (Exception e) {throw new RuntimeException("Failed to calculate HMAC-SHA256", e);}}/*** 通過指定有效的時長(秒)生成過期時間。** @param seconds 有效時長(秒)。* @return ISO8601 時間字符串,如:"2014-12-01T12:00:00.000Z"。*/public static String generateExpiration(long seconds) {// 獲取當前時間戳(以秒為單位)long now = Instant.now().getEpochSecond();// 計算過期時間的時間戳long expirationTime = now + seconds;// 將時間戳轉換為Instant對象,并格式化為ISO8601格式Instant instant = Instant.ofEpochSecond(expirationTime);// 定義時區為UTCZoneId zone = ZoneOffset.UTC;// 將 Instant 轉換為 ZonedDateTimeZonedDateTime zonedDateTime = instant.atZone(zone);// 定義日期時間格式,例如2023-12-03T13:00:00.000ZDateTimeFormatter formatter = DateTimeFormatter.ofPattern(TIME_FORMAT_PATTERN);// 格式化日期時間String formattedDate = zonedDateTime.format(formatter);// 輸出結果return formattedDate;}}

STSPolicyDTO.java

@Getter
@Setter
@Accessors(chain = true)
public class STSPolicyDTO {/*** 官方代碼示例中給的“"OSS4-HMAC-SHA256"”*/private String version="OSS4-HMAC-SHA256";private String policy;private String x_oss_credential;private String x_oss_date;private String signature;private String security_token;private String dir;private String host;
}

提供接口

@RestController
@RequestMapping("/oss")
@Api("OSS文件上傳驗簽")
public class AliOSSController {final AliOSSService ossService;public AliOSSController(AliOSSService ossService) {this.ossService = ossService;}/*** oss上傳文件:使用服務端驗簽web直傳的方式* 該接口提供web直傳所必須的驗簽信息* 文檔地址:https://help.aliyun.com/zh/oss/use-cases/obtain-signature-information-from-the-server-and-upload-data-to-oss?spm=a2c4g.11186623.help-menu-31815.d_6_1_0_0.386b4acdkrwKDc&scm=20140722.H_31926._.OR_help-T_cn~zh-V_1* @return*/@GetMapping("policy")@ApiOperation("STS驗簽V4版")public R<STSPolicyDTO> policy() throws JsonProcessingException {// UploadPolicyDTO uploadPolicy = ossService.getUploadPolicy();STSPolicyDTO uploadPolicy = ossService.getSTSUploadPolicy();return R.ok().data(uploadPolicy);}}

接口的響應數據示例


{"success": true,"code": 2000,"message": "成功","data": {"version": "OSS4-HMAC-SHA256","policy": "eyJleHBpcmF0aW9uIjoiMjAyNS0wNy0zMFQxNToyMjowNy4wMDBaIiwiY29uZGl0aW9ucyI6W3siYnVja2V0IjoiaWRvb3ktbWFsbCJ9LHsieC1vc3Mtc2VjdXJpdHktdG9rZW4iOiJDQUlTelFKMXE2RnQ1QjJ5ZlNqSXI1blFFZXo1aDVzVjRZYXpZM1BjZ1ZFZGFkcGl2cFB5aWp6MklIaE1lWEJoQStrZHR2b3duMnBaN3Z3Y2xyMXlSNWhDVkhiRGFjWkw0NDlNOEFTblJZUEV0cFFiWm1DelpjYjNkMUtJQWp2WGdlWHdBWXlnUHY2L0Y5NnBiMWZiN0Z3UnBaTHhhVFNsV1hHOExKU05rdVFKUjk4TFh3NitIMUVrYlpVc1VXa0Vrc0lCTW1iTFB2dUFLd1BqaG5HcWJIQmxvUTFoazJoeW04L2RxNCsra2tPRzBnU2xsYkJPKzltdWNzUDdNWmxXVWMwaEE0dnY3b3RmYmJIYzFTTmMwUjlPK1pwdGdiWk1rVFc5NVluRlhnQUF1VXpkYTdTTHFZYytkRlVuZk00OUFMVUJzL1gyME9CZ3Z1dmFtNVJIYk9USnNUek1PczYyWmZkRG9LT3NjSXZCWHI2eUpRamxvSElPQzZpd0xHL3pxUzBtVjJBNTlmOG1GQ0haMG9hWjZOSDlvOXdiODBKR0ZZRURvL1phcHNKdXFzSkpPdUtlcEE2QVZ0VW44QVhuSzkwYWdBRWloRDByMzE0TnNadUp6UHFkbkF3aUVXWjhWdWFvWlZUUzl0eTdmTW1vUTRIaGsrODE3U3BqeWVvMloycGo3T21zaFVWRmpKNFN5cjVsMWo2VFM3aVBqcFZlRG1xZjhtZ0tRc2F0bFdReHFwdk9MQmIray9QTktNei9kRXA4RFF3clg3S2x6b1RVRTA4bndKK0dqeEFFd0FkVWh3blBBbk14dVlXTEZrdUtZQ0FBIn0seyJ4LW9zcy1zaWduYXR1cmUtdmVyc2lvbiI6Ik9TUzQtSE1BQy1TSEEyNTYifSx7Ingtb3NzLWNyZWRlbnRpYWwiOiJTVFMuTlplWlZNakQ0VkRYYVVtZVFIZVVOUVZZaC8yMDI1MDczMC9jbi1jaGVuZ2R1L29zcy9hbGl5dW5fdjRfcmVxdWVzdCJ9LHsieC1vc3MtZGF0ZSI6IjIwMjUwNzMwVDE0MjIwN1oifSxbImNvbnRlbnQtbGVuZ3RoLXJhbmdlIiwxLDEwMjQwMDAwXSxbImVxIiwiJHN1Y2Nlc3NfYWN0aW9uX3N0YXR1cyIsIjIwMCJdLFsic3RhcnRzLXdpdGgiLCIka2V5IiwiYnJhbmQvMjAyNS0wNy0zMCJdXX0=","x_oss_credential": "STS.NZeZVMjD4VDXaUmeQHeUNQVYh/20250730/cn-chengdu/oss/aliyun_v4_request","x_oss_date": "20250730T142207Z","signature": "e583ba3040d9ac4544b4008f7193edf30fdef75cca6d4ca0e449150cf4904165","security_token": "CAISzQJ1q6Ft5B2yfSjIr5nQEez5h5sV4YazY3PcgVEdadpivpPyijz2IHhMeXBhA+kdtvown2pZ7vwclr1yR5hCVHbDacZL449M8ASnRYPEtpQbZmCzZcb3d1KIAjvXgeXwAYygPv6/F96pb1fb7FwRpZLxaTSlWXG8LJSNkuQJR98LXw6+H1EkbZUsUWkEksIBMmbLPvuAKwPjhnGqbHBloQ1hk2hym8/dq4++kkOG0gSllbBO+9mucsP7MZlWUc0hA4vv7otfbbHc1SNc0R9O+ZptgbZMkTW95YnFXgAAuUzda7SLqYc+dFUnfM49ALUBs/X20OBgvuvam5RHbOTJsTzMOs62ZfdDoKOscIvBXr6yJQjloHIOC6iwLG/zqS0mV2A59f8mFCHZ0oaZ6NH9o9wb80JGFYEDo/ZapsJuqsJJOuKepA6AVtUn8AXnK90agAEihD0r314NsZuJzPqdnAwiEWZ8VuaoZVTS9ty7fMmoQ4Hhk+817Spjyeo2Z2pj7OmshUVFjJ4Syr5l1j6TS7iPjpVeDmqf8mgKQsatlWQxqpvOLBb+k/PNKMz/dEp8DQwrX7KlzoTUE08nwJ+GjxAEwAdUhwnPAnMxuYWLFkuKYCAA","dir": "brand/2025-07-30","host": "目標bucket的公網訪問域名"}
}

Apifox模擬Web端文件直傳

文件上傳的地址,就是你自己目標bucket的公網訪問域名,也可以直接從上面接口的響應字段host獲取,這部分就是結合自己的前端項目自行開發。將上傳的參數名稱做個簡單的說明。
請求參數名稱:

{"success_action_status", "200""policy", data.policy"x-oss-signature", data.signature"x-oss-signature-version", "OSS4-HMAC-SHA256""x-oss-credential", data.x_oss_credential"x-oss-date", data.x_oss_date"key", data.dir + file.name // 文件名"x-oss-security-token", data.security_token"file", file); // file 必須為最后一個表單域
}                

在這里插入圖片描述
沒啥文章功底,主要是站在自己的角度一通記錄而已;多包涵,歡迎在評論區討論共同學習。

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

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

相關文章

uniapp實現微信小程序導航功能

1.導航按鈕<button click"navigation()">導航到倉庫</button>2.導航功能const navigation (item) > {let address item.province item.city item.district item.address //地址let latitude Number(item.latitude) …

07.4-使用 use 關鍵字引入路徑

使用 use 關鍵字引入路徑 每次調用函數時都必須寫出完整路徑&#xff0c;可能會感覺不便且重復。在清單7-7中&#xff0c;無論我們選擇絕對路徑還是相對路徑來調用 add_to_waitlist 函數&#xff0c;每次調用時都必須指定 front_of_house 和 hosting。幸運的是&#xff0c;有一…

7.Linux :進程管理,進程控制與計劃任務

Linux &#xff1a;進程管理&#xff0c;進程控制與計劃任務 一、進程管理 1. 進程與程序 程序&#xff1a;靜態的可執行文件&#xff08;存儲于磁盤&#xff09;。進程&#xff1a;動態執行的程序實例&#xff08;占用CPU/內存&#xff09;。 2. 查看進程命令作用常用組合ps靜…

Matplotlib(四)- 圖表樣式美化

文章目錄一、Matplotlib圖表樣式介紹1. 圖表樣式簡介2. 默認圖表樣式2.1 查看默認配置2.2 常用的配置3. 圖表樣式修改3.1 局部修改3.1.1 通過繪圖方法設置參數修改3.1.2 通過rcParams修改3.1.3 通過rc()方法修改3.2 全局修改二、顏色設置1. 顏色的三種表示方式1.1 顏色單詞1.2 …

三十四、【Linux常用工具】rsync+inotify實時同步演示

實時同步演示技術架構全景核心組件詳解1. inotify 內核子系統2. Rsync 高效同步工具實踐演示一、環境準備與安裝1. 檢查內核支持2. 安裝 inotify-tools二、配置 Rsync 服務端&#xff08;目標機&#xff09;1. 創建 Rsync 配置文件2. 啟動 Rsync 守護進程三、配置實時同步腳本&…

windows環境下MySQL 8.0 修改或重置密碼

windows環境下MySQL 8.0 修改或重置密碼 1打開命令窗口cmd&#xff0c;輸入命令&#xff1a;net stop mysql&#xff0c; 停止MySQL服務&#xff0c; 開啟跳過密碼驗證登錄的MySQL服務 2輸入命令 mysqld --console --skip-grant-tables --shared-memory 再打開一個新的cmd&…

基于YOLOP與GAN的圖像修復與防御系統設計與實現

基于YOLOP與GAN的圖像修復與防御系統設計與實現 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家&#xff0c;覺得好請收藏。點擊跳轉到網站。 1. 引言 1.1 研究背景 隨著深度學習技術在計算機視覺領域的…

將目錄文件轉移到D盤,使之后的下載緩存數據轉移,不再存入c盤

將 C:\Users 文件夾&#xff08;用戶文件夾&#xff09;轉移到其他盤是一個復雜且風險較高的操作。C:\Users 文件夾包含了系統中每個用戶的個人數據和配置文件&#xff0c;修改這個路徑可能會導致系統出現問題&#xff0c;包括程序無法正常工作或無法登錄。因此&#xff0c; 強…

Cesium大氣散射效果

由于做全球體積云效果的需要&#xff0c;再來研究下大氣散射效果和體積云類似&#xff0c;關于大氣散射顏色計算的過程也僅發生在這兩個球體之間。如圖所示。計算從相機出發的視線與球殼的交點&#xff0c;如果不相交&#xff0c;則該視線方向上不會發生大氣散射&#xff0c;直…

預過濾環境光貼圖制作教程:第二步 - 生成環境貼圖圖集

核心目標 本步驟的核心是生成一張包含 6 級分辨率的環境貼圖圖集(envAtlas),實現: 將第一步的立方體貼圖(sourceCube)重新映射為等矩形投影(適合存儲和采樣); 生成 6 級不同分辨率的等矩形數據(0 級最高清,5 級最模糊); 用 RGBP 編碼壓縮 HDR 數據(平衡精度與存…

1. ESP開發之實體按鍵(KEYPADBUTTON)控制LVGL控件

說明LV_INDEV_TYPE_BUTTON的使用LV_INDEV_TYPE_KEYPAD的使用 說明 本實驗使用LVGL版本為v9.2 LVGL中有四種輸入設備,如下LV_INDEV_TYPE_POINTER, /**< Touch pad, mouse, external button*/ LV_INDEV_TYPE_KEYPAD, /**< Keypad or keyboard*/ LV_INDEV_TYPE_BUTTON, /*…

C++:STL中list的使用和模擬實現

C中的list是標準模板庫&#xff08;STL&#xff09;提供的雙向鏈表容器&#xff0c;支持高效的元素插入和刪除操作。在上一篇中講解了vector的使用和模擬實現&#xff0c;vector是具有連續的空間&#xff0c;迭代器是可以隨機的&#xff0c;而list卻于vector不同&#xff0c;li…

【編號58-61】我國四大高原矢量示意圖shp數據

今天分享的是&#xff1a;中國四大高原&#xff0c;分別是青藏高原、內蒙古高原、黃土高原、云貴高原。青藏高原位置與范圍&#xff1a;位于中國西南部&#xff0c;包括西藏、青海的全部&#xff0c;川西高原及滇西北高原等部分地區。它的邊界&#xff0c;向東是橫斷山脈&#…

【AI落地應用實戰】利用 Amazon Bedrock Claude3 打造個性化 AI Character 應用

目錄一、引言&#xff1a;AI Character應用的市場前景與技術基礎二、技術架構設計2.1、整體方案概述2.2、核心組件介紹2.3、部署架構圖三、系統部署方案3.1、方案總述3.2、實踐流程1??. Bedrock 配置2??. 安裝 SillyTavern3??. 配置 SillyTavern 使用 Claude3 模型4??.…

Java常用日志框架介紹

Java提供了很多第三方的日志框架可供使用&#xff0c;按照現在的設計理念&#xff0c;一般把日志框架分成門面(Facade)部分和具體實現(Implementation)部分&#xff0c;門面(Facade)提供了抽象的api規范&#xff0c;實現(Implementation)負責實現api完成具體的日志記錄功能。開…

飛書 —— 多維表格 —— AI生成

1.添加關聯賬號&#xff1a; 2.獲取密鑰 ARK_API_KEY 進入火山引擎服務頁面&#xff1a;https://console.volcengine.com/ark/region:arkcn-beijing/model/detail?Iddeepseek-r1 先進入推理模型 > 快捷API接入 再去在線推理中創建推理接入點 點擊新創建好的接入點的API調…

我的世界模組開發教程——資源(1)

下面我們來研究一下ResourceLocation,每次開啟游戲時都會報這個錯誤:“ResourceLocation 中的 ResourceLocation(String) 已過時, 且標記為待刪除”,下面我們來詳細的研究一下這個類 ResourceLocation ResourceLocation 是 Minecraft 中用于唯一標識游戲資源的核心類(如方…

我從 Web2 轉型到 Web3 的 9 條經驗總結

作者&#xff1a;Forte Group 高級區塊鏈工程師 Yurii Kovalchuk原文&#xff1a;https://cryptoslate.com/why-i-left-web2-for-web3-and-why-you-might-too/三年前&#xff0c;我做出了一個徹底改變職業軌跡的決定&#xff1a;離開熟悉的 Web2&#xff0c;投身于深邃、混亂卻…

【MySQL 數據庫】MySQL索引特性(一)磁盤存儲定位扇區InnoDB頁

文章目錄沒有索引&#xff0c;可能會有什么問題二、認識磁盤2.1 MySQL與存儲2.2 磁盤&#xff1a;2.3 扇區2.4 定位扇區2.5 結論三、三者作用流程&#xff08;磁盤&#xff0c;塊&#xff0c;InnoDB頁&#xff09;四、MySQL與磁盤交互基本單位五、建立共識&#x1f6a9;總結沒有…

2419. 按位與最大的最長子數組

Problem: 2419. 按位與最大的最長子數組 文章目錄思路解題過程復雜度Code思路 按位異或只會讓數值越來越小&#xff0c;因此最長的連續按位與的最大值只存在于連續最大值中。 解題過程 遍歷數組取出最大值&#xff0c;再遍歷找到每一次連續最大值&#xff0c;從中取出最長的連續…