学习目标
深入理解微服务架构设计,掌握云原生技术栈,学习系统设计方法,准备技术面试,了解新技术趋势,完成项目实战。
1. 微服务架构深入
1.1 服务注册与发现
Eureka服务注册中心:
java
// Eureka Server配置
@SpringBootApplication
@EnableEurekaServer
@Slf4j
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
// Eureka Server配置类
@Configuration
public class EurekaServerConfig {
@Bean
public EurekaInstanceConfigBean eurekaInstanceConfig() {
EurekaInstanceConfigBean config = new EurekaInstanceConfigBean();
config.setHostname("localhost");
config.setInstanceId("eureka-server");
config.setLeaseRenewalIntervalInSeconds(30);
config.setLeaseExpirationDurationInSeconds(90);
return config;
}
}
// Eureka Client配置
@SpringBootApplication
@EnableEurekaClient
@Slf4j
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
// Eureka Client配置类
@Configuration
@Slf4j
public class EurekaClientConfig {
@Value("${eureka.instance.hostname}")
private String hostname;
@Value("${server.port}")
private int port;
@Bean
public EurekaInstanceConfigBean eurekaInstanceConfig() {
EurekaInstanceConfigBean config = new EurekaInstanceConfigBean();
config.setHostname(hostname);
config.setInstanceId(hostname + ":" + port);
config.setLeaseRenewalIntervalInSeconds(30);
config.setLeaseExpirationDurationInSeconds(90);
// 健康检查配置
Map<String, String> metadataMap = new HashMap<>();
metadataMap.put("management.port", String.valueOf(port));
config.setMetadataMap(metadataMap);
return config;
}
}
// 服务发现客户端
@Service
@Slf4j
public class ServiceDiscoveryClient {
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
// 获取服务实例
public List<ServiceInstance> getServiceInstances(String serviceName) {
return discoveryClient.getInstances(serviceName);
}
// 负载均衡调用服务
public <T> T callService(String serviceName, String path, Class<T> responseType) {
List<ServiceInstance> instances = getServiceInstances(serviceName);
if (instances.isEmpty()) {
throw new RuntimeException("服务不可用: " + serviceName);
}
// 简单轮询负载均衡
ServiceInstance instance = instances.get(
new Random().nextInt(instances.size())
);
String url = "http://" + instance.getHost() + ":" + instance.getPort() + path;
return restTemplate.getForObject(url, responseType);
}
// 使用Ribbon负载均衡
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public <T> T callServiceWithRibbon(String serviceName, String path, Class<T> responseType) {
String url = "http://" + serviceName + path;
return restTemplate.getForObject(url, responseType);
}
}
1.2 配置中心
Spring Cloud Config配置中心:
java
// Config Server配置
@SpringBootApplication
@EnableConfigServer
@Slf4j
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
// Config Server配置类
@Configuration
public class ConfigServerConfig {
// Git仓库配置
@Bean
public GitRepository gitRepository() {
GitRepository repository = new GitRepository();
repository.setUri("https://github.com/example/config-repo.git");
repository.setSearchPaths("config");
return repository;
}
}
// Config Client配置
@SpringBootApplication
@EnableConfigClient
@RefreshScope
@Slf4j
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
// 动态配置服务
@Service
@Slf4j
public class DynamicConfigService {
@Value("${app.order.timeout:5000}")
private int orderTimeout;
@Value("${app.order.retry-count:3}")
private int retryCount;
@Value("${app.feature.enable-new-payment:false}")
private boolean enableNewPayment;
// 获取配置值
public int getOrderTimeout() {
return orderTimeout;
}
public int getRetryCount() {
return retryCount;
}
public boolean isEnableNewPayment() {
return enableNewPayment;
}
// 配置变更监听
@EventListener
public void handleConfigChange(EnvironmentChangeEvent event) {
log.info("配置变更: {}", event.getKeys());
// 处理配置变更逻辑
}
}
// Nacos配置中心(替代方案)
@Configuration
@Slf4j
public class NacosConfig {
@NacosValue(value = "${app.order.timeout:5000}", autoRefreshed = true)
private int orderTimeout;
@NacosValue(value = "${app.order.retry-count:3}", autoRefreshed = true)
private int retryCount;
// 监听配置变更
@NacosConfigListener(dataId = "order-service", groupId = "DEFAULT_GROUP")
public void onConfigChange(String newConfig) {
log.info("配置变更: {}", newConfig);
// 解析并应用新配置
}
}
1.3 API网关
Spring Cloud Gateway:
java
// Gateway配置
@SpringBootApplication
@Slf4j
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
// Gateway路由配置
@Configuration
@Slf4j
public class GatewayConfig {
// 路由配置
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
// 订单服务路由
.route("order-service", r -> r
.path("/api/orders/**")
.filters(f -> f
.stripPrefix(1)
.addRequestHeader("X-Gateway", "Spring-Cloud-Gateway")
.retry(config -> config
.setRetries(3)
.setStatuses(HttpStatus.INTERNAL_SERVER_ERROR)
.setMethods(HttpMethod.GET)
)
)
.uri("lb://order-service")
)
// 用户服务路由
.route("user-service", r -> r
.path("/api/users/**")
.filters(f -> f
.stripPrefix(1)
.circuitBreaker(config -> config
.setName("user-service-circuit")
.setFallbackUri("forward:/fallback/user")
)
)
.uri("lb://user-service")
)
// 限流路由
.route("rate-limit-route", r -> r
.path("/api/public/**")
.filters(f -> f
.requestRateLimiter(config -> config
.setRateLimiter(redisRateLimiter())
.setKeyResolver(ipKeyResolver())
)
)
.uri("lb://public-service")
)
.build();
}
// Redis限流器
@Bean
public RedisRateLimiter redisRateLimiter() {
return new RedisRateLimiter(10, 20); // 每秒10个请求,突发20个
}
// 限流Key解析器(按IP限流)
@Bean
public KeyResolver ipKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()
);
}
// 全局过滤器
@Bean
public GlobalFilter customGlobalFilter() {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
log.info("请求路径: {}", request.getURI().getPath());
// 添加请求头
ServerHttpRequest modifiedRequest = request.mutate()
.header("X-Request-Time", String.valueOf(System.currentTimeMillis()))
.build();
return chain.filter(exchange.mutate().request(modifiedRequest).build());
};
}
// 自定义过滤器
@Component
@Slf4j
public static class AuthFilter implements GatewayFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String token = request.getHeaders().getFirst("Authorization");
if (token == null || !isValidToken(token)) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
return chain.filter(exchange);
}
private boolean isValidToken(String token) {
// Token验证逻辑
return token.startsWith("Bearer ");
}
@Override
public int getOrder() {
return -100;
}
}
}
// 降级处理
@RestController
@Slf4j
public class FallbackController {
@RequestMapping("/fallback/user")
public ResponseEntity<Map<String, Object>> userFallback() {
Map<String, Object> result = new HashMap<>();
result.put("code", 500);
result.put("message", "用户服务暂时不可用,请稍后重试");
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(result);
}
}
1.4 服务调用
OpenFeign服务调用:
java
// Feign客户端接口
@FeignClient(name = "user-service", fallback = UserServiceFallback.class)
public interface UserServiceClient {
@GetMapping("/api/users/{id}")
UserDTO getUserById(@PathVariable("id") Long id);
@PostMapping("/api/users")
UserDTO createUser(@RequestBody CreateUserRequest request);
@GetMapping("/api/users")
List<UserDTO> getUsers(@RequestParam("ids") List<Long> ids);
}
// Feign降级处理
@Component
@Slf4j
public class UserServiceFallback implements UserServiceClient {
@Override
public UserDTO getUserById(Long id) {
log.warn("用户服务降级,返回默认用户: {}", id);
UserDTO user = new UserDTO();
user.setId(id);
user.setName("默认用户");
return user;
}
@Override
public UserDTO createUser(CreateUserRequest request) {
log.warn("用户服务降级,创建用户失败");
throw new RuntimeException("用户服务不可用");
}
@Override
public List<UserDTO> getUsers(List<Long> ids) {
log.warn("用户服务降级,返回空列表");
return new ArrayList<>();
}
}
// Feign配置
@Configuration
@Slf4j
public class FeignConfig {
// 请求拦截器
@Bean
public RequestInterceptor requestInterceptor() {
return requestTemplate -> {
// 添加请求头
requestTemplate.header("X-Request-Id", UUID.randomUUID().toString());
requestTemplate.header("X-Service-Name", "order-service");
};
}
// 日志配置
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
// 错误解码器
@Bean
public ErrorDecoder errorDecoder() {
return new ErrorDecoder() {
@Override
public Exception decode(String methodKey, Response response) {
if (response.status() == 404) {
return new ResourceNotFoundException("资源未找到");
} else if (response.status() >= 500) {
return new ServiceException("服务异常");
}
return new RuntimeException("未知错误");
}
};
}
// 重试配置
@Bean
public Retryer retryer() {
return new Retryer.Default(100, 1000, 3);
}
}
// 使用Feign客户端
@Service
@Slf4j
public class OrderService {
@Autowired
private UserServiceClient userServiceClient;
public OrderDTO createOrder(CreateOrderRequest request) {
// 调用用户服务
UserDTO user = userServiceClient.getUserById(request.getUserId());
if (user == null) {
throw new RuntimeException("用户不存在");
}
// 创建订单逻辑
OrderDTO order = new OrderDTO();
order.setUserId(user.getId());
order.setUserName(user.getName());
// ...
return order;
}
}
2. 云原生技术
2.1 Docker容器化
Dockerfile编写:
dockerfile
# 多阶段构建
# 第一阶段:构建应用
FROM maven:3.8.4-openjdk-17 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests
# 第二阶段:运行应用
FROM openjdk:17-jre-slim
WORKDIR /app
# 创建非root用户
RUN groupadd -r appuser && useradd -r -g appuser appuser
# 复制构建产物
COPY --from=builder /app/target/*.jar app.jar
# 设置文件权限
RUN chown -R appuser:appuser /app
# 切换到非root用户
USER appuser
# 暴露端口
EXPOSE 8080
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
CMD curl -f http://localhost:8080/actuator/health || exit 1
# 启动应用
ENTRYPOINT ["java", "-jar", "app.jar"]
Docker Compose配置:
yaml
version: '3.8'
services:
# 订单服务
order-service:
build:
context: ./order-service
dockerfile: Dockerfile
container_name: order-service
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=docker
- EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://eureka:8761/eureka/
depends_on:
- mysql
- redis
networks:
- microservices-network
restart: unless-stopped
# 用户服务
user-service:
build:
context: ./user-service
dockerfile: Dockerfile
container_name: user-service
ports:
- "8081:8080"
environment:
- SPRING_PROFILES_ACTIVE=docker
- EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://eureka:8761/eureka/
depends_on:
- mysql
networks:
- microservices-network
restart: unless-stopped
# Eureka服务注册中心
eureka:
image: springcloud/eureka
container_name: eureka-server
ports:
- "8761:8761"
networks:
- microservices-network
restart: unless-stopped
# MySQL数据库
mysql:
image: mysql:8.0
container_name: mysql
environment:
- MYSQL_ROOT_PASSWORD=root123
- MYSQL_DATABASE=order_db
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
networks:
- microservices-network
restart: unless-stopped
# Redis缓存
redis:
image: redis:7-alpine
container_name: redis
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks:
- microservices-network
restart: unless-stopped
volumes:
mysql-data:
redis-data:
networks:
microservices-network:
driver: bridge
Docker操作服务:
java
// Docker操作服务
@Service
@Slf4j
public class DockerService {
// 构建Docker镜像
public void buildImage(String dockerfilePath, String imageName, String tag) {
try {
ProcessBuilder processBuilder = new ProcessBuilder(
"docker", "build",
"-f", dockerfilePath,
"-t", imageName + ":" + tag,
"."
);
Process process = processBuilder.start();
int exitCode = process.waitFor();
if (exitCode == 0) {
log.info("Docker镜像构建成功: {}:{}", imageName, tag);
} else {
log.error("Docker镜像构建失败,退出码: {}", exitCode);
}
} catch (Exception e) {
log.error("构建Docker镜像异常", e);
}
}
// 运行Docker容器
public void runContainer(String imageName, String containerName,
Map<String, String> envVars, int port) {
try {
List<String> command = new ArrayList<>();
command.add("docker");
command.add("run");
command.add("-d");
command.add("--name");
command.add(containerName);
command.add("-p");
command.add(port + ":8080");
// 添加环境变量
for (Map.Entry<String, String> entry : envVars.entrySet()) {
command.add("-e");
command.add(entry.getKey() + "=" + entry.getValue());
}
command.add(imageName);
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();
int exitCode = process.waitFor();
if (exitCode == 0) {
log.info("Docker容器启动成功: {}", containerName);
} else {
log.error("Docker容器启动失败,退出码: {}", exitCode);
}
} catch (Exception e) {
log.error("启动Docker容器异常", e);
}
}
}
2.2 Kubernetes部署
Kubernetes部署配置:
yaml
# Deployment配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
labels:
app: order-service
spec:
replicas: 3
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service
image: order-service:latest
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "k8s"
- name: EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE
value: "http://eureka-service:8761/eureka/"
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
---
# Service配置
apiVersion: v1
kind: Service
metadata:
name: order-service
spec:
selector:
app: order-service
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
---
# Ingress配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: order-service-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: api.example.com
http:
paths:
- path: /api/orders
pathType: Prefix
backend:
service:
name: order-service
port:
number: 80
---
# ConfigMap配置
apiVersion: v1
kind: ConfigMap
metadata:
name: order-service-config
data:
application.yml: |
spring:
datasource:
url: jdbc:mysql://mysql-service:3306/order_db
redis:
host: redis-service
port: 6379
---
# Secret配置
apiVersion: v1
kind: Secret
metadata:
name: order-service-secret
type: Opaque
data:
db-password: cm9vdDEyMw== # base64编码的密码
Kubernetes操作服务:
java
// Kubernetes操作服务
@Service
@Slf4j
public class KubernetesService {
// 创建Deployment
public void createDeployment(String name, String image, int replicas) {
try {
ProcessBuilder processBuilder = new ProcessBuilder(
"kubectl", "create", "deployment",
name,
"--image=" + image,
"--replicas=" + replicas
);
Process process = processBuilder.start();
int exitCode = process.waitFor();
if (exitCode == 0) {
log.info("Kubernetes Deployment创建成功: {}", name);
} else {
log.error("Kubernetes Deployment创建失败,退出码: {}", exitCode);
}
} catch (Exception e) {
log.error("创建Kubernetes Deployment异常", e);
}
}
// 扩缩容
public void scaleDeployment(String name, int replicas) {
try {
ProcessBuilder processBuilder = new ProcessBuilder(
"kubectl", "scale", "deployment",
name,
"--replicas=" + replicas
);
Process process = processBuilder.start();
int exitCode = process.waitFor();
if (exitCode == 0) {
log.info("Kubernetes Deployment扩缩容成功: {} -> {}", name, replicas);
} else {
log.error("Kubernetes Deployment扩缩容失败,退出码: {}", exitCode);
}
} catch (Exception e) {
log.error("Kubernetes Deployment扩缩容异常", e);
}
}
// 滚动更新
public void rollingUpdate(String name, String newImage) {
try {
ProcessBuilder processBuilder = new ProcessBuilder(
"kubectl", "set", "image",
"deployment/" + name,
name + "=" + newImage
);
Process process = processBuilder.start();
int exitCode = process.waitFor();
if (exitCode == 0) {
log.info("Kubernetes滚动更新成功: {} -> {}", name, newImage);
} else {
log.error("Kubernetes滚动更新失败,退出码: {}", exitCode);
}
} catch (Exception e) {
log.error("Kubernetes滚动更新异常", e);
}
}
}
2.3 Service Mesh
Istio Service Mesh配置:
yaml
# VirtualService配置
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: order-service
spec:
hosts:
- order-service
http:
- match:
- headers:
version:
exact: v2
route:
- destination:
host: order-service
subset: v2
weight: 100
- route:
- destination:
host: order-service
subset: v1
weight: 90
- destination:
host: order-service
subset: v2
weight: 10
---
# DestinationRule配置
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: order-service
spec:
host: order-service
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
connectionPool:
tcp:
maxConnections: 100
http:
http1MaxPendingRequests: 10
http2MaxRequests: 100
maxRequestsPerConnection: 2
circuitBreaker:
consecutiveErrors: 5
interval: 30s
baseEjectionTime: 30s
maxEjectionPercent: 50
minHealthPercent: 50
---
# Gateway配置
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: order-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- api.example.com
3. 系统设计实战
3.1 高并发系统设计
高并发系统架构:
java
// 限流服务
@Service
@Slf4j
public class RateLimitService {
// 令牌桶限流
private final RateLimiter rateLimiter = RateLimiter.create(100.0); // 每秒100个请求
public boolean tryAcquire() {
return rateLimiter.tryAcquire();
}
// 滑动窗口限流
private final Map<String, List<Long>> requestWindows = new ConcurrentHashMap<>();
private static final int WINDOW_SIZE = 60; // 60秒窗口
private static final int MAX_REQUESTS = 100; // 最大100个请求
public boolean isAllowed(String key) {
long currentTime = System.currentTimeMillis() / 1000;
List<Long> window = requestWindows.computeIfAbsent(key, k -> new ArrayList<>());
// 移除过期请求
window.removeIf(time -> time < currentTime - WINDOW_SIZE);
if (window.size() >= MAX_REQUESTS) {
return false;
}
window.add(currentTime);
return true;
}
}
// 缓存服务
@Service
@Slf4j
public class CacheService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// 多级缓存
private final Cache<String, Object> localCache = Caffeine.newBuilder()
.maximumSize(10000)
.expireAfterWrite(5, TimeUnit.MINUTES)
.build();
public <T> T get(String key, Class<T> type, Supplier<T> dataLoader) {
// 一级缓存:本地缓存
T value = (T) localCache.getIfPresent(key);
if (value != null) {
return value;
}
// 二级缓存:Redis
value = (T) redisTemplate.opsForValue().get(key);
if (value != null) {
localCache.put(key, value);
return value;
}
// 三级缓存:数据库
value = dataLoader.get();
if (value != null) {
redisTemplate.opsForValue().set(key, value, 1, TimeUnit.HOURS);
localCache.put(key, value);
}
return value;
}
}
// 异步处理服务
@Service
@Slf4j
public class AsyncProcessService {
@Async("taskExecutor")
public CompletableFuture<Void> processAsync(String data) {
// 异步处理逻辑
log.info("异步处理: {}", data);
return CompletableFuture.completedFuture(null);
}
// 线程池配置
@Bean(name = "taskExecutor")
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(200);
executor.setThreadNamePrefix("async-task-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
3.2 分布式系统设计
分布式系统架构:
java
// 分布式任务调度
@Service
@Slf4j
public class DistributedTaskScheduler {
@Autowired
private RedisTemplate<String, String> redisTemplate;
// 分布式锁实现任务调度
public void scheduleTask(String taskId, Runnable task) {
String lockKey = "task:lock:" + taskId;
String lockValue = UUID.randomUUID().toString();
try {
if (tryLock(lockKey, lockValue, 30)) {
// 检查任务是否已执行
String executedKey = "task:executed:" + taskId;
if (redisTemplate.hasKey(executedKey)) {
log.info("任务已执行: {}", taskId);
return;
}
// 执行任务
task.run();
// 标记任务已执行
redisTemplate.opsForValue().set(executedKey, "1", 1, TimeUnit.HOURS);
}
} finally {
releaseLock(lockKey, lockValue);
}
}
private boolean tryLock(String lockKey, String lockValue, long expireTime) {
Boolean result = redisTemplate.opsForValue()
.setIfAbsent(lockKey, lockValue, expireTime, TimeUnit.SECONDS);
return Boolean.TRUE.equals(result);
}
private void releaseLock(String lockKey, String lockValue) {
String luaScript =
"if redis.call('get', KEYS[1]) == ARGV[1] then " +
" return redis.call('del', KEYS[1]) " +
"else return 0 end";
DefaultRedisScript<Long> script = new DefaultRedisScript<>();
script.setScriptText(luaScript);
script.setResultType(Long.class);
redisTemplate.execute(script, Collections.singletonList(lockKey), lockValue);
}
}
4. 面试准备
4.1 常见面试题
Java基础面试题:
java
// 1. 单例模式实现
public class Singleton {
// 双重检查锁定
private volatile static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
// 静态内部类实现
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance2() {
return SingletonHolder.INSTANCE;
}
}
// 2. 线程安全的单例
public enum SingletonEnum {
INSTANCE;
public void doSomething() {
// 业务逻辑
}
}
// 3. 生产者消费者模式
public class ProducerConsumer {
private final BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);
class Producer implements Runnable {
@Override
public void run() {
try {
for (int i = 0; i < 100; i++) {
queue.put(i);
System.out.println("生产: " + i);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
class Consumer implements Runnable {
@Override
public void run() {
try {
while (true) {
Integer value = queue.take();
System.out.println("消费: " + value);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
4.2 算法题
常见算法实现:
java
// 快速排序
public class QuickSort {
public void sort(int[] arr, int low, int high) {
if (low < high) {
int pivot = partition(arr, low, high);
sort(arr, low, pivot - 1);
sort(arr, pivot + 1, high);
}
}
private int partition(int[] arr, int low, int high) {
int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (arr[j] < pivot) {
i++;
swap(arr, i, j);
}
}
swap(arr, i + 1, high);
return i + 1;
}
private void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// 二分查找
public class BinarySearch {
public int search(int[] arr, int target) {
int left = 0, right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
}
// LRU缓存实现
public class LRUCache {
private final int capacity;
private final Map<Integer, Node> cache;
private final Node head;
private final Node tail;
public LRUCache(int capacity) {
this.capacity = capacity;
this.cache = new HashMap<>();
this.head = new Node(0, 0);
this.tail = new Node(0, 0);
head.next = tail;
tail.prev = head;
}
public int get(int key) {
Node node = cache.get(key);
if (node == null) {
return -1;
}
moveToHead(node);
return node.value;
}
public void put(int key, int value) {
Node node = cache.get(key);
if (node == null) {
Node newNode = new Node(key, value);
cache.put(key, newNode);
addToHead(newNode);
if (cache.size() > capacity) {
Node tail = removeTail();
cache.remove(tail.key);
}
} else {
node.value = value;
moveToHead(node);
}
}
private void addToHead(Node node) {
node.prev = head;
node.next = head.next;
head.next.prev = node;
head.next = node;
}
private void removeNode(Node node) {
node.prev.next = node.next;
node.next.prev = node.prev;
}
private void moveToHead(Node node) {
removeNode(node);
addToHead(node);
}
private Node removeTail() {
Node lastNode = tail.prev;
removeNode(lastNode);
return lastNode;
}
static class Node {
int key;
int value;
Node prev;
Node next;
Node(int key, int value) {
this.key = key;
this.value = value;
}
}
}
5. 新技术趋势
5.1 响应式编程
Reactor响应式编程:
java
// 响应式服务
@Service
@Slf4j
public class ReactiveService {
// 创建Flux
public Flux<String> getDataStream() {
return Flux.range(1, 10)
.map(i -> "数据" + i)
.delayElements(Duration.ofMillis(100))
.doOnNext(data -> log.info("处理数据: {}", data));
}
// 创建Mono
public Mono<String> getSingleData() {
return Mono.just("单个数据")
.delayElement(Duration.ofMillis(100))
.doOnNext(data -> log.info("处理数据: {}", data));
}
// 组合多个流
public Flux<String> combineStreams() {
Flux<String> stream1 = Flux.just("A", "B", "C");
Flux<String> stream2 = Flux.just("1", "2", "3");
return Flux.zip(stream1, stream2, (s1, s2) -> s1 + s2);
}
// 错误处理
public Flux<String> handleError() {
return Flux.range(1, 10)
.map(i -> {
if (i == 5) {
throw new RuntimeException("错误");
}
return "数据" + i;
})
.onErrorResume(error -> {
log.error("处理错误", error);
return Flux.just("错误恢复数据");
});
}
}
// WebFlux控制器
@RestController
@Slf4j
public class ReactiveController {
@Autowired
private ReactiveService reactiveService;
@GetMapping("/api/data/stream")
public Flux<String> getDataStream() {
return reactiveService.getDataStream();
}
@GetMapping("/api/data/single")
public Mono<String> getSingleData() {
return reactiveService.getSingleData();
}
}
5.2 虚拟线程(Java 19+)
虚拟线程使用:
java
// 虚拟线程服务
@Service
@Slf4j
public class VirtualThreadService {
// 使用虚拟线程
public void processWithVirtualThread() {
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 10000; i++) {
final int taskId = i;
executor.submit(() -> {
log.info("虚拟线程执行任务: {}", taskId);
// 执行任务
});
}
}
}
// 虚拟线程与CompletableFuture结合
public CompletableFuture<String> processAsync() {
return CompletableFuture.supplyAsync(() -> {
// 业务逻辑
return "处理结果";
}, Executors.newVirtualThreadPerTaskExecutor());
}
}