安全架构概述

安全架构是确保网络环境中的数据、系统和用户安全的关键组成部分,它涉及到多种技术和策略的综合应用。基本内容主要包括以下几个方面:

1.  访问控制与身份验证 :确保只有经过验证的用户或系统可以访问特定资源,常用技术包括多因素认证、访问控制列表(ACL)、角色基础访问控制(RBAC)等。

2.  加密技术 :用于保护数据的机密性和完整性,如SSL/TLS协议用于加密网络通信,AES、RSA等算法用于数据加密和数字签名。

3.  防火墙与边界防护 :设置在网络边缘的防火墙监控进出流量,根据预定义规则过滤恶意或非授权访问。

4.  入侵检测与防御系统(IDS/IPS) :自动监测网络活动,识别并阻止潜在的攻击行为。

5.  安全协议与标准 :遵循如HTTPS、SSH、SFTP等安全协议,以及行业安全标准如PCI-DSS、GDPR等,以确保合规性。

6.  数据备份与恢复计划 :定期备份重要数据,并建立灾难恢复计划,以防数据丢失或损坏。

7.  漏洞管理与补丁更新 :定期扫描系统和应用程序漏洞,并及时应用补丁,减少被利用的风险。

8.  安全审计与日志管理 :记录并分析系统活动日志,用于监控异常行为,支持事件调查。

9.  应急响应计划 :制定应对安全事件的预案,包括事件报告流程、隔离受损系统、恢复操作等步骤。

 案例分析示例 :

-  数据泄露事件 :某大型互联网公司遭遇黑客攻击,导致用户数据泄露。公司迅速启动应急响应计划,包括立即断开受感染系统与网络的连接,通知受影响用户,加强监控并修复系统漏洞,同时配合执法部门调查。此案例强调了应急响应计划的重要性及数据保护的必要性。

-  XSS攻击 :在一个在线购物平台上,攻击者利用XSS漏洞在商品评论区植入恶意脚本,当其他用户查看评论时,脚本被执行,窃取用户的登录凭证。对此,平台升级了其Web应用防火墙规则,实施输入验证和输出编码,以防止此类跨站脚本攻击,体现了Web安全防护的必要性。

这些架构内容和案例展示了互联网安全是一个多层面、动态调整的过程,需要持续监控、评估风险并采取相应措施。

访问控制与身份验证是确保系统安全的核心组件,它们的实现通常涉及复杂的逻辑和多种技术手段。源码说明会根据具体的应用场景和技术栈有所不同,但核心思想和流程大致相似。以下是一个简化的示例,说明一个基于令牌(Token)的身份验证与访问控制过程,这在微服务架构中非常常见:

### 示例:基于JWT的访问控制与身份验证

  1. 用户认证  

-   登录接口  :用户向服务器提供用户名和密码。
-   服务器验证  :后端验证用户名和密码是否匹配数据库记录。
-   生成JWT  :验证成功后,服务器生成一个JSON Web Token(JWT),这个Token包含了用户的身份信息(如用户ID、角色等),并使用私钥进行签名,保证其不可篡改。
-   返回Token  :服务器将JWT发送给客户端,客户端通常存储在本地(如Cookie或LocalStorage)。

  源码示例(伪代码)  :

```python

# 假设使用Python的Flask框架和PyJWT库
from flask import Flask, request, jsonify
import jwt
from jwt import exceptionsapp = Flask(__name__)SECRET_KEY = 'your_secret_key'@app.route('/login', methods=['POST'])
def login():username = request.json.get('username')password = request.json.get('password')# 简化处理,实际应从数据库验证if username == 'user' and password == 'password':payload = {'exp': datetime.utcnow() + timedelta(minutes=30),'iat': datetime.utcnow(),'sub': username}token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')return jsonify({'token': token}), 200else:return jsonify({'error': 'Invalid credentials'}), 401

```

  2. 访问控制  

-   中间件或装饰器  :在需要保护的API路由前添加身份验证逻辑,检查每个请求的JWT。
-   验证Token  :服务器解码并验证JWT的有效性(未过期、签名正确)。
-   提取用户信息  :从Token中提取用户角色或其他权限信息。
-   授权决策  :根据用户角色或具体权限决定是否允许访问特定资源。

  源码示例(伪代码)  :

```python

def token_required(f):@wraps(f)def decorator(*args,   kwargs):token = Noneif 'x-access-token' in request.headers:token = request.headers['x-access-token']if not token:return jsonify({'message': 'Token is missing!'}), 401try:data = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])current_user = data['sub']except exceptions:return jsonify({'message': 'Token is invalid!'}), 401return f(current_user, *args,   kwargs)return decorator@app.route('/protected', methods=['GET'])
@token_required
def protected_route(current_user):return jsonify({'message': f'Hello, {current_user}! This is a protected route.'}), 200

```

上述代码示例展示了如何实现一个简单的基于JWT的用户认证和访问控制流程。在实际应用中,还需考虑更多安全细节,比如使用HTTPS、处理Token刷新、防止重放攻击等。不同的编程语言和框架会有相应的库和最佳实践来支持这些功能。

基于JWT(JSON Web Tokens)的访问控制与身份验证在Java中通常使用一些流行的库来实现,例如jjwt库用于生成和解析JWT,Spring Security框架可以进一步增强安全性并简化身份验证和授权的实现。下面是一个简化的示例,展示如何在Java Spring Boot应用中实现JWT的登录认证和访问控制。

1. 添加依赖
首先,在你的pom.xml文件中添加必要的依赖。这里使用jjwt库处理JWT以及Spring Security。

<dependencies><!-- Spring Boot Starter Security --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- jjwt for JWT handling --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.2</version></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.2</version><scope>runtime</scope></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred --><version>0.11.2</version><scope>runtime</scope></dependency>
</dependencies>

2. JWT工具类

创建一个JWT工具类,用于生成和解析JWT。

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;public class JwtUtil {private static final long EXPIRATION_TIME = 864_000_000; // 10 daysprivate static final String SIGNING_KEY = "yourSecretKey";public String generateToken(UserDetails userDetails) {Map<String, Object> claims = new HashMap<>();return Jwts.builder().setClaims(claims).setSubject(userDetails.getUsername()).setIssuedAt(new Date(System.currentTimeMillis())).setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)).signWith(SignatureAlgorithm.HS256, SIGNING_KEY).compact();}public boolean validateToken(String token, UserDetails userDetails) {String username = getUsernameFromToken(token);return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));}public String getUsernameFromToken(String token) {return getClaimFromToken(token, Claims::getSubject);}private Date getExpirationDateFromToken(String token) {return getClaimFromToken(token, Claims::getExpiration);}private <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {final Claims claims = getAllClaimsFromToken(token);return claimsResolver.apply(claims);}private Claims getAllClaimsFromToken(String token) {return Jwts.parser().setSigningKey(SIGNING_KEY).parseClaimsJws(token).getBody();}private Boolean isTokenExpired(String token) {final Date expiration = getExpirationDateFromToken(token);return expiration.before(new Date());}
}

3. Spring Security配置

配置Spring Security以使用JWT进行身份验证。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate UserDetailsService userDetailsService;@Autowiredprivate JwtAuthenticationEntryPoint unauthorizedHandler;@Beanpublic JwtAuthenticationFilter jwtAuthenticationFilter() {return new JwtAuthenticationFilter();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.cors().and().csrf().disable().exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests().antMatchers("/api/auth/**").permitAll().anyRequest().authenticated();http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);}
}

4. JWT过滤器

创建JWT过滤器,用于解析JWT并设置用户认证信息。

import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {@Autowiredprivate JwtUtil jwtUtil;@Autowiredprivate UserDetailsService userDetailsService;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws ServletException, IOException {final String header = request.getHeader("Authorization");if (header != null && header.startsWith("Bearer ")) {try {String jwt = header.substring(7);if (!jwtUtil.isTokenExpired(jwt)) {String username = jwtUtil.getUsernameFromToken(jwt);UserDetails userDetails = userDetailsService.loadUserByUsername(username);if (jwtUtil.validateToken(jwt, userDetails)) {UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));SecurityContextHolder.getContext().setAuthentication(authentication);}}} catch (IllegalArgumentException | ExpiredJwtException e) {logger.error("JWT token is invalid: {}", e.getMessage());}}chain.doFilter(request, response);}
}

这个示例展示了如何在Java Spring Boot应用中使用JWT进行用户身份验证和访问控制的基础配置。请根据你的具体需求调整代码,例如添加更细粒度的权限控制、异常处理等。

5. 用户登录认证实现

为了完成用户登录并返回JWT Token的功能,你需要实现一个API端点。这通常涉及到验证用户凭据(如用户名和密码),然后生成一个JWT令牌并将其返回给客户端。

下面是如何实现一个简单的登录认证控制器:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/api/auth")
public class AuthController {@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate JwtUtil jwtTokenUtil;@PostMapping("/signin")public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {try {Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));SecurityContextHolder.getContext().setAuthentication(authentication);String jwt = jwtTokenUtil.generateToken(authentication.getName());return ResponseEntity.ok(new JwtResponse(jwt));} catch (BadCredentialsException e) {return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new ApiResponse(false, "Invalid username or password"));}}
}// 假设的LoginRequest和JwtResponse类定义
public class LoginRequest {private String username;private String password;// getters and setters
}public class JwtResponse {private String token;public JwtResponse(String token) {this.token = token;}// getters
}public class ApiResponse {private boolean success;private String message;public ApiResponse(boolean success, String message) {this.success = success;this.message = message;}// getters
}

在这个例子中,AuthController中的authenticateUser方法接收用户的登录请求,尝试使用AuthenticationManager验证提供的用户名和密码。如果认证成功,使用JwtUtil生成JWT令牌,并通过JwtResponse对象返回给客户端。如果认证失败,则返回一个错误响应。

6. 注意事项
安全性: 确保使用安全的方式来存储JWT的密钥(SIGNING_KEY),并且在生产环境中使用HTTPS来保护传输中的数据。
资源服务器配置: 上述示例主要集中在认证逻辑上,实际应用中还需配置资源服务器来验证JWT并执行相应的授权逻辑。
刷新令牌: 实际应用中,可能需要实现JWT的刷新机制,以便在令牌过期时无需重新登录。
错误处理: 完善错误处理逻辑,避免泄露过多信息给潜在攻击者。
这些步骤和代码片段为你提供了基于JWT的访问控制与身份验证的基本框架。根据你的具体应用场景,可能还需要进一步定制和优化。

7. 用户注销与令牌失效

在许多应用中,用户注销功能同样重要,它涉及到使当前用户的JWT令牌失效。然而,由于JWT的设计是无状态的且一旦签发无法撤销,直接使JWT失效较为复杂。一种常见的做法是维护一个黑名单或者使用较短的有效期结合刷新令牌机制。

黑名单策略

维护一个JWT黑名单,当用户注销时,将该用户的JWT添加到黑名单中。之后,每次请求到达服务器时,除了验证JWT的有效性外,还要检查它是否在黑名单中。

刷新令牌(Refresh Token)

使用刷新令牌机制可以提高安全性,同时允许用户保持登录状态更长时间。基本思路是,用户登录时,服务器不仅返回一个短期有效的访问令牌(Access Token),还会返回一个长期有效的刷新令牌(Refresh Token)。当访问令牌过期时,客户端可以使用刷新令牌获取一个新的访问令牌,而无需用户提供凭证。当用户注销时,服务器可以撤销对应的刷新令牌,从而阻止后续获取新的访问令牌。

8. 示例代码:添加注销功能

假设我们采用刷新令牌机制,并在用户注销时撤销其刷新令牌。

首先,确保数据库中有保存和管理刷新令牌的机制。下面是一个简化的示例,展示如何在注销时从数据库中删除用户的刷新令牌。

@RestController
@RequestMapping("/api/auth")
public class AuthController {// 假设有一个RefreshTokenService来处理刷新令牌的存储和撤销@Autowiredprivate RefreshTokenService refreshTokenService;@PostMapping("/signout")public ResponseEntity<?> logoutUser() {// 假设当前用户信息可以从SecurityContext中获取String username = SecurityContextHolder.getContext().getAuthentication().getName();// 从数据库中撤销用户的刷新令牌refreshTokenService.revokeRefreshTokensForUser(username);return ResponseEntity.ok(new ApiResponse(true, "User logged out successfully"));}
}@Service
public class RefreshTokenService {// 假设的逻辑来存储和检索刷新令牌public void revokeRefreshTokensForUser(String username) {// 这里应该有逻辑去数据库中找到该用户的刷新令牌并标记为已撤销或直接删除}
}

9. 注意事项

  • 安全性: 在处理刷新令牌时要特别注意安全性,包括存储、传输和撤销过程。
  • 客户端处理: 客户端应用程序需要妥善处理访问令牌过期和使用刷新令牌的情况,确保用户体验流畅。
  • 并发问题: 在高并发环境下,确保撤销刷新令牌的操作是原子性的,防止并发冲突。

通过上述步骤,你不仅可以实现用户的登录认证,还能提供用户注销功能,并通过刷新令牌机制增强安全性。请根据你的具体需求调整和扩展这些方案。

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

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

相关文章

MySQL从入门到高级 --- 4.约束

文章目录 第四章&#xff1a;4.MySQL约束4.1 主键约束4.1.1 添加单列主键4.1.2 添加多列主键(联合主键)4.1.3 通过修改表结构添加主键4.1.4 删除主键约束4.1.5 自增长约束特点 4.1.6 指定自增字段初始值 - 创建表时指定4.1.7 指定自增字段初始值 - 创建表之后4.1.8 delete与tru…

如何配置 Prettier 配置文件,确保其中的文件 glob 模式能够正确包含 postcss.config.js 文件

如何配置 Prettier 配置文件&#xff0c;确保其中的文件 glob 模式能够正确包含 postcss.config.js 文件 要配置 Prettier 以确保其文件 glob 模式能够正确包含 postcss.config.js 文件&#xff0c;您可以按照以下步骤操作&#xff1a; 确认 Prettier 配置文件的存在&#xf…

商城数据库88张表结构(十五)

DDL 57.后台权限表 CREATE TABLE wang_privileges (privilegeId int(11) NOT NULL AUTO_INCREMENT COMMENT 自增ID,menuId int(11) NOT NULL COMMENT 父ID,privilegeCode varchar(20) NOT NULL COMMENT 权限代码,privilegeName varchar(30) NOT NULL COMMENT 权限名称,isMenu…

websocket全局封装使用

WebSocket对象的创建 WebSocket对象的关闭 启用心跳机制&#xff0c;避免断连 消息推送&#xff0c;接收到消息后进行业务逻辑处理 重连机制&#xff0c;如果断连后尝试一定次数的重连&#xff0c;超过最大次数后仍然失败则关闭连接 调用案例如下&#xff1a; const socketMana…

Vue笔记 4

内置指令 1.v-text_指令 我们学过的指令&#xff1a; ​ v-bind : 单向绑定解析表达式, 可简写为 :xxx ​ v-model : 双向数据绑定 ​ v-for : 遍历数组/对象/字符串 ​ v-on : 绑定事件监听, 可简写为 ​ v-if : 条件渲染&#xff08;动态控制节点是否存存在&#xff0…

洞察未来:数据治理中的数据架构新思维

随着大数据时代的来临&#xff0c;数据已经成为企业运营和社会发展的重要资产。然而&#xff0c;数据的复杂性和快速增长给企业带来了前所未有的挑战。在这样的背景下&#xff0c;数据治理成为了企业不可或缺的一环。数据治理不仅涉及数据的管理、安全和隐私保护&#xff0c;更…

ubuntu部署sonar与windows下使用sonar-scanner

ubuntu部署sonar与windows下使用sonar-scanner sonar部署java安装mysql安装配置sonarqube 插件安装sonar-scanner使用简单使用 sonar部署 使用的是sonarqube-7.5&#xff0c;支持的java环境是jdk8&#xff0c;且MySQL版本 >5.6 && <8.0 java安装 打开终端&…

Jackson-自定义注解及实现数据脱敏、枚举转换

Hi,大家好&#xff0c;我是抢老婆酸奶的小肥仔。 上一章&#xff0c;我们介绍了下Jackson及相关的注解&#xff0c;其实我们可以通过仿照一些注解来实现自定义以满足我们自己的业务需求&#xff0c;这一章&#xff0c;我们来说说jackson提供的自定义注解及一些应用吧。 废话不…

Virtualbox7.0.10--创建虚拟机

前言 下载Virtualbox7.0.10&#xff0c;可参考《Virtualbox–下载指定版本》 Virtualbox7.0.10具体安装步骤&#xff0c;可参考《Virtualbox7.0.10的安装步骤》 Virtualbox7.0.10创建虚拟机&#xff0c;可参考《Virtualbox7.0.10–创建虚拟机》 Virtualbox7.0.10安装Ubuntu20.0…

H.265码流解析

这一篇内容旨在对H.265码流中的一些概念做简单了解,部分概念与H.264相同,本篇中将不再重复。 1、NALU H.265(HEVC)码流的NALU结构和AVC有一些不同,属于增强版,HEVC NALU结构如下: NALU Header: Forbidden_zero_bit:1位,必须为0,如果不是则表示NALU非法;Nal_unit_t…

后端如何处理接口的重复调用

首先是&#xff0c;原理在请求接口之前&#xff0c;使用过滤器拦截数据&#xff0c;来进行判断两次数据是否一致。 1.自定义注解 2.创建一个Handler处理器 3.RepeatSubmitInterceptor的实现类 4.过滤器的配置

大型企业总分支多区域数据传输,效率为先还是安全为先?

大型企业为了业务拓展需要&#xff0c;会在全国乃至全球各地设立分公司和办事机构&#xff0c;以便更好地处理当地事务&#xff0c;并进行市场的开拓和客户维护&#xff0c;此时&#xff0c;企业内部就衍生出了新的业务需求&#xff0c;即多区域数据传输。 多区域很难准确定义&…

云容器与云中间件

云容器与中间件是两种不同的技术和服务类别&#xff0c;它们分别在云计算环境中扮演着不同的角色&#xff0c;旨在帮助企业构建、部署、管理应用程序并确保其高效、可靠地运行。下面分别介绍两者的基本概念、包含的内容以及各自的用途。 容器 基本概念&#xff1a; 在腾讯云中…

[C++][算法基础]最大不相交区间数量(贪心 + 区间问题2)

给定 &#x1d441; 个闭区间 [&#x1d44e;&#x1d456;,&#x1d44f;&#x1d456;]&#xff0c;请你在数轴上选择若干区间&#xff0c;使得选中的区间之间互不相交&#xff08;包括端点&#xff09;。 输出可选取区间的最大数量。 输入格式 第一行包含整数 &#x1d4…

Aiseesoft Data Recovery for Mac:专业数据恢复软件

Aiseesoft Data Recovery for Mac是一款高效且专业的数据恢复软件&#xff0c;专为Mac用户量身打造。 Aiseesoft Data Recovery for Mac v1.8.22激活版下载 无论是由于误删、格式化还是系统崩溃等原因导致的数据丢失&#xff0c;Aiseesoft都能帮助您快速找回。 它采用先进的扫描…

使用命令删除zip中的文件

要删除zip文件中的某个文件&#xff0c;可以使用zip工具的-d&#xff08;delete&#xff09;选项。 首先需要确保系统已安装zip程序&#xff0c;通常会预装在Linux与macOS上。在Windows系统上&#xff0c;可能要安装额外的压缩工具如7-zip&#xff0c;才能在命令行中执行这类操…

IDEA插件-通义灵码 VS ChatGPT-EasyCode

智能编码助手新时代&#xff1a;通义灵码 vs ChatGPT-EasyCode 随着人工智能技术的飞速发展&#xff0c;智能编码助手逐渐成为程序员的必备工具。它们可以帮助程序员提高编码效率&#xff0c;降低代码缺陷率&#xff0c;并解放创造力。 目前市场上涌现出了众多智能编码助手&a…

Golang | Leetcode Golang题解之第60题排列序列

题目&#xff1a; 题解&#xff1a; func getPermutation(n int, k int) string {factorial : make([]int, n)factorial[0] 1for i : 1; i < n; i {factorial[i] factorial[i - 1] * i}k--ans : ""valid : make([]int, n 1)for i : 0; i < len(valid); i {…

【哈希】Leetcode 217. 存在重复元素

题目讲解 217. 存在重复元素 算法讲解 使用set集合完成元素的存储&#xff0c;当我们将当前元素插入到集合单中&#xff0c;如果insert的返回值的pair.second等于false说明当前元素已经存在&#xff0c;反之元素在集合中存在 class Solution { public:bool containsDuplica…

开放式耳机哪个牌子好?五大爆款机型大盘点

开放式耳机采用挂耳设计&#xff0c;体积小巧&#xff0c;携带方便&#xff0c;并且更加通风透气&#xff0c;避免了耳朵过热和出汗导致的问题&#xff1b;更轻的重量能有效减少长期佩戴对耳朵带来的压力&#xff0c;佩戴时舒适度直接爆表&#xff0c;在跑步、爬山、打球等户外…