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

news2025/6/3 0:54:00

   软件测试是确保软件质量的关键环节,它通过执行程序来发现错误,验证软件是否满足需求。本章将依据目录,结合 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 {
    @Test
    public void testAddPositiveNumbers() {
        Calculator calculator = new Calculator();
        int result = calculator.add(3, 5);
        assertEquals(8, result); // 预期结果为8
    }

    @Test
    public 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 {
    @Test
    public void testCheckNumberTrue() {
        ControlFlow cf = new ControlFlow();
        assertTrue(cf.checkNumber(12)); // 覆盖true分支
    }

    @Test
    public void testCheckNumberFalse1() {
        ControlFlow cf = new ControlFlow();
        assertFalse(cf.checkNumber(5)); // 覆盖false分支(num <= 10)
    }

    @Test
    public 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 {
    @Test
    public void testEquilateralTriangle() {
        TriangleClassifier tc = new TriangleClassifier();
        assertEquals("等边三角形", tc.classify(3, 3, 3));
    }

    @Test
    public void testIsoscelesTriangle() {
        TriangleClassifier tc = new TriangleClassifier();
        assertEquals("等腰三角形", tc.classify(3, 3, 4));
    }

    @Test
    public void testScaleneTriangle() {
        TriangleClassifier tc = new TriangleClassifier();
        assertEquals("普通三角形", tc.classify(3, 4, 5));
    }

    @Test
    public void testNotTriangle() {
        TriangleClassifier tc = new TriangleClassifier();
        assertEquals("非三角形", tc.classify(1, 2, 3));
    }

    @Test
    public void testBoundaryValues() {
        TriangleClassifier tc = new TriangleClassifier();
        assertEquals("非三角形", tc.classify(0, 3, 4)); // 边界值0
        assertEquals("等腰三角形", 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;

    @BeforeEach
    public void setUp() {
        stack = new Stack(5);
    }

    @Test
    public void testPushAndPop() {
        stack.push(10);
        stack.push(20);
        assertEquals(20, stack.pop());
        assertEquals(10, stack.pop());
    }

    @Test
    public void testPeek() {
        stack.push(10);
        assertEquals(10, stack.peek());
        assertEquals(10, stack.peek()); // 多次peek不应改变栈
    }

    @Test
    public void testEmptyStack() {
        assertTrue(stack.isEmpty());
        assertThrows(EmptyStackException.class, () -> stack.pop());
        assertThrows(EmptyStackException.class, () -> stack.peek());
    }

    @Test
    public 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 {
    @Test
    public 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);
    }

    @Test
    public 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 setters
    public 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 {
    @Override
    public 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;
    }

    @Override
    public 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 {
    @Test
    public void testRegisterUserSuccess() {
        UserService userService = new UserServiceImpl();
        User user = new User("john_doe", "john@example.com", "password123");
        assertTrue(userService.registerUser(user));
    }

    @Test
    public void testRegisterUserInvalidEmail() {
        UserService userService = new UserServiceImpl();
        User user = new User("john_doe", "invalid_email", "password123");
        assertFalse(userService.registerUser(user));
    }

    @Test
    public void testRegisterUserShortUsername() {
        UserService userService = new UserServiceImpl();
        User user = new User("jo", "john@example.com", "password123");
        assertFalse(userService.registerUser(user));
    }

    @Test
    public 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 setters
    public 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 setters
    public 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 {
    @Test
    public 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;
    }

    // Getters
    public 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;

    @BeforeEach
    public void setUp() {
        account = new BankAccount("123456", 1000.0);
    }

    @Test
    public void testInitialState() {
        assertEquals("123456", account.getAccountNumber());
        assertEquals(1000.0, account.getBalance(), 0.001);
        assertEquals(AccountStatus.ACTIVE, account.getStatus());
    }

    @Test
    public void testDeposit() {
        account.deposit(500.0);
        assertEquals(1500.0, account.getBalance(), 0.001);
    }

    @Test
    public void testDepositNegativeAmount() {
        assertThrows(IllegalArgumentException.class, () -> account.deposit(-100.0));
    }

    @Test
    public void testWithdraw() {
        account.withdraw(300.0);
        assertEquals(700.0, account.getBalance(), 0.001);
    }

    @Test
    public void testWithdrawInsufficientFunds() {
        assertThrows(InsufficientFundsException.class, () -> account.withdraw(1500.0));
    }

    @Test
    public void testCloseAccount() {
        account.withdraw(1000.0); // 清空余额
        account.close();
        assertEquals(AccountStatus.CLOSED, account.getStatus());
    }

    @Test
    public 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 setters
    public 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;
    }

    // Getters
    public 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;
    }

    // Getters
    public 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 {
    @Test
    public 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);
    }

    @Test
    public 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;
    }

    @Override
    public double calculateArea() {
        return length * width;
    }

    @Override
    public 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;
    }

    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }

    @Override
    public double calculatePerimeter() {
        return 2 * Math.PI * radius;
    }
}

// 继承测试用例
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class ShapeInheritanceTest {
    @Test
    public void testRectangleArea() {
        Rectangle rectangle = new Rectangle(5.0, 3.0);
        assertEquals(15.0, rectangle.calculateArea(), 0.001);
        assertEquals(16.0, rectangle.calculatePerimeter(), 0.001);
    }

    @Test
    public void testSquareArea() {
        Square square = new Square(4.0);
        assertEquals(16.0, square.calculateArea(), 0.001);
        assertEquals(16.0, square.calculatePerimeter(), 0.001);
    }

    @Test
    public 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);
    }

    @Test
    public 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小结

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

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

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

相关文章

消息队列-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…

bug: uniCloud 查询数组字段失败

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

视觉分析开发范例: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…

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

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

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

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

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…

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

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

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

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

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

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

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

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

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

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

Python自动化之selenium语句——打开、关闭浏览器和网页

目录 一、打开谷歌浏览器 1.双击桌面的Pycharm工具 2.新建Python文件&#xff0c;输入文件名 3.新建的Python文件如下 4.安装selenium库 5.导入包 二、打开网页、关闭网页、关闭浏览器 1.导入增加一个时间包 2.使用函数打包之前写的浏览器的配置 3.调用 4.打开百度网…

【数据结构】--二叉树--堆(上)

一、树的概念和结构 概念&#xff1a; 树是一种非线性的数据结构&#xff0c;他是由n(n>0)个有限结点组成一个具有层次关系的集合。其叫做树&#xff0c;是因为他倒过来看就和一棵树差不多&#xff0c;其实际上是根在上&#xff0c;树枝在下的。 树的特点&#xff1a; 1…

多线程(5)——单例模式,阻塞队列

目录 单例模式饿汉模式懒汉模式—单线程版懒汉模式—多线程版&#xff08;经典面试题&#xff09;懒汉模式—多线程版&#xff08;改进&#xff09; 阻塞队列阻塞队列是什么生产者消费者模型标准库中的阻塞队列-BlockingQueue阻塞队列实现 单例模式 单例模式是一种设计模式&am…

视频监控汇聚平台EasyCVR工业与安全监控:防爆摄像机的安全应用与注意事项

石油、化工、煤矿等行业存在易燃易爆气体、粉尘&#xff0c;普通监控设备易因电火花、高温引发爆炸火灾。随着工业规模扩大&#xff0c;安全生产监控需求激增&#xff0c;防爆摄像机成为保障安全的关键。加之国家法规与行业标准对危险环境监控设备要求严格&#xff0c;规范其应…