使用Java构建高效的Web服务架构
使用Java构建高效的Web服务架构
随着互联网技术的飞速发展,Web服务在现代应用中扮演着至关重要的角色。尤其是在企业级应用中,如何构建一个高效、可扩展且易维护的Web服务架构,成为了开发者和架构师面临的一项重要挑战。Java作为一种成熟、稳定且功能强大的编程语言,凭借其丰富的生态系统和高性能的特性,成为构建高效Web服务架构的理想选择。
本文将详细探讨如何使用Java构建一个高效的Web服务架构,介绍相关技术栈、设计原则及优化策略,并提供一些具体的代码实例,帮助开发者更好地理解和实践。
1. 构建高效Web服务架构的核心技术栈
1.1 使用Spring Boot简化服务开发
Spring Boot是Java领域最流行的开发框架之一,它通过自动化配置、内嵌式Web服务器、简化的依赖管理等特性,极大地简化了Web服务的开发过程。Spring Boot允许开发者专注于业务逻辑,而无需过多关注框架的配置和管理。
示例:创建一个简单的Spring Boot Web服务
package com.example.demo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}@RestController
class HelloController {@GetMapping("/hello")public String sayHello() {return "Hello, World!";}
}
上述代码展示了如何使用Spring Boot快速创建一个简单的Web服务。@SpringBootApplication注解自动配置了Web服务的基础设施,而@RestController和@GetMapping则用于定义一个RESTful接口,能够处理HTTP GET请求。
1.2 使用Spring Cloud构建微服务架构
对于复杂的分布式系统,微服务架构是一种理想的设计模式。Spring Cloud提供了一整套基于Spring Boot的解决方案,帮助开发者构建和管理微服务系统。Spring Cloud包括服务注册与发现(Eureka)、配置管理(Spring Cloud Config)、断路器(Hystrix)等组件,能有效解决微服务中的服务治理、容错处理和配置管理等问题。
示例:使用Eureka进行服务注册与发现
package com.example.discoveryservice;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication
@EnableEurekaServer
public class DiscoveryServiceApplication {public static void main(String[] args) {SpringApplication.run(DiscoveryServiceApplication.class, args);}
}
在这个示例中,@EnableEurekaServer注解启用了Eureka服务注册与发现功能,允许其他服务将自身注册到该服务中心,从而实现服务间的自动发现与通信。
1.3 数据持久化与优化:Spring Data JPA
对于大多数Web服务来说,数据存储和访问是不可或缺的部分。Spring Data JPA是Spring的一个子项目,它简化了与数据库交互的复杂性,并提供了强大的功能来提高开发效率。它通过JPA(Java Persistence API)和Hibernate等持久化技术,帮助开发者方便地进行数据的增、删、改、查操作。
示例:使用Spring Data JPA进行数据持久化
package com.example.demo.repository;import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;public interface UserRepository extends JpaRepository<User, Long> {User findByUsername(String username);
}
package com.example.demo.entity;import javax.persistence.Entity;
import javax.persistence.Id;@Entity
public class User {@Idprivate Long id;private String username;private String password;// Getters and setters
}
在这个例子中,UserRepository是一个继承自JpaRepository的接口,通过Spring Data JPA,开发者无需编写SQL语句即可完成对User实体的数据库操作。
2. 高效Web服务架构的设计原则
2.1 分层架构设计
为了提高系统的可维护性和可扩展性,分层架构设计是构建高效Web服务的重要原则。通常,Web服务可以分为以下几个层次:
- 表示层(Controller层):负责接收客户端请求并将请求转发到业务逻辑层。
- 业务逻辑层(Service层):处理业务逻辑,调用数据访问层获取数据。
- 数据访问层(Repository层):与数据库进行交互,进行CRUD操作。
示例:分层架构的实现
// Controller层
@RestController
@RequestMapping("/users")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/{id}")public User getUserById(@PathVariable Long id) {return userService.getUserById(id);}
}
// Service层
@Service
public class UserService {@Autowiredprivate UserRepository userRepository;public User getUserById(Long id) {return userRepository.findById(id).orElseThrow(() -> new RuntimeException("User not found"));}
}
// Repository层
public interface UserRepository extends JpaRepository<User, Long> {
}
2.2 异步处理与响应式编程
在Web服务中,处理高并发和长时间运行的请求时,异步处理和响应式编程能大大提升系统的响应能力和吞吐量。Spring WebFlux是Spring提供的响应式编程框架,它基于非阻塞I/O模型,可以更好地应对高并发场景。
示例:使用Spring WebFlux进行异步请求处理
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;@RestController
public class AsyncController {@GetMapping("/async")public Mono<String> asyncResponse() {return Mono.just("This is an asynchronous response");}
}
在这个示例中,Mono是Spring WebFlux中表示单个异步结果的类,它允许开发者在不阻塞线程的情况下处理请求。通过这种方式,Web服务可以更高效地处理并发请求。
2.3 缓存优化
缓存是提高Web服务性能的常用手段,特别是在频繁查询相同数据的情况下。常见的缓存方案有Redis、EhCache等,它们可以极大减少数据库的压力,并提高响应速度。
示例:使用Spring Cache和Redis进行缓存
@Configuration
@EnableCaching
public class CacheConfig {@Beanpublic RedisCacheManager cacheManager(RedisConnectionFactory factory) {RedisCacheManager cacheManager = RedisCacheManager.builder(factory).build();return cacheManager;}
}
@Service
public class UserService {@Cacheable(value = "users", key = "#id")public User getUserById(Long id) {// Simulate a slow database queryreturn userRepository.findById(id).orElseThrow(() -> new RuntimeException("User not found"));}
}
在此示例中,@Cacheable注解表示该方法的结果将被缓存,下次调用时会直接从缓存中获取数据,避免了不必要的数据库查询。
3. 性能优化策略
3.1 使用负载均衡
当Web服务需要处理大量请求时,负载均衡是确保系统高可用性和可扩展性的重要手段。通过将请求分发到多个后端服务器,负载均衡能够平衡各个节点的负载,避免某个节点的过载。
常用的负载均衡工具有Nginx、HAProxy等,可以与Spring Cloud结合使用,实现微服务间的负载均衡。
3.2 监控与日志
监控和日志是确保Web服务稳定运行的重要手段。使用Spring Boot Actuator可以轻松地监控应用的健康状况、性能指标等。同时,结合日志管理工具如ELK(Elasticsearch, Logstash, Kibana)或者Prometheus、Grafana等工具,可以帮助开发者实时监控Web服务的运行状态,并快速定位问题。
4. 性能优化策略(续)
4.1 数据库优化
数据库是大多数Web服务的核心部分,尤其在处理大量数据时,如何高效地与数据库交互成为了影响Web服务性能的关键因素之一。以下是一些常见的数据库优化策略:
4.1.1 索引优化
为数据库表创建合适的索引可以显著提高查询性能。尤其在处理大量数据时,索引的使用能够减少扫描数据表的时间。需要根据查询条件的频繁程度和类型来优化索引。
例如,在一个用户表中,如果经常根据username字段查询用户,可以在username字段上创建索引:
CREATE INDEX idx_username ON users(username);
在Java中,我们使用Spring Data JPA时,可以通过@Query注解来执行自定义查询,并确保查询效率:
public interface UserRepository extends JpaRepository<User, Long> {@Query("SELECT u FROM User u WHERE u.username = :username")User findByUsername(@Param("username") String username);
}
4.1.2 使用分页查询
对于大量数据的查询,使用分页查询可以有效减少每次查询时需要加载的数据量,从而提高性能。Spring Data JPA提供了内置的分页功能,可以非常方便地实现分页查询。
Page<User> findByUsername(String username, Pageable pageable);
在使用时,开发者可以通过传入PageRequest对象来指定分页参数:
Page<User> users = userRepository.findByUsername("john_doe", PageRequest.of(0, 10));
4.2 使用异步任务与后台处理
在Web服务中,某些任务可能需要较长时间才能完成,例如大数据处理、邮件发送等。这些任务如果阻塞了请求线程,会影响用户体验。通过异步处理可以将这些任务移到后台执行,避免影响主流程。
4.2.1 使用Spring异步执行任务
Spring框架支持异步方法执行,通过使用@Async注解,开发者可以将耗时操作放到独立的线程中进行处理,从而不阻塞主请求线程。
首先,确保在配置类中启用异步支持:
@Configuration
@EnableAsync
public class AsyncConfig {
}
然后,可以在服务层使用@Async注解将方法标记为异步执行:
@Service
public class NotificationService {@Asyncpublic void sendEmailNotification(String email) {// 发送邮件的逻辑System.out.println("Sending email to " + email);}
}
在调用该方法时,Spring会自动在后台执行,返回的Future对象可以用于跟踪异步任务的完成情况。
4.2.2 使用消息队列
对于需要异步处理且无法即刻完成的任务,可以将任务放入消息队列中,由独立的消费者服务进行处理。常见的消息队列有RabbitMQ、Kafka等。这种方法适用于长时间运行的任务,能够更好地解耦系统中的各个组件。
例如,使用Spring Boot与RabbitMQ整合,首先配置连接工厂和队列:
@Configuration
public class RabbitConfig {@Beanpublic Queue queue() {return new Queue("taskQueue", false);}@Beanpublic TopicExchange exchange() {return new TopicExchange("taskExchange");}@Beanpublic Binding binding(Queue queue, TopicExchange exchange) {return BindingBuilder.bind(queue).to(exchange).with("task.routing.key");}
}
然后,在服务中发送消息到RabbitMQ队列:
@Autowired
private RabbitTemplate rabbitTemplate;public void sendTaskToQueue(String taskData) {rabbitTemplate.convertAndSend("taskExchange", "task.routing.key", taskData);
}
消费者服务从消息队列中接收任务并处理:
@RabbitListener(queues = "taskQueue")
public void handleTask(String taskData) {// 处理任务的逻辑System.out.println("Processing task: " + taskData);
}
这种异步消息处理的方式不仅能提高系统的并发处理能力,还能解耦Web服务与长时间任务的执行过程。
4.3 前端优化
Web服务的性能不仅仅依赖于后端的优化,前端的优化同样重要。通过减少前端页面的加载时间,减少HTTP请求次数,能够显著提升用户的体验。以下是几种常见的前端优化策略:
4.3.1 压缩资源文件
对于前端的静态资源(如CSS、JavaScript、图片等),可以通过压缩和优化减少文件的大小,从而加速资源的加载。Spring Boot本身支持通过spring.resources.static-locations配置来管理静态资源的路径,开发者可以通过Webpack或Gulp等工具对前端资源进行压缩和优化。
4.3.2 延迟加载
通过懒加载技术,可以将一些不需要立刻加载的资源推迟到用户实际需要时再加载。例如,图片、视频等较大的资源,可以等到用户滚动到页面的相应位置时再加载,减少初次加载的时间。
Spring Boot中,可以通过支持的@Async注解和JavaScript的异步加载机制配合来实现前端的延迟加载。
5. 高可用性与容错设计
在构建Web服务时,确保系统的高可用性和容错性是非常重要的。现代Web服务必须能够应对部分节点故障、网络中断等各种意外情况,确保系统持续稳定地运行。
5.1 服务熔断与降级
在微服务架构中,如果某个服务出现故障,如何确保整个系统的稳定运行是一个关键问题。熔断器模式(Circuit Breaker)能够帮助我们实现服务故障的快速响应和处理。Spring Cloud提供了Hystrix作为服务熔断的解决方案。通过配置Hystrix,当服务调用失败时,系统会立即启动熔断机制,避免请求进入失败状态的服务。
示例:Hystrix熔断器的使用
@HystrixCommand(fallbackMethod = "defaultFallback")
public String getUserInfo(String username) {// 模拟服务调用,可能会失败return restTemplate.getForObject("http://user-service/user/" + username, String.class);
}public String defaultFallback(String username) {return "User service is currently unavailable, please try again later.";
}
在这个例子中,@HystrixCommand注解指定了一个熔断方法defaultFallback,当getUserInfo方法失败时,Hystrix将触发熔断机制,并调用备用方法。
5.2 服务容错
在服务调用过程中,网络的波动、远程服务的不可用等都会影响系统的稳定性。除了熔断机制外,还需要进行服务容错设计。例如,服务可以采用超时重试、请求队列等技术,确保服务请求能够有效地处理,即使在出现某些网络问题时,也能够保证一定的服务质量。
Spring Retry提供了一种简洁的方式来进行方法重试。通过@Retryable注解,开发者可以轻松地为方法添加重试逻辑。
示例:使用Spring Retry进行服务重试
@Service
public class UserService {@Retryable(value = {TimeoutException.class}, maxAttempts = 3, backoff = @Backoff(delay = 2000))public String fetchUserData(String userId) {// 可能会因超时而失败的远程服务调用return restTemplate.getForObject("http://external-service/users/" + userId, String.class);}
}
通过@Retryable注解,fetchUserData方法将会在遇到TimeoutException时自动重试,最多重试三次,且每次重试之间间隔2秒。
6. 高并发处理与水平扩展
当Web服务面临高并发请求时,如何有效处理这些请求并保证系统的高效运行是一个重要的挑战。水平扩展和负载均衡是解决高并发问题的有效手段。水平扩展意味着通过增加更多的服务器来分担请求的负载,从而提高系统的处理能力。
6.1 水平扩展
在Web服务架构中,水平扩展通常涉及部署多个服务实例并使用负载均衡器将请求均匀地分发到各个实例。通过这种方式,可以显著提升系统的吞吐量,并确保系统在高并发下保持高可用性。
示例:使用Docker与Kubernetes进行服务扩展
通过Docker容器化应用,并使用Kubernetes进行容器编排,可以实现Web服务的水平扩展。
- Dockerfile示例:在应用目录下创建
Dockerfile文件,用于构建Web服务的Docker镜像。
FROM openjdk:11-jre-slim
COPY target/demo-0.0.1-SNAPSHOT.jar /usr/app/
WORKDIR /usr/app
ENTRYPOINT ["java", "-jar", "demo-0.0.1-SNAPSHOT.jar"]
- 构建Docker镜像:
docker build -t my-web-service .
- Kubernetes部署示例:通过Kubernetes部署多个服务实例,并通过服务发现与负载均衡进行请求分发。
apiVersion: apps/v1
kind: Deployment
metadata:name: web-service
spec:replicas: 3selector:matchLabels:app: web-servicetemplate:metadata:labels:app: web-servicespec:containers:- name: web-serviceimage: my-web-service:latestports:- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:name: web-service
spec:selector:app: web-serviceports:- port: 8080targetPort: 8080type: LoadBalancer
通过Kubernetes,我们可以轻松地扩展Web服务实例,并实现自动扩展、负载均衡和故障恢复等功能。
6.2 负载均衡
负载均衡是确保Web服务高可用性的另一个关键因素。负载均衡器可以分发请求到不同的Web服务实例,并根据实际情况进行流量调度,避免某个节点过载。
示例:使用Nginx进行负载均衡
假设有多个Web服务实例运行在不同的主机上,Nginx可以作为反向代理服务器,负责将请求转发到不同的实例。
http {upstream backend {server backend1.example.com;server backend2.example.com;server backend3.example.com;}server {listen 80;location / {proxy_pass http://backend;}}
}
Nginx会根据配置将请求轮询转发给backend1.example.com、backend2.example.com、backend3.example.com等后端服务实例,从而实现负载均衡。
6.3 异步处理与消息队列
在高并发环境下,某些请求可能需要较长的处理时间。如果这些请求同步处理,会导致服务响应变慢,从而影响系统性能。异步处理和消息队列是解决这一问题的常见方案。
例如,使用消息队列(如RabbitMQ、Kafka)将请求消息放入队列,由后台消费者异步处理。
示例:使用RabbitMQ进行异步任务处理
@Configuration
public class RabbitConfig {@Beanpublic Queue queue() {return new Queue("taskQueue", false);}@Beanpublic TopicExchange exchange() {return new TopicExchange("taskExchange");}@Beanpublic Binding binding(Queue queue, TopicExchange exchange) {return BindingBuilder.bind(queue).to(exchange).with("task.routing.key");}
}
在服务中,将需要异步处理的任务发送到RabbitMQ:
@Autowired
private RabbitTemplate rabbitTemplate;public void sendTaskToQueue(String taskData) {rabbitTemplate.convertAndSend("taskExchange", "task.routing.key", taskData);
}
消费者服务异步接收并处理任务:
@RabbitListener(queues = "taskQueue")
public void handleTask(String taskData) {// 异步处理任务的逻辑System.out.println("Processing task: " + taskData);
}
通过异步任务处理和消息队列的组合使用,可以有效避免高并发场景中的阻塞问题。
7. 安全性设计与防护
在构建高效的Web服务时,除了性能和可用性,安全性同样至关重要。随着网络攻击手段的不断升级,Web服务的安全性问题日益成为开发者需要重点关注的领域。为了保证Web服务的安全性,需要从身份验证、授权、数据加密等方面入手。
7.1 身份验证与授权
身份验证和授权是保证Web服务安全性的基础。常见的身份验证机制有基于用户名密码的验证、OAuth2认证等,而授权则是根据用户的身份决定其访问权限。
示例:使用Spring Security实现JWT认证
JWT(JSON Web Token)是一种常见的身份认证机制,它通过传递加密的token来验证用户的身份,避免了传统基于会话的认证方式存在的性能瓶颈。
- 添加Spring Security和JWT依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId>
</dependency>
- 创建JWT工具类:用于生成和解析JWT令牌。
public class JwtTokenUtil {private static final String SECRET_KEY = "mysecretkey";public static String generateToken(String username) {return Jwts.builder().setSubject(username).setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60)) // 1 hour expiry.signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();}public static String extractUsername(String token) {return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject();}public static boolean isTokenExpired(String token) {return extractExpirationDate(token).before(new Date());}private static Date extractExpirationDate(String token) {return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getExpiration();}
}
- 在Spring Security中配置JWT认证:通过自定义
AuthenticationManager来进行身份验证。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable().authorizeRequests().antMatchers("/login", "/register").permitAll().anyRequest().authenticated().and().addFilter(new JwtAuthenticationFilter(authenticationManager()));}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}
}
- 实现JWT过滤器:用来在请求中解析并验证JWT令牌。
public class JwtAuthenticationFilter extends OncePerRequestFilter {private final AuthenticationManager authenticationManager;public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {this.authenticationManager = authenticationManager;}@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {String token = extractTokenFromRequest(request);if (token != null && !JwtTokenUtil.isTokenExpired(token)) {String username = JwtTokenUtil.extractUsername(token);UsernamePasswordAuthenticationToken authenticationToken =new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>());SecurityContextHolder.getContext().setAuthentication(authenticationToken);}filterChain.doFilter(request, response);}private String extractTokenFromRequest(HttpServletRequest request) {String header = request.getHeader("Authorization");if (header != null && header.startsWith("Bearer ")) {return header.substring(7);}return null;}
}
通过JWT认证,Web服务能够在用户请求中安全地传递身份信息,从而保证服务的安全性。
7.2 数据加密
为了保护敏感数据,尤其是在传输过程中,需要使用加密技术来确保数据的安全性。常见的加密技术有TLS/SSL加密、AES加密等。
示例:启用HTTPS
为了保护传输过程中的数据不被窃听和篡改,可以启用HTTPS协议。在Spring Boot中,可以通过以下方式启用HTTPS:
- 生成SSL证书:
keytool -genkeypair -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650
- 配置Spring Boot使用SSL:
server.port=8443
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=yourpassword
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=tomcat
启用SSL后,所有传输的数据将被加密,确保通信的安全性。
7.3 防止常见安全攻击
Web服务可能面临各种安全攻击,例如跨站脚本攻击(XSS)、跨站请求伪造(CSRF)等。可以通过以下方式防止这些攻击:
- 使用Spring Security的CSRF防护功能,自动为每个请求生成并验证CSRF令牌。
- 使用输入验证和输出编码防止XSS攻击。
- 使用适当的HTTP头(如
X-Content-Type-Options,X-Frame-Options等)防止点击劫持和MIME类型嗅探攻击。
通过这些安全措施,可以有效提高Web服务的抗攻击能力,保护用户数据免受威胁。
总结
构建高效且安全的Web服务架构涉及多个方面的考虑,包括性能优化、高并发处理、容错设计、安全性等。我们探讨了如何通过合适的技术栈和架构设计来实现一个高效且稳定的Web服务,具体包括以下几个关键领域:
1. 性能优化
- 缓存机制:通过内存缓存和分布式缓存(如Redis)减少数据库查询,提高响应速度。
- 数据库优化:通过索引优化、分页查询等手段提升数据库查询效率。
- 异步处理与消息队列:将耗时操作异步处理,避免阻塞主请求线程,从而提高系统并发能力。
2. 高可用性与容错设计
- 服务熔断与降级:使用Hystrix等工具,防止系统因单个服务故障而崩溃,通过服务熔断与降级保证系统稳定性。
- 水平扩展与负载均衡:通过增加服务实例和负载均衡器(如Nginx)分担请求流量,提升系统吞吐量和容错能力。
- 重试与消息队列:通过重试机制和消息队列来处理高并发请求,保证系统的稳定性和高效性。
3. 安全性设计
- 身份验证与授权:通过JWT等认证机制,确保用户身份的安全,防止未经授权的访问。
- 数据加密:启用HTTPS协议,保证数据传输过程中的安全,防止敏感数据泄露。
- 防御常见攻击:通过CSRF防护、XSS防护等手段,避免Web应用面临的常见安全威胁。
4. 高并发与水平扩展
- Docker与Kubernetes:通过容器化和容器编排,轻松实现Web服务的水平扩展,提高系统的扩展性和灵活性。
- 消息队列与异步处理:通过消息队列(如RabbitMQ)和异步处理,缓解高并发场景下的压力,提高系统的吞吐量。
通过整合这些技术,开发者能够构建一个高效、可靠、安全且可扩展的Web服务架构,满足现代Web应用对性能、可用性和安全性的要求。这些技术不仅能够提升系统的稳定性和响应速度,还能帮助开发团队应对不断增长的流量和复杂的业务需求。

相关文章:
使用Java构建高效的Web服务架构
使用Java构建高效的Web服务架构 随着互联网技术的飞速发展,Web服务在现代应用中扮演着至关重要的角色。尤其是在企业级应用中,如何构建一个高效、可扩展且易维护的Web服务架构,成为了开发者和架构师面临的一项重要挑战。Java作为一种成熟、稳…...
《Python实战进阶》No 10:基于Flask案例的Web 安全性:防止 SQL 注入、XSS 和 CSRF 攻击
第10集:Web 安全性:防止 SQL 注入、XSS 和 CSRF 攻击 在现代 Web 开发中,安全性是至关重要的。无论是用户数据的保护,还是系统稳定性的维护,开发者都需要对常见的 Web 安全威胁有深刻的理解,并采取有效的防…...
蓝桥备赛(六)- C/C++输入输出
一、OJ题目输入情况汇总 OJ(online judge) 接下来会有例题 , 根据一下题目 , 对这些情况进行分析 1.1 单组测试用例 单在 --> 程序运行一次 , 就处理一组 练习一:计算 (ab)/c 的值 B2009 计算 (ab)/c …...
企微审批中MySQL字段TEXT类型被截断的排查与修复实践
在MySQL中,TEXT类型字段常用于存储较大的文本数据,但在一些应用场景中,当文本内容较大时,TEXT类型字段可能无法满足需求,导致数据截断或插入失败。为了避免这种问题,了解不同文本类型(如TEXT、M…...
[ISP] AE 自动曝光
相机通过不同曝光参数(档位快门时间 x 感光度 x 光圈大小)控制进光量来完成恰当的曝光。 自动曝光流程大概分为三部分: 1. 测光:点测光、中心测光、全局测光等;通过调整曝光档位使sensor曝光在合理的阈值内࿰…...
小程序画带圆角的圆形进度条
老的API <canvas id"{{canvasId}}" canvas-id"{{canvasId}}" style"opacity: 0;" class"canvas"/> startDraw() {const { canvasId } this.dataconst query this.createSelectorQuery()query.select(#${canvasId}).bounding…...
16. LangChain实战项目2——易速鲜花内部问答系统
需求简介 易束鲜花企业内部知识库如下: 本实战项目设计一个内部问答系统,基于这些内部知识,回答内部员工的提问。 在前面课程的基础上,需要安装的依赖包如下: pip install docx2txt pip install qdrant-client pip i…...
代码的解读——自用
代码来自:https://github.com/ChuHan89/WSSS-Tissue?tabreadme-ov-file 借助了一些人工智能 run_pipeline.sh 功能总结 该脚本用于执行一个 弱监督语义分割(WSSS) 的完整流程,包含三个阶段: Stage1:训…...
蓝桥杯试题:DFS回溯
一、题目要求 输入一个数组n,输出1到n的全排列 二、代码展示 import java.util.*;public class ikun {static List<List<Integer>> list new ArrayList<>();public static void main(String[] args) { Scanner sc new Scanner(System.in);…...
FPGA开发,使用Deepseek V3还是R1(8):FPGA的全流程(简略版)
以下都是Deepseek生成的答案 FPGA开发,使用Deepseek V3还是R1(1):应用场景 FPGA开发,使用Deepseek V3还是R1(2):V3和R1的区别 FPGA开发,使用Deepseek V3还是R1&#x…...
一个py文件搞定mysql查询+Json转换+表数据提取+根据数据条件生成excel文件+打包运行一条龙
import os import argparse import pymssql import json import pandas as pd from datetime import datetime from pandas.io.formats.excel import ExcelFormatter import openpyxl# 投注类型映射字典 BET_MAPPING {1: WIN, 2: PLA, 3: QIN, 4: QPL,5: DBL, 6: TCE, 7: QTT,…...
微服务学习(1):RabbitMQ的安装与简单应用
目录 RabbitMQ是什么 为什么要使用RabbitMQ RabbitMQ的安装 RabbitMQ架构及其对应概念 队列的主要作用 交换机的主要作用 RabbitMQ的应用 通过控制面板操作(实现收发消息) RabbitMQ是什么 RabbitMQ是一个开源的消息队列软件(消息代理…...
【RAG】Embeding 和 Rerank学习笔记
Q: 现在主流Embeding模型架构 在RAG(Retrieval-Augmented Generation)系统中,嵌入模型(Embedding Model) 是检索阶段的核心组件,负责将查询(Query)和文档(Document&#…...
【Delphi】如何解决使用webView2时主界面置顶,而导致网页选择文件对话框被覆盖问题
一、问题描述: 在Delphi 中使用WebView2控件,如果预先把主界面置顶(Self.FormStyle : fsStayOnTop;),此时,如果在Web页面中有使用(<input type"file" id"fileInput" acc…...
【量化金融自学笔记】--开篇.基本术语及学习路径建议
在当今这个信息爆炸的时代,金融领域正经历着一场前所未有的变革。传统的金融分析方法逐渐被更加科学、精准的量化技术所取代。量化金融,这个曾经高不可攀的领域,如今正逐渐走进大众的视野。它将数学、统计学、计算机科学与金融学深度融合&…...
iOS 使用消息转发机制实现多代理功能
在iOS开发中,我们有时候会用到多代理功能,比如我们列表的埋点事件,需要我们在列表的某个特定的时机进行埋点上报,我们当然可以用最常见的做法,就是设置代理实现代理方法,然后在对应的代理方法里面进行上报&…...
16.3 LangChain Runnable 协议精要:构建高效大模型应用的核心基石
LangChain Runnable 协议精要:构建高效大模型应用的核心基石 关键词:LCEL Runnable 协议、LangChain 链式开发、自定义组件集成、流式处理优化、生产级应用设计 1. Runnable 协议设计哲学与核心接口 1.1 协议定义与类结构 #mermaid-svg-PlmvpSDrEUrUGv2p {font-family:&quo…...
Starrocks入门(二)
1、背景:考虑到Starrocks入门这篇文章,安装的是3.0.1版本的SR,参考:Starrocks入门-CSDN博客 但是官网的文档,没有对应3.0.x版本的资料,却有3.2或者3.3或者3.4或者3.1或者2.5版本的资料,不要用较…...
【北京迅为】itop-3568 开发板openharmony鸿蒙烧写及测试-第1章 体验OpenHarmony—烧写镜像
瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工…...
Electron一小时快速上手
1. 什么是 Electron? Electron 是一个跨平台桌面应用开发框架,开发者可以使用 HTML、CSS、JavaScript 等 Web 技术来构建桌面应用程序。它的本质是结合了 Chromium 和 Node.js,现在广泛用于桌面应用程序开发。例如,以下桌面应用都使用了 El…...
算法004——盛最多水的容器
力扣——盛最多水的容器点击即可跳转 当我们选择1号线和8号线时,下标为 1 和 8 形成容器的容积的高度是由 较矮的决定的,即下标为 8 的位置; 而宽度则是 1到8 之间的距离,为 8-17,此时容器的容积为 7 * 7 49。 当我…...
Java Web-Filter
Filter 在 Java Web 开发中,Filter(过滤器)是 Servlet 规范中的一个重要组件,它可以对客户端与服务器之间的请求和响应进行预处理和后处理。以下从多个方面详细介绍 Java Web 中的 Filter: 一、概念和作用 概念&…...
LeetCode 热题100 438. 找到字符串中所有字母异位词
LeetCode 热题100 | 438. 找到字符串中所有字母异位词 大家好,今天我们来解决一道经典的算法题——找到字符串中所有字母异位词。这道题在 LeetCode 上被标记为中等难度,要求我们在字符串 s 中找到所有是 p 的异位词的子串,并返回这些子串的…...
DeepSeek-R1训练时采用的GRPO算法数学原理及算法过程浅析
先来简单看下PPO和GRPO的区别: PPO:通过奖励和一个“评判者”模型(critic 模型)评估每个行为的“好坏”(价值),然后小步调整策略,确保改进稳定。 GRPO:通过让模型自己生…...
Qt基于信号量QSemaphore实现的生产者消费者模型
在 Qt 中,信号量(QSemaphore)是一种用于控制对共享资源访问的同步工具。它允许一定数量的线程同时访问共享资源,适合用于生产者-消费者模型。 代码实现 #include <QCoreApplication> #include <QThread> #include &…...
七星棋牌 6 端 200 子游戏全开源修复版源码(乐豆 + 防沉迷 + 比赛场 + 控制)
七星棋牌源码 是一款运营级的棋牌产品,覆盖 湖南、湖北、山西、江苏、贵州 等 6 大省区,支持 安卓、iOS 双端,并且 全开源。这个版本是 修复优化后的二开版本,新增了 乐豆系统、比赛场模式、防沉迷机制、AI 智能控制 等功能&#…...
CSDN博客导出设置介绍
在CSDN编辑博客时,如果想导出保存到本地,可以选择导出为Markdown或者HTML格式。其中导出为HTML时有这几种选项:jekyll site,plain html,plain text,styled html,styled html with toc。分别是什…...
_ 为什么在python中可以当变量名
在 Python 中,_(下划线)是一个有效的变量名,这主要源于 Python 的命名规则和一些特殊的使用场景。以下是为什么 _ 可以作为变量名的原因和常见用途: --- ### 1. **Python 的命名规则** Python 允许使用字母ÿ…...
使用haproxy实现MySQL服务器负载均衡
一、环境准备 主机名IP地址备注openEuler-1192.168.121.11mysql-server-1openEuler-2192.168.121.12mysql-server-2openEuler-3192.168.121.13clientRocky-1192.168.121.51haproxy 二、mysql-server配置 [rootopenEuler-1 ~]# yum install -y mariadb-server [rootopenEuler…...
音视频-WAV格式
1. WAV格式说明: 2. 格式说明: chunkId:通常是 “RIFF” 四个字节,用于标识文件类型。(wav文件格式表示)chunkSize:表示整个文件除了chunkId和chunkSize这 8 个字节外的其余部分的大小。Forma…...
