一 产品介绍

腾讯云官方介绍链接

腾讯云新一代行为验证码(Captcha),基于十道安全防护策略,为网页、App、小程序开发者打造立体、全面的人机验证。在保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。

验证码服务可以帮助您解决以下业务安全问题:

  1. 登录注册:有效防止撞库攻击、阻止注册机批量注册小号。
  2. 活动秒杀:有效拦截刷单操作,防止自动机刷取福利券。
  3. 点赞发帖:有效解决广告屠版、恶意灌水、刷票问题。
  4. 数据保护:有效防止自动机、爬虫盗取网页内容和数据。

操作简单,部分示例:

二 大致流程

这个流程图可以点击链接看到  验证码 快速入门_腾讯云

大致流程就是:

  • 前端请求appid
  • 拿到appid后使用腾讯云提供的方法,可以加载出来各种类型的验证码(验证码的类型,看appid申请的是什么样的)
  • 用户完成认证后,会得到返回一系列参数,如randstr,ticket
  • 前端拿着randstr,ticket请求后端接口,验证这个验证码是否OK,后端返回true或者false

三 腾讯云申请流程

1. 在腾讯云官网搜索验证码

2. 领取7天免费的,没用过验证码功能的第一次进去会看到领取的地方

3. 前往控制台

4. 记录下来生成的密钥

5 记录下来自己的账号密钥

四 后端代码编写

1. 总的demo结构

2. pom

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--   腾讯云 验证码    --><dependency><groupId>com.tencentcloudapi</groupId><artifactId>tencentcloud-sdk-java</artifactId><version>3.1.1297</version></dependency><!-- Lombok for reducing boilerplate code --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- Validation --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>

3. Yaml

server:port: 8080spring:application:name: tcaptcha-demo# 日志配置logging:level:org.example: DEBUGcom.tencentcloudapi: INFOpattern:console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"# 腾讯云验证码配置
tencent:captcha:# 腾讯云API密钥IDsecretId: xxxxxxxxxxxx# 腾讯云API密钥secretKey: xxxxxxxxxx# 验证码应用IDcaptchaAppId: 123456789# 验证码应用密钥appSecretKey: xxxxxxxx# API端点endpoint: xxxxxxxxxxxx# API服务名称service: captcha# API操作名称action: DescribeCaptchaResult# 验证码类型captchaType: 9# 是否需要获取验证码时间needGetCaptchaTime: 1# API版本version: "2025-07-10"

4. 配置类 config包下

4.1 

package org.example.config;import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 验证码配置类** @author wangmh**/
@Configuration
@EnableConfigurationProperties(CaptchaProperties.class)
public class CaptchaConfig {/*** 配置ObjectMapper* * @return ObjectMapper实例*/@Beanpublic ObjectMapper objectMapper() {ObjectMapper objectMapper = new ObjectMapper();objectMapper.registerModule(new JavaTimeModule());objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);return objectMapper;}
} 
package org.example.config;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;/*** 腾讯云验证码配置属性** @author wangmh**/
@Component
@ConfigurationProperties(prefix = "tencent.captcha")
public class CaptchaProperties {/*** 腾讯云API密钥ID*/private String secretId;/*** 腾讯云API密钥*/private String secretKey;/*** 验证码应用ID*/private Integer captchaAppId;/*** 验证码类型*/private Integer captchaType;/*** 是否需要获取验证码时间*/private Integer needGetCaptchaTime;/*** 应用密钥*/private String appSecretKey;/*** API版本*/private String version;/*** API端点*/private String endpoint;/*** API服务名称*/private String service;/*** API操作名称*/private String action;// Getters and Setterspublic String getSecretId() {return secretId;}public void setSecretId(String secretId) {this.secretId = secretId;}public String getSecretKey() {return secretKey;}public void setSecretKey(String secretKey) {this.secretKey = secretKey;}public Integer getCaptchaAppId() {return captchaAppId;}public void setCaptchaAppId(Integer captchaAppId) {this.captchaAppId = captchaAppId;}public Integer getCaptchaType() {return captchaType;}public void setCaptchaType(Integer captchaType) {this.captchaType = captchaType;}public Integer getNeedGetCaptchaTime() {return needGetCaptchaTime;}public void setNeedGetCaptchaTime(Integer needGetCaptchaTime) {this.needGetCaptchaTime = needGetCaptchaTime;}public String getAppSecretKey() {return appSecretKey;}public void setAppSecretKey(String appSecretKey) {this.appSecretKey = appSecretKey;}public String getVersion() {return version;}public void setVersion(String version) {this.version = version;}public String getEndpoint() {return endpoint;}public void setEndpoint(String endpoint) {this.endpoint = endpoint;}public String getService() {return service;}public void setService(String service) {this.service = service;}public String getAction() {return action;}public void setAction(String action) {this.action = action;}
} 

5 实体类  dto包下

package org.example.dto;import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;/*** 验证码验证请求DTO* * @author wangmh**/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CaptchaVerifyRequest {/*** 用户IP地址*/@NotBlank(message = "用户IP地址不能为空")@JsonProperty("userIp")private String userIp;/*** 随机字符串*/@NotBlank(message = "随机字符串不能为空")@JsonProperty("randstr")private String randstr;/*** 验证票据*/@NotBlank(message = "验证票据不能为空")@JsonProperty("ticket")private String ticket;
} 
package org.example.dto;import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;/*** 验证码验证响应DTO** @author wangmh**/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CaptchaVerifyResponse {/*** 请求ID*/@JsonProperty("RequestId")private String RequestId;/*** 验证码验证结果* 1: 验证通过*/@JsonProperty("CaptchaCode")private Integer CaptchaCode;/*** 验证码验证消息*/@JsonProperty("CaptchaMsg")private String CaptchaMsg;/*** 前端获取验证码时间*/@JsonProperty("GetCaptchaTime")private Integer GetCaptchaTime;/*** 提交验证码时间*/@JsonProperty("SubmitCaptchaTime")private Integer SubmitCaptchaTime;/*** 无感验证模式下,该参数返回验证结果*/@JsonProperty("EvilLevel")private Integer EvilLevel;/*** 拦截类型*/@JsonProperty("EvilBitmap")private Integer EvilBitmap;/*** 是否验证通过*/public boolean isSuccess() {return CaptchaCode != null && CaptchaCode == 1;}} 

6 Service

package org.example.service;import com.fasterxml.jackson.databind.ObjectMapper;
import com.tencentcloudapi.common.CommonClient;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.config.CaptchaProperties;
import org.example.dto.CaptchaVerifyRequest;
import org.example.dto.CaptchaVerifyResponse;
import org.springframework.stereotype.Service;import jakarta.annotation.PostConstruct;
import org.springframework.util.ObjectUtils;import java.util.HashMap;
import java.util.Map;/*** 腾讯云验证码服务** @author wangmh**/
@Slf4j
@Service
@RequiredArgsConstructor
public class CaptchaService {private final CaptchaProperties captchaProperties;private final ObjectMapper objectMapper;private CommonClient commonClient;/*** 初始化腾讯云客户端*/@PostConstructpublic void init() {try {Credential credential = new Credential(captchaProperties.getSecretId(), captchaProperties.getSecretKey());HttpProfile httpProfile = new HttpProfile();httpProfile.setEndpoint(captchaProperties.getEndpoint());ClientProfile clientProfile = new ClientProfile();clientProfile.setHttpProfile(httpProfile);this.commonClient = new CommonClient(captchaProperties.getService(),captchaProperties.getVersion(),credential,"",clientProfile);log.info("腾讯云验证码客户端初始化成功");} catch (Exception e) {log.error("腾讯云验证码客户端初始化失败", e);throw new RuntimeException("腾讯云验证码客户端初始化失败", e);}}/*** 验证验证码* * @param request 验证请求* @return 验证响应*/public CaptchaVerifyResponse verifyCaptcha(CaptchaVerifyRequest request) throws TencentCloudSDKException {try {Map<String, Object> params = buildRequestParams(request);String paramsJson = objectMapper.writeValueAsString(params);log.info("验证码请求参数: {}", paramsJson);String response = commonClient.call(captchaProperties.getAction(), paramsJson);log.info("腾讯云API响应: {}", response);Map<String, Object> responseMap = objectMapper.readValue(response, Map.class);CaptchaVerifyResponse captchaResponse = buildCaptchaResponse(responseMap);return captchaResponse;} catch (TencentCloudSDKException e) {log.error("腾讯云API调用失败", e);throw e;} catch (Exception e) {log.error("验证码验证过程中发生异常", e);throw new RuntimeException("验证码验证失败", e);}}/*** 构建请求参数* * @param request 验证请求* @return 请求参数Map*/private Map<String, Object> buildRequestParams(CaptchaVerifyRequest request) {Map<String, Object> params = new HashMap<>();// 从配置中获取的参数params.put("CaptchaAppId", captchaProperties.getCaptchaAppId());params.put("CaptchaType", captchaProperties.getCaptchaType());params.put("NeedGetCaptchaTime", captchaProperties.getNeedGetCaptchaTime());params.put("AppSecretKey", captchaProperties.getAppSecretKey());// 从请求中获取的参数params.put("UserIp", request.getUserIp());params.put("Randstr", request.getRandstr());params.put("Ticket", request.getTicket());return params;}/*** 简单验证方法 - 只返回是否验证通过* * @param userIp 用户IP* @param randstr 随机字符串* @param ticket 验证票据* @return 是否验证通过*/public boolean isCaptchaValid(String userIp, String randstr, String ticket) {try {CaptchaVerifyRequest request = CaptchaVerifyRequest.builder().userIp(userIp).randstr(randstr).ticket(ticket).build();CaptchaVerifyResponse response = verifyCaptcha(request);return response.isSuccess();} catch (Exception e) {log.error("验证码验证失败", e);return false;}}/*** 构建验证码响应对象** @param responseMap 响应Map* @return 验证码响应对象*/private CaptchaVerifyResponse buildCaptchaResponse(Map<String, Object> responseMap) {CaptchaVerifyResponse response = new CaptchaVerifyResponse();try {if (responseMap.containsKey("Response")) {Map<String, Object> responseData = (Map<String, Object>) responseMap.get("Response");populateResponse(response, responseData);}} catch (Exception e) {log.error("解析响应数据失败", e);}return response;}/*** 填充响应数据** @param response 响应对象* @param data 数据Map*/private void populateResponse(CaptchaVerifyResponse response, Map<String, Object> data) {if (data.containsKey("RequestId")) {response.setRequestId((String) data.get("RequestId"));}if (data.containsKey("CaptchaCode")) {Object v = data.get("CaptchaCode");if (!ObjectUtils.isEmpty(v))response.setCaptchaCode(v instanceof Integer ? (Integer) v : Integer.parseInt(v.toString()));}if (data.containsKey("CaptchaMsg")) {response.setCaptchaMsg((String) data.get("CaptchaMsg"));}if (data.containsKey("GetCaptchaTime")) {Object v = data.get("GetCaptchaTime");if (!ObjectUtils.isEmpty(v))response.setGetCaptchaTime(v instanceof Integer ? (Integer) v : Integer.parseInt(v.toString()));}if (data.containsKey("SubmitCaptchaTime")) {Object v = data.get("SubmitCaptchaTime");if (!ObjectUtils.isEmpty(v))response.setSubmitCaptchaTime(v instanceof Integer ? (Integer) v : Integer.parseInt(v.toString()));}if (data.containsKey("EvilLevel")) {Object v = data.get("EvilLevel");if (!ObjectUtils.isEmpty(v))response.setEvilLevel(v instanceof Integer ? (Integer) v : Integer.parseInt(v.toString()));}if (data.containsKey("EvilBitmap")) {Object v = data.get("EvilBitmap");if (!ObjectUtils.isEmpty(v))response.setEvilBitmap(v instanceof Integer ? (Integer) v : Integer.parseInt(v.toString()));}}} 

6. Controller

package org.example.controller;import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.config.CaptchaProperties;
import org.example.dto.CaptchaVerifyRequest;
import org.example.dto.CaptchaVerifyResponse;
import org.example.service.CaptchaService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;import jakarta.validation.Valid;/*** 验证码控制器** @author wangmh**/
@Slf4j
@RestController
@RequestMapping("/api/captcha")
@RequiredArgsConstructor
public class CaptchaController {private final CaptchaService captchaService;private final CaptchaProperties captchaProperties;/*** 验证验证码* * @param request 验证请求* @return 验证结果*/@PostMapping("/verify")public ResponseEntity<CaptchaVerifyResponse> verifyCaptcha(@Valid @RequestBody CaptchaVerifyRequest request) {try {log.info("收到简单验证码验证请求: userIp={}, randstr={}", request.getUserIp(), request.getRandstr());CaptchaVerifyResponse response = captchaService.verifyCaptcha(request);return ResponseEntity.ok(response);} catch (Exception e) {log.error("验证码验证失败", e);return ResponseEntity.internalServerError().build();}}/*** 简单验证接口* * @param userIp 用户IP* @param randstr 随机字符串* @param ticket 验证票据* @return 是否验证通过*/@GetMapping("/verify")public ResponseEntity<Boolean> verifyCaptchaSimple(@RequestParam String userIp,@RequestParam String randstr,@RequestParam String ticket) {try {log.info("收到简单验证码验证请求: userIp={}, randstr={}", userIp, randstr);boolean isValid = captchaService.isCaptchaValid(userIp, randstr, ticket);log.info("收到简单验证码验证请求: userIp={}, randstr={} 验证结果:{}", userIp, randstr, isValid);return ResponseEntity.ok(isValid);} catch (Exception e) {log.error("验证码验证失败", e);return ResponseEntity.internalServerError().build();}}/*** 获取验证码应用ID* @return captchaAppId*/@GetMapping("/appid")public ResponseEntity<Integer> getCaptchaAppId() {return ResponseEntity.ok(captchaProperties.getCaptchaAppId());}} 

7. 请求测试

五 前端代码

里面的js 下载地址:https://turing.captcha.qcloud.com/TJCaptcha.js

css 可以删掉

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Web 前端接入示例</title><link rel="stylesheet" href="./css/style.css"><!-- 验证码程序依赖(必须)。请勿修改以下程序依赖,如通过其他手段规避加载,会导致验证码无法正常更新,对抗能力无法保证,甚至引起误拦截。 --><script src="./js/TJCaptcha.js"></script>
</head><body><button id="CaptchaId" type="button">验证</button>
</body><script>// 定义回调函数function callback(res) {// 第一个参数传入回调结果,结果如下:// ret         Int       验证结果,0:验证成功。2:用户主动关闭验证码。// ticket      String    验证成功的票据,当且仅当 ret = 0 时 ticket 有值。// CaptchaAppId       String    验证码应用ID。// bizState    Any       自定义透传参数。// randstr     String    本次验证的随机串,后续票据校验时需传递该参数。// verifyDuration     Int   验证码校验接口耗时(ms)。// actionDuration     Int   操作校验成功耗时(用户动作+校验完成)(ms)。// sid     String   链路sid。console.log('callback:', res);// res(用户主动关闭验证码)= {ret: 2, ticket: null}// res(验证成功) = {ret: 0, ticket: "String", randstr: "String"}// res(请求验证码发生错误,验证码自动返回trerror_前缀的容灾票据) = {ret: 0, ticket: "String", randstr: "String",  errorCode: Number, errorMessage: "String"}// 此处代码仅为验证结果的展示示例,真实业务接入,建议基于ticket和errorCode情况做不同的业务处理if (res.ret === 0) {// 复制结果至剪切板var str = '【randstr】->【' + res.randstr + '】      【ticket】->【' + res.ticket + '】';var ipt = document.createElement('input');ipt.value = str;document.body.appendChild(ipt);ipt.select();document.execCommand("Copy");document.body.removeChild(ipt);alert('1. 返回结果(randstr、ticket)已复制到剪切板,ctrl+v 查看。2. 打开浏览器控制台,查看完整返回结果。');}}// 定义验证码js加载错误处理函数function loadErrorCallback() {var appid = '您的CaptchaAppId';// 生成容灾票据或自行做其它处理var ticket = 'trerror_1001_' + appid + '_' + Math.floor(new Date().getTime() / 1000);callback({ret: 0,randstr: '@' + Math.random().toString(36).substr(2),ticket: ticket,errorCode: 1001,errorMessage: 'jsload_error'});}// 定义验证码触发事件window.onload = function () {document.getElementById('CaptchaId').onclick = function () {try {// 生成一个验证码对象// CaptchaAppId:登录验证码控制台,从【验证管理】页面进行查看。如果未创建过验证,请先新建验证。注意:不可使用客户端类型为小程序的CaptchaAppId,会导致数据统计错误。//callback:定义的回调函数var captcha = new TencentCaptcha('198595300', callback, {userLanguage: 'zh-cn',showFn: (ret) => {const {duration, // 验证码渲染完成的耗时(ms)sid, // 链路sid} = ret;},});// 调用方法,显示验证码captcha.show();} catch (error) {// 加载异常,调用验证码js加载错误处理函数loadErrorCallback();}}}
</script></html>

六 官方文档

验证码产品页面:T-sec-腾讯安全天御-行为式验证码 Captcha-腾讯云

产品叙述:验证码 产品概述_腾讯云


web端接入:验证码 Web 客户端接入_腾讯云

接收票据校验:验证码 接入票据校验(Web 及 App)_腾讯云

核验验证码票据结果:验证码 核查验证码票据结果(Web及APP)_腾讯云

jar包引入:云产品SDK中心_云产品SDK文档-腾讯云

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/88249.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/88249.shtml
英文地址,请注明出处:http://en.pswp.cn/web/88249.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SenseGlove新一代外骨骼力反馈手套Rembrand来袭!亚毫米级手部动捕+指尖触觉力采集+5Dof主动力反馈多模态

在远程机器人操作领域&#xff0c;精准的触觉感知与灵活的动作控制始终是核心需求。SenseGlove 新推出的 Rembrandt 力反馈外骨骼数据手套&#xff0c;以先进技术为支撑&#xff0c;为远程操控人形机器人手部提供了无缝解决方案&#xff0c;让操作更精准、更高效。值得一提的是…

Linux 信号机制:操作系统的“紧急电话”系统

想象一下&#xff0c;你正在电脑前专心工作&#xff0c;突然手机响了——这是一个通知&#xff0c;要求你立即处理一件新事情&#xff08;比如接电话&#xff09;。 Linux 系统中的信号&#xff08;Signal&#xff09;​​ 机制&#xff0c;本质上就是操作系统内核或进程之间用…

论文略读:Prefix-Tuning: Optimizing Continuous Prompts for Generation

2021 ACL固定预训练LM&#xff0c;为LM添加可训练&#xff0c;任务特定的前缀这样就可以为不同任务保存不同的前缀这种前缀可以看成连续可微的soft prompt&#xff0c;相比于离散的token&#xff0c;更好优化&#xff0c;效果更好训练的时候只需要更新prefix部分的参数&#xf…

CSS基础选择器、文本属性、引入方式及Chorme调试工具

CSS基础 1.1 CSS简介 CSS 是层叠样式表 ( Cascading Style Sheets ) 的简称. 有时我们也会称之为 CSS 样式表或级联样式表。 CSS 是也是一种标记语言 CSS 主要用于设置 HTML 页面中的文本内容&#xff08;字体、大小、对齐方式等&#xff09;、图片的外形&#xff08;宽高、边…

RabbitMQ 高级特性之事务

1. 简介与 MySQL、Redis 一样&#xff0c;RabbitMQ 也支持事务。事务中的消息&#xff0c;要么全都发送成功&#xff0c;要么全部发送失败&#xff0c;不会出现一部分成功一部分失败的情况。2. 使用事务发送消息spring 中使用 RabbitMQ 开启事务需要两步&#xff1a;第一步&…

iframe 的同源限制与反爬机制的冲突

一、事件背景A域名接入了动态防护&#xff08;Bot 防护、反爬虫机制&#xff09;&#xff0c;同时第三方业务B域名通过内嵌iframe的方式调用了A域名下的一个链接。二、动态防护介绍&#xff1a;动态防护&#xff08;也称为 Bot 防护、反爬虫机制&#xff09;是网站为了防止自动…

Rust 的 Copy 语义:深入浅出指南

在 Rust 中&#xff0c;Copy 是一个关键的特性&#xff0c;它定义了类型的复制行为。理解 Copy 语义对于掌握 Rust 的所有权系统和编写高效代码至关重要。一、核心概念&#xff1a;Copy vs Move特性Copy 类型非 Copy 类型 (Move)赋值行为按位复制 (bitwise copy)所有权转移 (ow…

Qt的信号与槽(二)

Qt的信号与槽&#xff08;二&#xff09;1.自定义槽2.通过图形化界面来生成自定义槽3.自定义信号3.信号和槽带参数4.参数数量5.connect函数的设计&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f;&#x1f31f; &#x1f680;&#x1f680;系列专栏&#xf…

Java研学-MongoDB(三)

三 文档相关 7 文档统计查询① 语法&#xff1a; // 精确统计文档数 慢 准 dahuang> db.xiaohuang.countDocuments({条件}) 4 // 粗略统计文档数 快 大致准 dahuang> db.xiaohuang.estimatedDocumentCount({条件}) 4② 例子&#xff1a; // 精确统计文档数 name为奔波儿灞…

TCP协议格式与连接释放

TCP报文段格式 TCP虽然是面向字节流的&#xff0c;但TCP传送带数据单元确是报文段。TCP报文段分为首部和数据段部分&#xff0c;而TCP的全部功能体现在它在首部中各字段的作用。因此&#xff0c;只有弄清TCP首部各字段的作用才能掌握TCP的工作原理。 TCP报文段首部的前20字节是…

CSS05:结构伪类选择器和属性选择器

结构伪类选择器 /*ul的第一个子元素*/ ul li:first-child{background: #0af6f6; }/*ul的最后一个子元素*/ ul li:last-child{background: #d27bf3; } /*选中p1&#xff1a;定位到父元素&#xff0c;选择当前的第一个元素 选择当前p元素的父级元素&#xff0c;选中父级元素的第…

使用策略模式 + 自动注册机制来构建旅游点评系统的搜索模块

✅ 目标&#xff1a; 搜索模块支持不同内容类型&#xff08;攻略、达人、游记等&#xff09;每种搜索逻辑用一个策略类表示自动注册&#xff08;基于注解 Spring 容器&#xff09;新增搜索类型时&#xff0c;只需添加一个类 一个注解&#xff0c;无需改工厂、注册表等&#x…

第八十九篇 大数据开发中的数据算法:贪心策略 - 生活中的“精打细算”艺术

在资源有限的世界里&#xff0c;贪心算法教会我们&#xff1a;局部最优的累积&#xff0c;往往是通往全局最高效的捷径。本文通过3个生活化场景原创图表&#xff0c;揭示大数据开发中最实用的优化策略。目录一、贪心算法核心思想&#xff1a;当下即最优二、三大核心应用场景详解…

【论文阅读】Dynamic Few-Shot Visual Learning without Forgetting

系统概述如下: (a) 一个基于卷积神经网络(ConvNet)的识别模型,该模型包含特征提取器和分类器; (b) 一个少样本分类权重生成器。这两个组件都是在一组基础类别上训练的,我们为这些类别准备了大量训练数据。在测试阶段,权重生成器会接收少量新类别的训练数据以及基础类别的…

HTML应用指南:利用GET请求获取全国山姆门店位置信息

山姆会员店作为全球知名的零售品牌&#xff0c;自进入中国市场以来&#xff0c;始终致力于为消费者提供高品质商品与便捷的购物体验。随着新零售业态的快速发展&#xff0c;门店位置信息的获取变得愈发重要。品牌通过不断拓展门店网络&#xff0c;目前已覆盖多个一、二线城市&a…

java ThreadLocal源码分析

写个demo测试下&#xff1a;private static void testThreadLocal() {ThreadLocal<Integer> threadLocal new ThreadLocal<>();new Thread(){Overridepublic void run() {threadLocal.set(9527);System.out.println("curr thread: " Thread.currentThr…

后端Web实战(项目管理)

Restful风格 我们的案例是基于当前最为主流的前后端分离模式进行开发 在前后端分离的开发模式中&#xff0c;前后端开发人员都需要根据提前定义好的接口文档&#xff0c;来进行前后端功能的开发。 后端开发人员&#xff1a;必须严格遵守提供的接口文档进行后端功能开发&#…

Leetcode 3604. Minimum Time to Reach Destination in Directed Graph

Leetcode 3604. Minimum Time to Reach Destination in Directed Graph 1. 解题思路2. 代码实现 题目链接&#xff1a;3604. Minimum Time to Reach Destination in Directed Graph 1. 解题思路 这一题思路上就是一个广度优先遍历&#xff0c;我们不断考察当前时间点以及位置…

OpenXR Runtime切换工具-OpenXR-Runtime-Switcher

在开发VR时&#xff0c;有时有多个设备&#xff0c;大家可能也会选择不同的串流工具&#xff0c;OpenXR类似于默认浏览器&#xff0c;如果设置错误可能导致游戏无法串流。 推荐一个工具&#xff0c;可以设置默认的OpenXR工具。 OpenXR-Runtime-Switcher 对于没有的设备&#…

Opencv探索之旅:从像素变化到世界轮廓的奥秘

在你已经能熟练地为图像施展“降噪”、“缩放”等魔法之后&#xff0c;你的探索之旅来到了一个全新的领域。你可能会好奇&#xff1a;我们人类能轻易地识别出照片中杯子的边缘、建筑的轮廓&#xff0c;那计算机是如何“看见”这些边界的呢&#xff1f;仅仅依靠滤波和颜色变换&a…