安全架构概述

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

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 exceptions

app = 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}), 200
    else:
        return jsonify({'error': 'Invalid credentials'}), 401

```

  2. 访问控制  

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

  源码示例(伪代码)  :

```python

def token_required(f):
    @wraps(f)
    def decorator(*args,   kwargs):
        token = None
        if 'x-access-token' in request.headers:
            token = request.headers['x-access-token']
        
        if not token:
            return jsonify({'message': 'Token is missing!'}), 401
        
        try:
            data = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
            current_user = data['sub']
        except exceptions:
            return jsonify({'message': 'Token is invalid!'}), 401
        
        return 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 days
    private 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 {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() {
        return new JwtAuthenticationFilter();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected 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 {

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected 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 {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private 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来处理刷新令牌的存储和撤销
    @Autowired
    private 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.mfbz.cn/a/585377.html

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

相关文章

基于python的舞蹈经验分享交流网站django+vue

1.运行环境&#xff1a;python3.7/python3.8。 2.IDE环境&#xff1a;pycharmmysql5.7/8.0; 3.数据库工具&#xff1a;Navicat11 4.硬件环境&#xff1a;windows11/10 8G内存以上 5.数据库&#xff1a;MySql 5.7/8.0版本&#xff1b; 运行成功后&#xff0c;在浏览器中输入&am…

什么牌子内衣洗衣机好用?五种高性价比单品一览

随着科技的进步和消费者对生活质量的要求越来越高&#xff0c;很多小家电被发明出来&#xff0c;其中讨论热度较高是内衣洗衣机。它不仅方便快捷&#xff0c;还能保持衣物清洁和卫生。不过现在市面上的内衣洗衣机品牌实在太多了&#xff0c;在选购的时候让人很犹豫&#xff0c;…

日本一站式软文发稿:开启你的日本市场之旅

在当今的业界里&#xff0c;软文发稿已经成为一种被广泛采用的营销策略。不同于硬广告的直接推销&#xff0c;软文发稿注重以讲故事&#xff0c;提供有价值的信息&#xff0c;借此影响和吸引读者&#xff0c;从而间接推广企业的产品和服务。 相对于其它地区&#xff0c;日本市…

单片机排队叫号系统Proteus仿真程序 有取号键和叫号键以及重复叫号键 有注释

目录 1、前言 ​ 2、程序 资料下载地址&#xff1a;单片机排队叫号系统Proteus仿真程序 有取号键和叫号键以及重复叫号键 有注释 1、前言 系统组成&#xff1a;STC89C52RCLcd1602蜂鸣器按键 具体介绍&#xff1a; Lcd1602排队叫号系统&#xff0c;有取号显示窗和叫号显示窗…

解决clickhouse 启动报错

解决clickhouse 启动报错 Error response from daemon: driver failed programming external connectivity on endpoint clickhouse-server (b42457434cebe7d8ad024d31e4fd28eae2139bb2b5046c283bea17ce4398d5b0): Error starting userland proxy: listen tcp4 0.0.0.0:8123: …

MySQL中怎么存放一条记录

2.2.1. MySQL中一行记录是怎么存储的&#xff1f; MySQL的数据存储在那个文件&#xff1f; 每创建一个 database&#xff08;数据库&#xff09;都会在 /var/lib/mysql/ 目录里面创建一个以 database 为名的目录&#xff0c;然后保存表结构和表数据的文件都会存放在这个目录里…

【软件工程与实践】(第四版)第7章习题答案详解

写在文章开头&#xff0c;感谢你的支持与关注&#xff01;小卓不羁 第7章 一、填空题二、选择题三、简答题四、实践题 一、填空题 &#xff08;1&#xff09;发现软件的错误 &#xff08;2&#xff09;白盒法 系统的模块功能规格说明 &#xff08;3&#xff09;功能 &#xf…

如何用揿针治疗慢性咽炎?

点击文末领取揿针的视频教程跟直播讲解 在日常生活中&#xff0c;慢性咽炎极为常见&#xff0c;不致命却很恼人。一旦发作&#xff0c;你的喉咙每天都会不舒服&#xff0c;总感觉有东西堵着&#xff0c;但是呢&#xff0c;咳又咳不出来&#xff0c;咽也咽不下去&#xff0c;你…

在一台交换机上配置VLAN

实验环境 实验拓扑图结构如图12.12所示&#xff0c;其中PC1和PC3属于VLAN 2&#xff0c;PC2属于 VLAN 3&#xff0c;PC1的IP地址为192.168.0.2/24&#xff0c;PC2的IP地址为192.168.1.2/24&#xff0c;PC3的 IP地址为192.168.0.3/24。 图12.12 需求描述 要求处于相同VLAN中的主…

JavaScript运算符及优先级全攻略,点击立刻升级你的编程水平!

在编程的世界里&#xff0c;运算符是构建逻辑、实现功能的重要工具。它能帮助我们完成各种复杂的计算和操作。 今天&#xff0c;我们就来深入探索JavaScript中运算符的奥秘&#xff0c;掌握它们的种类和优先级&#xff0c;让你的代码更加高效、简洁&#xff01; 一、什么是运…

C# Web控件与数据感应之 CheckBoxList 类

目录 关于数据感应 CheckBoxList 类 范例运行环境 数据源表设计 角色字典表 用户角色表 AutoValueDBList 方法 原理 设计 实现 调用示例 初始化数据 启动查询模式 使用保存模式 小结 关于数据感应 数据感应也即数据捆绑&#xff0c;是一种动态的&#xff0c;We…

【氮化镓】一种新型的p-GaN/p-AlGaN/AlGaN/GaN异质结场效应晶体管

文章由韩国首尔弘益大学电子与电气工程学院的Dong-Guk Kim等人撰写&#xff0c;题为“P-GaN/p-AlGaN/AlGaN/GaN heterojunction field-effect transistor with a threshold voltage of 6 V”&#xff0c;发表在IEEE Electron Device Letters上。文章提出了一种新型的p-GaN/p-Al…

HTTP:强缓存优化实践

强缓存&#xff1a;浏览器不会向服务器发送任何请求&#xff0c;直接从本地缓存中读取文件 强缓存是指浏览器在向服务器请求资源时&#xff0c;判断本地是否存在该资源的缓存&#xff0c;并判断是否过期。 如果本地缓存未过期&#xff0c;浏览器就直接使用本地缓存&#xff0c…

C#基础|了解对象在程序中的状态及垃圾回收机制

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 本节了解对象的生命周期及对象状态和垃圾回收机制&#xff0c;以下为学习笔记。 1、对象的生命周期 对象在内存中不断地被引用&#xff0c;被释放&#xff0c;形成了类似生命周期的过程。 2、对象在内存中的状态 对…

【2024新windows电脑部署测试环境系列】Jenkins部署 (上)

jenkins对我们测试来说挺重要的&#xff0c;持续集成cicd ,定时任务&#xff0c;远程控制&#xff0c;打包部署测试环境等等。虽然在一些公司&#xff0c;早已用上自研的这种综合控制平台&#xff0c;不过也至少9成以上的组织还是在用jenkins。 一个公司并不一定只有一个jenkin…

一文解决ArcGIS生成点和管段 含案例讲解

背景 在工作中&#xff0c;我们经常遇到要将坐标数据导入 GIS&#xff0c;生成点位&#xff0c;若是地理坐标系&#xff08;经纬度&#xff09;&#xff0c;那么直接用 arcgis或者QGIS 导入数据就行了&#xff0c;可实际中总会遇到各种问题&#xff1a; 坐标数据集为大地 200…

(三十二)第 5 章 数组和广义表(稀疏矩阵的十字链表存储表示实现)

1. 背景说明 2. 示例代码 1) errorRecord.h // 记录错误宏定义头文件#ifndef ERROR_RECORD_H #define ERROR_RECORD_H#include <stdio.h> #include <string.h> #include <stdint.h>// 从文件路径中提取文件名 #define FILE_NAME(X) strrchr(X, \\) ? strrch…

latex使用bib引用参考文献时,正文编号顺序乱序解决办法,两分钟搞定!

一、背景 用Latex写文章时&#xff0c;使用bib添加参考文献是一种最为简便的方式。但有的期刊模板&#xff0c;如机器人顶会IROS&#xff0c;会出现正文参考文献序号没按顺序排列的情况&#xff0c;如下图所示。按理说文献[4]应该是文献[2]&#xff0c;[2]应该是[3]&#xff0…

现代机器学习(ML)技术在医疗成像领域的新应用

现代机器学习(ML)技术在医疗成像领域的新应用主要包括以下几个方面: 一、自动病变检测 使用深度学习算法,尤其是卷积神经网络(CNN),自动识别和分类医学影像中的病变,如肿瘤、炎症等。自动病变检测是现代机器学习技术在医疗成像领域应用的一个重要方向。它主要通过以下…

spark实验求TOP值

实验1&#xff1a;求TOP值 已知存在两个文本文件&#xff0c;file1.txt和file2.txt&#xff0c;内容分别如下&#xff1a; file1.txt 1,1768,50,155 2,1218, 600,211 3,2239,788,242 4,3101,28,599 5,4899,290,129 6,3110,54,1201 7,4436,259,877 8,2369,7890,27 fil…
最新文章