当前位置: 首页 > article >正文

《软件工程》第 12 章 - 软件测试

   软件测试是确保软件质量的关键环节,它通过执行程序来发现错误,验证软件是否满足需求。本章将依据目录,结合 Java 代码示例、可视化图表,深入讲解软件测试的概念、过程、方法及实践。

12.1 软件测试的概念

12.1.1 软件测试的任务

软件测试的主要任务是:

  1. 发现错误:通过执行程序,找出代码中的缺陷和逻辑错误
  2. 验证功能:确保软件满足用户需求和规格说明。
  3. 评估质量:对软件的可靠性、性能等质量属性进行评估。

12.1.2 测试阶段的信息流程

测试阶段的信息流程:

展示测试过程中的信息流转。

12.1.3 测试用例及其设计

   测试用例是为测试而设计的一组输入和预期输出,用于验证软件的特定功能。例如,测试一个简单的加法函数的测试用例:

public class Calculator {public int add(int a, int b) {return a + b;}
}// 对应的测试用例(使用JUnit框架)
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;public class CalculatorTest {@Testpublic void testAddPositiveNumbers() {Calculator calculator = new Calculator();int result = calculator.add(3, 5);assertEquals(8, result); // 预期结果为8}@Testpublic void testAddNegativeNumbers() {Calculator calculator = new Calculator();int result = calculator.add(-3, -5);assertEquals(-8, result); // 预期结果为-8}
}

12.1.4 软件测试的原则

软件测试应遵循以下原则:

  1. 尽早测试:测试应从软件开发的早期阶段开始,如需求分析和设计阶段。
  2. 全面测试覆盖所有可能的输入和场景,包括边界条件和异常情况
  3. 避免自测:开发人员应避免测试自己编写的代码,减少主观因素影响。
  4. 记录测试结果:详细记录测试过程和结果,便于追踪和分析。

12.2 软件测试的过程模型

   软件测试的过程模型通常与软件开发过程模型对应,常见的有 V 模型、W 模型等。以 V 模型为例:

展示 V 模型中测试阶段与开发阶段的对应关系。

12.3 软件测试方法

12.3.1 白盒测试

白盒测试基于代码的内部结构和逻辑,主要技术包括:

  • 语句覆盖:确保每个语句至少执行一次。
  • 判定覆盖:确保每个判定的真假分支至少执行一次。
  • 条件覆盖:确保每个判定中的每个条件的可能取值至少执行一次。

示例代码及测试用例:

public class ControlFlow {public boolean checkNumber(int num) {if (num > 10 && num % 2 == 0) {return true;} else {return false;}}
}// 白盒测试用例
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;public class ControlFlowTest {@Testpublic void testCheckNumberTrue() {ControlFlow cf = new ControlFlow();assertTrue(cf.checkNumber(12)); // 覆盖true分支}@Testpublic void testCheckNumberFalse1() {ControlFlow cf = new ControlFlow();assertFalse(cf.checkNumber(5)); // 覆盖false分支(num <= 10)}@Testpublic void testCheckNumberFalse2() {ControlFlow cf = new ControlFlow();assertFalse(cf.checkNumber(11)); // 覆盖false分支(num为奇数)}
}

12.3.2 黑盒测试

   黑盒测试基于软件的外部功能和需求,不考虑内部实现。主要技术包括:

  • 等价类划分:将输入域划分为若干等价类,从每个等价类中选取代表性值作为测试用例。
  • 边界值分析:选择输入域的边界值作为测试用例,如最小值、最大值、刚好超过边界的值。
  • 错误推测法:基于经验和直觉推测可能的错误,设计针对性的测试用例。

以三角形分类函数为例:

public class TriangleClassifier {public String classify(int a, int b, int c) {// 检查是否构成三角形if (a <= 0 || b <= 0 || c <= 0 || a + b <= c || a + c <= b || b + c <= a) {return "非三角形";}// 检查等边三角形if (a == b && b == c) {return "等边三角形";}// 检查等腰三角形if (a == b || a == c || b == c) {return "等腰三角形";}// 普通三角形return "普通三角形";}
}// 黑盒测试用例(等价类划分和边界值分析)
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;public class TriangleClassifierTest {@Testpublic void testEquilateralTriangle() {TriangleClassifier tc = new TriangleClassifier();assertEquals("等边三角形", tc.classify(3, 3, 3));}@Testpublic void testIsoscelesTriangle() {TriangleClassifier tc = new TriangleClassifier();assertEquals("等腰三角形", tc.classify(3, 3, 4));}@Testpublic void testScaleneTriangle() {TriangleClassifier tc = new TriangleClassifier();assertEquals("普通三角形", tc.classify(3, 4, 5));}@Testpublic void testNotTriangle() {TriangleClassifier tc = new TriangleClassifier();assertEquals("非三角形", tc.classify(1, 2, 3));}@Testpublic void testBoundaryValues() {TriangleClassifier tc = new TriangleClassifier();assertEquals("非三角形", tc.classify(0, 3, 4)); // 边界值0assertEquals("等腰三角形", tc.classify(2, 2, 4)); // 边界值a+b=c}
}

12.4 软件测试活动及实施策略

12.4.1 单元测试

   单元测试是对软件中的最小可测试单元(如方法、类)进行测试。例如,测试一个栈类的基本操作:

import java.util.EmptyStackException;public class Stack {private int[] array;private int top;private int capacity;public Stack(int capacity) {this.capacity = capacity;this.array = new int[capacity];this.top = -1;}public void push(int item) {if (top == capacity - 1) {throw new StackOverflowError("栈已满");}array[++top] = item;}public int pop() {if (isEmpty()) {throw new EmptyStackException();}return array[top--];}public int peek() {if (isEmpty()) {throw new EmptyStackException();}return array[top];}public boolean isEmpty() {return top == -1;}
}// 单元测试用例
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;public class StackTest {private Stack stack;@BeforeEachpublic void setUp() {stack = new Stack(5);}@Testpublic void testPushAndPop() {stack.push(10);stack.push(20);assertEquals(20, stack.pop());assertEquals(10, stack.pop());}@Testpublic void testPeek() {stack.push(10);assertEquals(10, stack.peek());assertEquals(10, stack.peek()); // 多次peek不应改变栈}@Testpublic void testEmptyStack() {assertTrue(stack.isEmpty());assertThrows(EmptyStackException.class, () -> stack.pop());assertThrows(EmptyStackException.class, () -> stack.peek());}@Testpublic void testStackOverflow() {for (int i = 0; i < 5; i++) {stack.push(i);}assertThrows(StackOverflowError.class, () -> stack.push(5));}
}

12.4.2 集成测试

   集成测试是将多个单元组合成更大的模块进行测试,验证模块间的交互。例如,测试一个简单的订单处理系统:

// 订单类
public class Order {private String orderId;private double totalAmount;private boolean paid;public Order(String orderId, double totalAmount) {this.orderId = orderId;this.totalAmount = totalAmount;this.paid = false;}public String getOrderId() {return orderId;}public double getTotalAmount() {return totalAmount;}public boolean isPaid() {return paid;}public void setPaid(boolean paid) {this.paid = paid;}
}// 支付服务接口
public interface PaymentService {boolean processPayment(double amount);
}// 订单处理服务
public class OrderService {private PaymentService paymentService;public OrderService(PaymentService paymentService) {this.paymentService = paymentService;}public boolean checkout(Order order) {if (order.isPaid()) {return false;}boolean paymentResult = paymentService.processPayment(order.getTotalAmount());if (paymentResult) {order.setPaid(true);return true;}return false;}
}// 集成测试用例
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;public class OrderServiceIntegrationTest {@Testpublic void testCheckoutSuccess() {// 创建模拟的支付服务PaymentService paymentService = mock(PaymentService.class);when(paymentService.processPayment(100.0)).thenReturn(true);// 创建订单服务并注入模拟的支付服务OrderService orderService = new OrderService(paymentService);Order order = new Order("ORD123", 100.0);// 执行测试boolean result = orderService.checkout(order);// 验证结果assertTrue(result);assertTrue(order.isPaid());verify(paymentService, times(1)).processPayment(100.0);}@Testpublic void testCheckoutFailure() {PaymentService paymentService = mock(PaymentService.class);when(paymentService.processPayment(100.0)).thenReturn(false);OrderService orderService = new OrderService(paymentService);Order order = new Order("ORD123", 100.0);boolean result = orderService.checkout(order);assertFalse(result);assertFalse(order.isPaid());verify(paymentService, times(1)).processPayment(100.0);}
}

12.4.3 确认测试

   确认测试验证软件是否满足用户需求和规格说明,通常包括功能测试、性能测试等。例如,测试一个用户注册功能:

// 用户类
public class User {private String username;private String email;private String password;public User(String username, String email, String password) {this.username = username;this.email = email;this.password = password;}// Getters and setterspublic String getUsername() { return username; }public String getEmail() { return email; }public String getPassword() { return password; }
}// 用户服务接口
public interface UserService {boolean registerUser(User user);boolean isValidEmail(String email);
}// 用户服务实现
public class UserServiceImpl implements UserService {@Overridepublic boolean registerUser(User user) {// 验证邮箱格式if (!isValidEmail(user.getEmail())) {return false;}// 验证用户名和密码长度if (user.getUsername().length() < 3 || user.getPassword().length() < 6) {return false;}// 模拟保存用户到数据库System.out.println("用户注册成功: " + user.getUsername());return true;}@Overridepublic boolean isValidEmail(String email) {// 简单的邮箱格式验证return email.matches("^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$");}
}// 确认测试用例
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;public class UserServiceVerificationTest {@Testpublic void testRegisterUserSuccess() {UserService userService = new UserServiceImpl();User user = new User("john_doe", "john@example.com", "password123");assertTrue(userService.registerUser(user));}@Testpublic void testRegisterUserInvalidEmail() {UserService userService = new UserServiceImpl();User user = new User("john_doe", "invalid_email", "password123");assertFalse(userService.registerUser(user));}@Testpublic void testRegisterUserShortUsername() {UserService userService = new UserServiceImpl();User user = new User("jo", "john@example.com", "password123");assertFalse(userService.registerUser(user));}@Testpublic void testRegisterUserShortPassword() {UserService userService = new UserServiceImpl();User user = new User("john_doe", "john@example.com", "pass");assertFalse(userService.registerUser(user));}
}

12.4.4 系统测试

    系统测试将软件作为一个整体进行测试,验证系统是否满足需求。例如,测试一个在线购物系统的完整流程:

// 商品类
public class Product {private String productId;private String name;private double price;private int stock;public Product(String productId, String name, double price, int stock) {this.productId = productId;this.name = name;this.price = price;this.stock = stock;}// Getters and setterspublic String getProductId() { return productId; }public String getName() { return name; }public double getPrice() { return price; }public int getStock() { return stock; }public void setStock(int stock) { this.stock = stock; }
}// 购物车类
public class ShoppingCart {private Map<Product, Integer> items = new HashMap<>();public void addItem(Product product, int quantity) {items.put(product, items.getOrDefault(product, 0) + quantity);}public void removeItem(Product product) {items.remove(product);}public double getTotalPrice() {double total = 0;for (Map.Entry<Product, Integer> entry : items.entrySet()) {total += entry.getKey().getPrice() * entry.getValue();}return total;}public Map<Product, Integer> getItems() {return items;}
}// 订单类
public class Order {private String orderId;private List<Product> products;private double totalAmount;private OrderStatus status;public Order(String orderId, List<Product> products, double totalAmount) {this.orderId = orderId;this.products = products;this.totalAmount = totalAmount;this.status = OrderStatus.PENDING;}// Getters and setterspublic String getOrderId() { return orderId; }public List<Product> getProducts() { return products; }public double getTotalAmount() { return totalAmount; }public OrderStatus getStatus() { return status; }public void setStatus(OrderStatus status) { this.status = status; }
}// 订单状态枚举
public enum OrderStatus {PENDING, PAID, SHIPPED, DELIVERED, CANCELLED
}// 系统测试用例
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;public class ShoppingSystemSystemTest {@Testpublic void testEndToEndShoppingFlow() {// 创建商品Product laptop = new Product("P001", "笔记本电脑", 5000.0, 10);Product mouse = new Product("P002", "鼠标", 50.0, 20);// 创建购物车ShoppingCart cart = new ShoppingCart();cart.addItem(laptop, 1);cart.addItem(mouse, 2);// 验证购物车总价assertEquals(5100.0, cart.getTotalPrice(), 0.001);// 创建订单String orderId = "ORD" + System.currentTimeMillis();Order order = new Order(orderId, cart.getItems().keySet().stream().collect(Collectors.toList()), cart.getTotalPrice());// 处理订单支付order.setStatus(OrderStatus.PAID);assertEquals(OrderStatus.PAID, order.getStatus());// 更新库存for (Map.Entry<Product, Integer> entry : cart.getItems().entrySet()) {entry.getKey().setStock(entry.getKey().getStock() - entry.getValue());}// 验证库存更新assertEquals(9, laptop.getStock());assertEquals(18, mouse.getStock());// 发货order.setStatus(OrderStatus.SHIPPED);assertEquals(OrderStatus.SHIPPED, order.getStatus());// 确认收货order.setStatus(OrderStatus.DELIVERED);assertEquals(OrderStatus.DELIVERED, order.getStatus());}
}

12.5 面向对象软件的测试

12.5.1 类的测试

   类的测试关注类的属性、方法和状态。例如,测试一个银行账户类:

public class BankAccount {private String accountNumber;private double balance;private AccountStatus status;public BankAccount(String accountNumber, double initialBalance) {this.accountNumber = accountNumber;this.balance = initialBalance;this.status = AccountStatus.ACTIVE;}public void deposit(double amount) {if (amount <= 0) {throw new IllegalArgumentException("存款金额必须大于0");}if (status != AccountStatus.ACTIVE) {throw new IllegalStateException("账户状态异常,无法存款");}balance += amount;}public void withdraw(double amount) {if (amount <= 0) {throw new IllegalArgumentException("取款金额必须大于0");}if (status != AccountStatus.ACTIVE) {throw new IllegalStateException("账户状态异常,无法取款");}if (amount > balance) {throw new InsufficientFundsException("余额不足");}balance -= amount;}public void close() {if (balance != 0) {throw new IllegalStateException("账户余额不为0,无法关闭");}status = AccountStatus.CLOSED;}// Getterspublic String getAccountNumber() { return accountNumber; }public double getBalance() { return balance; }public AccountStatus getStatus() { return status; }
}// 账户状态枚举
public enum AccountStatus {ACTIVE, CLOSED, FROZEN
}// 自定义异常
public class InsufficientFundsException extends RuntimeException {public InsufficientFundsException(String message) {super(message);}
}// 类的测试用例
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;public class BankAccountTest {private BankAccount account;@BeforeEachpublic void setUp() {account = new BankAccount("123456", 1000.0);}@Testpublic void testInitialState() {assertEquals("123456", account.getAccountNumber());assertEquals(1000.0, account.getBalance(), 0.001);assertEquals(AccountStatus.ACTIVE, account.getStatus());}@Testpublic void testDeposit() {account.deposit(500.0);assertEquals(1500.0, account.getBalance(), 0.001);}@Testpublic void testDepositNegativeAmount() {assertThrows(IllegalArgumentException.class, () -> account.deposit(-100.0));}@Testpublic void testWithdraw() {account.withdraw(300.0);assertEquals(700.0, account.getBalance(), 0.001);}@Testpublic void testWithdrawInsufficientFunds() {assertThrows(InsufficientFundsException.class, () -> account.withdraw(1500.0));}@Testpublic void testCloseAccount() {account.withdraw(1000.0); // 清空余额account.close();assertEquals(AccountStatus.CLOSED, account.getStatus());}@Testpublic void testCloseAccountWithBalance() {assertThrows(IllegalStateException.class, () -> account.close());}
}

12.5.2 交互测试

   交互测试验证对象之间的协作和交互。例如,测试一个订单处理系统中对象间的交互:

// 订单类
public class Order {private String orderId;private List<OrderItem> items;private OrderStatus status;public Order(String orderId, List<OrderItem> items) {this.orderId = orderId;this.items = items;this.status = OrderStatus.PENDING;}public void processPayment(PaymentService paymentService) {double totalAmount = calculateTotalAmount();boolean paymentResult = paymentService.processPayment(totalAmount);if (paymentResult) {this.status = OrderStatus.PAID;}}private double calculateTotalAmount() {double total = 0;for (OrderItem item : items) {total += item.getProduct().getPrice() * item.getQuantity();}return total;}// Getters and setterspublic String getOrderId() { return orderId; }public List<OrderItem> getItems() { return items; }public OrderStatus getStatus() { return status; }
}// 订单条目类
public class OrderItem {private Product product;private int quantity;public OrderItem(Product product, int quantity) {this.product = product;this.quantity = quantity;}// Getterspublic Product getProduct() { return product; }public int getQuantity() { return quantity; }
}// 商品类
public class Product {private String productId;private String name;private double price;public Product(String productId, String name, double price) {this.productId = productId;this.name = name;this.price = price;}// Getterspublic String getProductId() { return productId; }public String getName() { return name; }public double getPrice() { return price; }
}// 支付服务接口
public interface PaymentService {boolean processPayment(double amount);
}// 交互测试用例
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;public class OrderInteractionTest {@Testpublic void testOrderPaymentProcess() {// 创建模拟的支付服务PaymentService paymentService = mock(PaymentService.class);when(paymentService.processPayment(100.0)).thenReturn(true);// 创建商品和订单条目Product product = new Product("P001", "手机", 100.0);OrderItem item = new OrderItem(product, 1);// 创建订单Order order = new Order("ORD123", List.of(item));// 处理支付order.processPayment(paymentService);// 验证结果assertEquals(OrderStatus.PAID, order.getStatus());verify(paymentService, times(1)).processPayment(100.0);}@Testpublic void testOrderPaymentFailure() {PaymentService paymentService = mock(PaymentService.class);when(paymentService.processPayment(100.0)).thenReturn(false);Product product = new Product("P001", "手机", 100.0);OrderItem item = new OrderItem(product, 1);Order order = new Order("ORD123", List.of(item));order.processPayment(paymentService);assertEquals(OrderStatus.PENDING, order.getStatus());verify(paymentService, times(1)).processPayment(100.0);}
}

12.5.3 继承的测试

   继承的测试关注子类与父类的关系,以及多态的正确性。例如,测试一个形状继承体系:

// 抽象形状类
public abstract class Shape {public abstract double calculateArea();public abstract double calculatePerimeter();
}// 矩形类
public class Rectangle extends Shape {private double length;private double width;public Rectangle(double length, double width) {this.length = length;this.width = width;}@Overridepublic double calculateArea() {return length * width;}@Overridepublic double calculatePerimeter() {return 2 * (length + width);}
}// 正方形类
public class Square extends Rectangle {public Square(double side) {super(side, side);}
}// 圆形类
public class Circle extends Shape {private double radius;public Circle(double radius) {this.radius = radius;}@Overridepublic double calculateArea() {return Math.PI * radius * radius;}@Overridepublic double calculatePerimeter() {return 2 * Math.PI * radius;}
}// 继承测试用例
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;public class ShapeInheritanceTest {@Testpublic void testRectangleArea() {Rectangle rectangle = new Rectangle(5.0, 3.0);assertEquals(15.0, rectangle.calculateArea(), 0.001);assertEquals(16.0, rectangle.calculatePerimeter(), 0.001);}@Testpublic void testSquareArea() {Square square = new Square(4.0);assertEquals(16.0, square.calculateArea(), 0.001);assertEquals(16.0, square.calculatePerimeter(), 0.001);}@Testpublic void testCircleArea() {Circle circle = new Circle(2.0);assertEquals(Math.PI * 4.0, circle.calculateArea(), 0.001);assertEquals(2 * Math.PI * 2.0, circle.calculatePerimeter(), 0.001);}@Testpublic void testPolymorphism() {Shape rectangle = new Rectangle(5.0, 3.0);Shape square = new Square(4.0);Shape circle = new Circle(2.0);assertEquals(15.0, rectangle.calculateArea(), 0.001);assertEquals(16.0, square.calculateArea(), 0.001);assertEquals(Math.PI * 4.0, circle.calculateArea(), 0.001);}
}

12.6小结

   软件测试是软件开发过程中不可或缺的环节,它贯穿于整个软件生命周期。通过本章的学习,我们了解了软件测试的概念、过程模型、测试方法以及面向对象软件的测试技术。合理运用各种测试方法和技术,能够有效发现软件中的缺陷,提高软件质量,确保软件满足用户需求。在实际项目中,应根据项目特点和需求,选择合适的测试策略和方法,制定全面的测试计划,以保证软件的可靠性和稳定性。

相关文章:

《软件工程》第 12 章 - 软件测试

软件测试是确保软件质量的关键环节&#xff0c;它通过执行程序来发现错误&#xff0c;验证软件是否满足需求。本章将依据目录&#xff0c;结合 Java 代码示例、可视化图表&#xff0c;深入讲解软件测试的概念、过程、方法及实践。 12.1 软件测试的概念 12.1.1 软件测试的任务 …...

消息队列-kafka为例

目录 消息队列应用场景和基础知识MQ常见的应用场景MQ消息队列的两种消息模式如何保证消息队列的高可用&#xff1f;如何保证消息不丢失&#xff1f;如何保证消息不被重复消费&#xff1f;如何保证消息消费的幂等性&#xff1f;重复消费的原因解决方案 如何保证消息被消费的顺序…...

学习STC51单片机20(芯片为STC89C52RCRC)

每日一言 生活不会一帆风顺&#xff0c;但你的勇敢能让风浪变成风景。 串口助手的界面就等于是pc端的页面设置的是pc端的波特率等等参数 程序里面的是单片机的波特率等等参数 串口助手是 PC 端软件 串口助手&#xff08;如 STC-ISP&#xff09;是运行在 PC 上的工具&#x…...

链路追踪神器zipkin安装详细教程教程

今天分享下zipkin的详细安装教程&#xff0c;具体代码demo可以参考我上篇文章&#xff1a;Spring Cloud Sleuth与Zipkin深度整合指南&#xff1a;微服务链路追踪实战-CSDN博客 一、Zipkin是什么&#xff1f; Zipkin是由Twitter开源的一款分布式追踪系统&#xff08;现由OpenZ…...

RabbitMQ备份与恢复技术详解:策略、工具与最佳实践

RabbitMQ作为广泛使用的消息中间件&#xff0c;其高可用性和数据持久化能力使其成为分布式系统的核心组件。然而&#xff0c;硬件故障、人为误操作或灾难性事件仍可能导致数据丢失或服务中断。因此&#xff0c;建立可靠的备份与恢复机制是运维工作的关键环节。本文基于RabbitMQ…...

bug: uniCloud 查询数组字段失败

问题根源&#xff1a;使用了支付宝云 官方说&#xff1a;2024年11月之后创建的新的支付宝云空间&#xff0c;数组字段查询强制必须设置 array 类型的索引 布尔类型的查询&#xff0c;强制必须设置 bool 类型的索引。 方案一&#xff1a;找到云服务空间-》云数据库-》对应的表-…...

Php JIT 使用详解

简介 PHP 8 引入的 JIT&#xff08;Just-In-Time 编译器&#xff09; 是该版本的一个重要性能特性&#xff0c;首次让 PHP 有了运行时即时编译的能力&#xff0c;从解释型语言迈向了“编译执行”的方向。 什么是 JIT&#xff1f; JIT 是 即时编译&#xff08;Just-In-Time c…...

视觉分析开发范例:Puppeteer截图+计算机视觉动态定位

一、选型背景&#xff1a;传统爬虫已无力应对的视觉挑战 在现代互联网环境中&#xff0c;尤其是小红书、抖音、B站等视觉驱动型平台&#xff0c;传统基于 HTML 的爬虫已经难以满足精准数据采集需求&#xff1a; 内容加载由 JS 动态触发&#xff0c;难以直接解析 HTML&#xf…...

Linux 基础开发工具的使用

目录 前言 一&#xff1a;下载工具yum 二&#xff1a;文本编辑器vim 1. 命令模式 2. 插入模式 3. 底行模式 三&#xff1a;gcc和g 基本使用格式 常用选项及作用 编译过程示例 四、Linux 项目自动化构建工具 ——make/Makefile 1. make 与 Makefile 的关系 2. Make…...

ElasticSearch查询指定时间内出现的次数/2秒内出现的次数

查询指定时间内出现的次数 POST process-log/_search {"size": 0,"query": {"bool": {"filter": [{"range": {"requestTime": {"from": 1722470400000,"to": 1722556800000}}}]}},"agg…...

华为云Flexus+DeepSeek征文 | Dify-LLM平台一键部署教程及问题解决指南

作者简介 我是摘星&#xff0c;一名专注于云计算和AI技术的开发者。本次通过华为云MaaS平台体验DeepSeek系列模型&#xff0c;将实际使用经验分享给大家&#xff0c;希望能帮助开发者快速掌握华为云AI服务的核心能力。 目录 1. 前言 2. 准备工作 2.1 注册华为云账号 2.2 确…...

STP协议:如何消除网络环路风暴

生成树协议&#xff08;STP&#xff0c;Spanning Tree Protocol&#xff09;的主要功能&#xff1a; 消除网络环路导致的广播风暴问题&#xff08;环路会引发MAC地址表不稳定&#xff09;防止网络中的主机接收重复数据帧 STP工作原理&#xff1a; 选举根桥&#xff08;Root …...

哈工大计算机系统2025大作业——Hello的程序人生

计算机系统 大作业 题 目 程序人生-Hello’s P2P 专 业 计算学部 学   号 2023113072 班 级 23L0513 学 生 董国帅 指 导 教 师 史先俊 计算机科学与…...

物联网常用协议Modbus、CAN、BACnet介绍

一、Modbus Modbus 作为工业通信领域的基石,是一款被广泛应用的工业通信协议,主要用于实现可编程逻辑控制器(PLC)等工业电子设备之间的连接。1979 年,Modicon 公司(现施耐德电气的一部分)开发了这一协议,旨在简化工厂内设备间的通信流程。经过多年发展,Modbus 衍生出…...

Vue中van-stepper与input值不同步问题及解决方案

一、问题描述 在使用Vant UI的van-stepper步进器组件与原生input输入框绑定同一响应式数据时&#xff0c;出现以下现象&#xff1a; 通过步进器修改值后&#xff0c;页面直接输出{{ count }}和watch监听器均能获取最新值但input输入框显示的数值未同步更新&#xff0c;仍为旧…...

react基础技术栈

react基础技术栈 react项目构建react的事件绑定React组件的响应式数据条件渲染和列表循环表单绑定 Props和组件间传值&#xff0c;插槽react中的样式操作 生命周期ref 和 context函数组件和hook高阶组件React性能问题React-route的三个版本react-router使用步骤react-router提供…...

Three.js搭建小米SU7三维汽车实战(4)场景搭建

场地搭建 javascript // 导入threejs import * as THREE from "three"; // 导入轨道控制器 import { OrbitControls } from "three/addons/controls/OrbitControls.js"; // 1. 创建场景 const scene new THREE.Scene(); // 2. 创建相机 const camera ne…...

redis五种数据结构底层实现

参考文档&#xff1a; redis5种数据结构底层实现...

Excel 统计某个字符串在指定区域出现的次数

【本文概要】 Excel 统计某个字符串在指定区域出现的次数&#xff1a; 1、Excel 统计一个单元格内的某字符串的出现次数 2、Excel 统计某一列所有单元格内的某字符串的出现次数 3、Excel 统计某一区域所有单元格内的某字符串的出现次数 1、Excel 统计一个单元格内的某字符串的出…...

【Kubernetes】ubuntu20.04通过kubeadm + Docker安装k8s

Kubernetes v1.24集群安装配置步骤总结 一、环境准备 &#xff08;一&#xff09;系统要求 运行兼容deb/rpm的Linux操作系统&#xff08;如Ubuntu或CentOS&#xff09;的计算机&#xff0c;1台或多台。每台机器内存2GB以上&#xff0c;内存不足会限制应用运行。控制平面节点…...

前端开源JavaScrip库

以下内容仍在持续完善中&#xff0c;如有遗漏或需要补充之处&#xff0c;欢迎在评论区指出。感谢支持&#xff0c;如果觉得有帮助&#xff0c;欢迎点赞鼓励。感谢支持 JavaScript 框架Vue.jsVue.js - 渐进式 JavaScript 框架 | Vue.jsReactReactAngularHome • AngularjQueryj…...

【Linux我做主】进度条小程序深度解析

Linux下C语言进度条程序深度解析 进度条小程序GitHub地址 前言前置知识回车换行&#xff08;CR/LF&#xff09;的深度解析历史渊源与技术规范在进度条/倒计时中的应用 缓冲区机制的全面剖析缓冲区引入缓冲类型对比进度条开发中的关键控制 进度条实现以小见大——倒计时倒计时最…...

MySQL 使用全局锁会导致的问题?

MySQL 使用全局锁会导致以下核心问题&#xff1a; ‌业务停摆与主从延迟‌ ‌主库备份‌&#xff1a;备份期间所有更新操作被阻塞&#xff0c;业务系统陷入等待状态‌从库备份‌&#xff1a;无法执行主库同步的 binlog&#xff0c;导致主从复制延迟加剧 ‌并发性能急剧下降‌ …...

从Homebrew找到openssl.cnf文件并拷贝到Go项目下使用

安装OpenSSL 在 macOS 上下载和安装 OpenSSL 最常见和推荐的方式是使用 Homebrew&#xff0c;这是一个 macOS 缺失的包管理器。 如果您还没有安装 Homebrew&#xff0c;请先安装它。安装 Homebrew 后&#xff0c;安装 OpenSSL 只需要一条命令。 步骤 1&#xff1a;安装 Home…...

在Java对象转JSON字符串时不显示无值参数

在Java中&#xff0c;可以通过在展示数据的逻辑中添加判断条件来实现这一需求。以下是一些常见的场景和实现方法&#xff1a; 场景一&#xff1a;在Java对象转JSON字符串时 使用Gson库 代码实现 首先引入Gson依赖&#xff0c;如果使用Maven构建项目&#xff0c;在pom.xml文件中…...

在 Ubuntu 服务器上 下载 Clash 文件使用代理

文件Clash.Verge_1.3.8_x64_portable.zip 在 Ubuntu 服务器上不能使用这个Clash 文件**&#xff0c;我们需要的是 Clash.Meta 而不是 Clash Verge GUI 客户端 也就是 Clash Verge GUI 客户端的 Windows 版本&#xff0c;是给 Windows 桌面环境用的图形界面&#xff0c;不适用…...

微信小程序一次性订阅封装

封装代码如下&#xff1a; export async function subscribeMessage(tmplIds: string[]): Promise<ISubscribeMessagePromise> {// 模板ID// 1、获取设置状态const settings (await wx.getSetting({ withSubscriptions: true })).subscriptionsSetting || {}console.log…...

Spring AI MCP的几个小问题

测试时间&#xff1a;2025/05/29 测试版本&#xff1a;Spring AI 1.0.0 问题1&#xff1a;由于启动顺序问题&#xff0c;MCP的服务器端和客户端不能在一个应用里&#xff0c;不然客户端连不上服务器会报错退出。(实际项目应该没有这样用的) 问题2&#xff1a;现在如果配置了…...

安全帽检测算法AI智能分析网关V4守护工地/矿山/工厂等多场景作业安全

一、方案概述​ 在工业生产与建筑施工场景中&#xff0c;安全帽是保障人员安全的重要装备。但传统人工巡检效率低、易疏漏&#xff0c;难以满足现代安全管理需求。AI智能分析网关V4安全帽检测方案&#xff0c;借助人工智能与计算机视觉技术&#xff0c;实现作业现场安全帽佩戴…...

Pycharm的简单介绍

目录 1. 起源与发展历史 2. 定位与核心作用 3. 主要版本 4. 应用场景 5. 核心功能与优势 6. 优缺点分析 7. 使用入门指南 8. 适用人群 9. 替代工具对比 总结 1. 起源与发展历史 公司背景&#xff1a;由捷克公司 JetBrains&#xff08;成立于2000年&#xff09;开发&a…...