使用 Golang `testing/quick` 包进行高效随机测试的实战指南

news2025/6/7 13:38:40

使用 Golang `testing/quick` 包进行高效随机测试的实战指南

    • Golang `testing/quick` 包概述
      • `testing/quick` 包的功能和用途
      • 为什么选择 `testing/quick` 进行测试
      • 快速入门:基本用法
      • 导入 `testing/quick` 包
      • 基本使用示例:快速生成测试数据
      • `quick.Check` 和 `quick.Value` 的基本用法
    • 深入理解 `quick.Generator` 接口
      • `quick.Generator` 接口介绍
      • 实现自定义生成器:基本示例
      • 使用自定义生成器进行复杂数据测试
      • 高级技巧:控制生成数据的范围和类型
      • 使用 `quick.Config` 自定义测试参数
      • 控制生成数据的范围和类型
      • 处理边界条件和极端值测试
    • 并发测试与性能优化
      • 并发测试的重要性
      • `testing/quick` 包中的并发测试策略
      • 提高测试性能的技巧和建议
    • 实战案例:综合运用
      • 结合实际项目案例进行综合测试
        • 订单处理系统示例
      • 常见问题和解决方案
        • 问题 1:随机数据生成不符合预期
        • 问题 2:并发测试中的数据竞争

在这里插入图片描述

Golang testing/quick 包概述

Golang 提供了丰富的标准库,其中 testing/quick 包是一个非常有用的工具,用于编写随机化测试。它允许开发者自动生成各种测试数据,以更好地覆盖代码的不同情况,从而提高代码的健壮性和可靠性。

testing/quick 包的功能和用途

testing/quick 包主要用于基于随机数据的快速测试。通过随机生成输入数据并进行测试,可以发现一些手工测试难以覆盖的边界条件和异常情况。这种方法特别适合于:

  • 探索性测试:在不知道具体输入数据会是什么的情况下,通过随机数据测试来探索代码可能存在的问题。
  • 边界测试:自动生成的测试数据可以包括各种边界值,从而更好地检测代码在极端情况下的表现。
  • 代码覆盖:通过大量随机数据的输入,可以提高代码的测试覆盖率,确保大部分代码路径都经过测试。

为什么选择 testing/quick 进行测试

  1. 简化测试数据生成:传统的单元测试通常需要开发者手动编写各种输入数据和预期结果,而 testing/quick 可以自动生成这些数据,大大简化了测试编写的工作量。
  2. 提高测试覆盖率:随机生成的测试数据可以覆盖更多的情况和边界条件,帮助发现手工测试可能遗漏的问题。
  3. 发现隐藏的 bug:由于输入数据是随机生成的,可能会发现一些在手工测试中无法发现的隐藏 bug。
  4. 节省时间和精力:自动化的数据生成和测试可以节省开发者大量的时间和精力,使其能够专注于更重要的开发任务。

通过了解 testing/quick 包的功能和用途,我们可以更好地利用这个工具进行高效、全面的测试。在接下来的章节中,我们将详细介绍如何使用 testing/quick 包进行测试,并提供丰富的代码示例帮助理解和实践。

快速入门:基本用法

为了更好地理解 testing/quick 包的使用,我们先从基本用法入手。

导入 testing/quick

在使用 testing/quick 包之前,需要先在代码中导入它。导入方法如下:

import (
    "testing"
    "testing/quick"
)

基本使用示例:快速生成测试数据

testing/quick 提供了 quick.Check 函数,用于自动生成测试数据并执行测试。以下是一个简单的示例,演示如何使用 quick.Check 进行基本的随机化测试:

func TestAdd(t *testing.T) {
    add := func(a, b int) int {
        return a + b
    }
    
    f := func(a, b int) bool {
        return add(a, b) == a + b
    }
    
    if err := quick.Check(f, nil); err != nil {
        t.Error(err)
    }
}

在这个示例中,我们定义了一个 add 函数和一个测试函数 ff 函数接受两个 int 类型的参数,并验证 add 函数的输出是否正确。quick.Check 函数会自动生成各种随机的 int 类型参数,并多次调用 f 函数进行测试。如果 f 函数返回 false 或者出现错误,quick.Check 会返回一个错误信息。

quick.Checkquick.Value 的基本用法

除了 quick.Checkquick.Value 也是 testing/quick 包中的一个重要函数。它用于生成随机值。以下是一个简单示例:

func TestRandomValue(t *testing.T) {
    var intValue int
    if err := quick.Value(reflect.TypeOf(intValue), nil); err != nil {
        t.Error(err)
    }
}

在这个示例中,quick.Value 会生成一个随机的 int 类型值并赋值给 intValue 变量。

通过上述示例,我们可以看到 testing/quick 包如何简化了测试数据的生成和测试过程。接下来,我们将深入探讨 quick.Generator 接口,了解如何自定义生成器以满足更复杂的测试需求。

深入理解 quick.Generator 接口

在使用 testing/quick 包进行测试时,有时我们需要生成一些更复杂的测试数据,而不仅仅是简单的基础数据类型。此时,我们可以通过实现 quick.Generator 接口来自定义数据生成器。

quick.Generator 接口介绍

quick.Generator 是一个接口,用于定义如何生成自定义的测试数据。该接口只有一个方法:

type Generator interface {
    Generate(rand *rand.Rand, size int) reflect.Value
}
  • Generate 方法接收一个随机数生成器 rand 和一个表示数据规模的整数 size,返回一个 reflect.Value 类型的值。

实现自定义生成器:基本示例

下面是一个简单示例,演示如何实现一个自定义生成器,用于生成一个包含随机字符串的结构体:

package main

import (
    "math/rand"
    "reflect"
    "testing/quick"
)

// 定义结构体
type MyStruct struct {
    Name string
}

// 实现 quick.Generator 接口
func (m MyStruct) Generate(rand *rand.Rand, size int) reflect.Value {
    letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
    name := make([]rune, size)
    for i := range name {
        name[i] = letters[rand.Intn(len(letters))]
    }
    m.Name = string(name)
    return reflect.ValueOf(m)
}

func main() {
    config := &quick.Config{
        MaxCount: 10, // 测试次数
    }
    f := func(m MyStruct) bool {
        // 在这里编写测试逻辑
        return len(m.Name) > 0
    }
    if err := quick.Check(f, config); err != nil {
        panic(err)
    }
}

在这个示例中,我们定义了一个结构体 MyStruct,并实现了 quick.Generator 接口的 Generate 方法,用于生成包含随机字符串的 MyStruct 实例。然后,我们使用 quick.Check 函数对生成的数据进行测试。

使用自定义生成器进行复杂数据测试

通过实现 quick.Generator 接口,我们可以生成各种复杂类型的数据,从而进行更全面的测试。下面是一个更复杂的示例,生成一个包含嵌套结构体的自定义数据类型:

package main

import (
    "math/rand"
    "reflect"
    "testing/quick"
)

// 定义嵌套结构体
type InnerStruct struct {
    Age int
}

type OuterStruct struct {
    Name  string
    Inner InnerStruct
}

// 实现 quick.Generator 接口
func (o OuterStruct) Generate(rand *rand.Rand, size int) reflect.Value {
    letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
    name := make([]rune, size)
    for i := range name {
        name[i] = letters[rand.Intn(len(letters))]
    }
    o.Name = string(name)
    o.Inner = InnerStruct{Age: rand.Intn(100)}
    return reflect.ValueOf(o)
}

func main() {
    config := &quick.Config{
        MaxCount: 10, // 测试次数
    }
    f := func(o OuterStruct) bool {
        // 在这里编写测试逻辑
        return len(o.Name) > 0 && o.Inner.Age >= 0
    }
    if err := quick.Check(f, config); err != nil {
        panic(err)
    }
}

在这个示例中,我们定义了两个结构体 InnerStructOuterStruct,并实现了 OuterStruct 的自定义生成器。Generate 方法生成包含随机字符串和随机整数的嵌套结构体实例。然后,我们使用 quick.Check 函数对生成的数据进行测试。

通过以上示例,我们了解了如何实现和使用自定义生成器来生成复杂的测试数据。在下一部分,我们将探讨如何使用 quick.Config 来控制生成数据的范围和类型,以便更精确地进行测试。

高级技巧:控制生成数据的范围和类型

在使用 testing/quick 包进行测试时,有时我们需要对生成的数据进行更精确的控制,例如限制数据的范围或类型。quick.Config 提供了一种灵活的方式来配置数据生成参数。

使用 quick.Config 自定义测试参数

quick.Config 结构体包含多个字段,用于配置测试参数。以下是 quick.Config 的定义:

type Config struct {
    MaxCount    int           // 最大测试次数
    MaxCountScale float64     // 测试次数的缩放比例
    Rand        *rand.Rand    // 自定义随机数生成器
    Values      func([]reflect.Value, *rand.Rand) // 自定义值生成函数
}

通过设置这些字段,我们可以灵活地控制测试数据的生成方式。

控制生成数据的范围和类型

以下是一个示例,演示如何使用 quick.Config 来限制生成的整数数据范围:

package main

import (
    "math/rand"
    "reflect"
    "testing"
    "testing/quick"
)

func TestRange(t *testing.T) {
    config := &quick.Config{
        Values: func(args []reflect.Value, rand *rand.Rand) {
            for i := range args {
                args[i] = reflect.ValueOf(rand.Intn(50) + 50) // 生成范围在 50 到 100 之间的整数
            }
        },
    }
    f := func(a int) bool {
        return a >= 50 && a <= 100
    }
    if err := quick.Check(f, config); err != nil {
        t.Error(err)
    }
}

在这个示例中,我们通过设置 quick.ConfigValues 字段,定义了一个自定义的值生成函数。该函数生成范围在 50 到 100 之间的随机整数。

处理边界条件和极端值测试

处理边界条件和极端值测试是确保代码健壮性的重要部分。以下示例演示如何生成和测试极端值:

package main

import (
    "math"
    "math/rand"
    "reflect"
    "testing"
    "testing/quick"
)

func TestExtremeValues(t *testing.T) {
    config := &quick.Config{
        Values: func(args []reflect.Value, rand *rand.Rand) {
            for i := range args {
                if rand.Float64() < 0.1 { // 10% 的概率生成极端值
                    args[i] = reflect.ValueOf(math.MaxInt64)
                } else {
                    args[i] = reflect.ValueOf(rand.Int63())
                }
            }
        },
    }
    f := func(a int64) bool {
        return true // 在这里编写测试逻辑
    }
    if err := quick.Check(f, config); err != nil {
        t.Error(err)
    }
}

在这个示例中,我们通过自定义的值生成函数,以 10% 的概率生成极端值 math.MaxInt64,其余情况下生成随机整数。这种方法可以有效地测试代码在处理极端值时的表现。

通过以上内容,我们详细介绍了如何使用 quick.Config 自定义测试参数和生成数据范围,并展示了如何处理边界条件和极端值测试。接下来,我们将探讨并发测试与性能优化技巧,以提高测试效率和效果。

并发测试与性能优化

在现代软件开发中,并发测试是非常重要的一环。特别是在 Golang 这种以并发为核心特性的语言中,并发测试能够有效发现多线程环境下的潜在问题和性能瓶颈。testing/quick 包同样适用于并发测试,并提供了一些策略和技巧来优化性能。

并发测试的重要性

并发测试能够帮助开发者发现以下问题:

  • 数据竞争:在多线程环境下,不同线程可能会同时访问和修改共享数据,从而导致数据不一致的问题。
  • 死锁:两个或多个线程在等待对方释放资源时,可能会陷入死锁状态,导致程序无法继续执行。
  • 性能瓶颈:并发测试可以揭示多线程环境下的性能问题,帮助开发者优化代码以提高性能。

testing/quick 包中的并发测试策略

通过结合 testing/quick 包和 Golang 的 testing 包,我们可以轻松实现并发测试。以下是一个示例,演示如何在 quick.Check 函数中进行并发测试:

package main

import (
    "math/rand"
    "reflect"
    "sync"
    "testing"
    "testing/quick"
)

// 线程安全的计数器
type Counter struct {
    mu    sync.Mutex
    count int
}

func (c *Counter) Increment() {
    c.mu.Lock()
    defer c.mu.Unlock()
    c.count++
}

func TestConcurrentCounter(t *testing.T) {
    config := &quick.Config{
        MaxCount: 1000, // 增加测试次数
    }

    f := func() bool {
        c := &Counter{}
        var wg sync.WaitGroup
        for i := 0; i < 10; i++ {
            wg.Add(1)
            go func() {
                defer wg.Done()
                for j := 0; j < 100; j++ {
                    c.Increment()
                }
            }()
        }
        wg.Wait()
        return c.count == 1000
    }

    if err := quick.Check(f, config); err != nil {
        t.Error(err)
    }
}

在这个示例中,我们定义了一个线程安全的计数器 Counter,并在测试函数中启动多个 goroutine 同时对计数器进行递增操作。quick.Check 函数将多次执行这个测试,确保计数器在并发环境下的正确性。

提高测试性能的技巧和建议

在进行大规模并发测试时,性能优化显得尤为重要。以下是一些提高测试性能的技巧和建议:

  1. 减少锁的争用:在编写并发代码时,尽量减少对锁的依赖,以避免性能瓶颈。例如,可以使用无锁数据结构或分片锁(sharded lock)来优化性能。
  2. 使用 Goroutine 池:在大量并发测试中,频繁创建和销毁 goroutine 可能会带来性能开销。使用 goroutine 池可以有效降低这种开销,提高测试性能。
  3. 配置合理的测试参数:通过调整 quick.Config 中的 MaxCountRand 等参数,可以控制测试的规模和随机性,平衡测试覆盖率与性能之间的关系。
  4. 分布式测试:对于非常大规模的并发测试,可以考虑将测试任务分布到多个机器上执行,以充分利用集群资源。

以下是一个使用 goroutine 池进行并发测试的示例:

package main

import (
    "math/rand"
    "reflect"
    "sync"
    "testing"
    "testing/quick"
)

type WorkerPool struct {
    tasks   chan func()
    wg      sync.WaitGroup
}

func NewWorkerPool(size int) *WorkerPool {
    pool := &WorkerPool{
        tasks: make(chan func()),
    }
    for i := 0; i < size; i++ {
        pool.wg.Add(1)
        go func() {
            defer pool.wg.Done()
            for task := range pool.tasks {
                task()
            }
        }()
    }
    return pool
}

func (p *WorkerPool) Submit(task func()) {
    p.tasks <- task
}

func (p *WorkerPool) Shutdown() {
    close(p.tasks)
    p.wg.Wait()
}

func TestWorkerPool(t *testing.T) {
    pool := NewWorkerPool(10)
    config := &quick.Config{
        MaxCount: 1000,
    }

    f := func() bool {
        c := &Counter{}
        var wg sync.WaitGroup
        for i := 0; i < 10; i++ {
            wg.Add(1)
            pool.Submit(func() {
                defer wg.Done()
                for j := 0; j < 100; j++ {
                    c.Increment()
                }
            })
        }
        wg.Wait()
        return c.count == 1000
    }

    if err := quick.Check(f, config); err != nil {
        t.Error(err)
    }

    pool.Shutdown()
}

在这个示例中,我们实现了一个简单的 goroutine 池 WorkerPool,并在并发测试中使用它来分配任务。这样可以避免频繁创建和销毁 goroutine 带来的性能开销,提高测试效率。

通过以上内容,我们了解了如何使用 testing/quick 包进行并发测试,并学习了一些提高测试性能的技巧和建议。在下一部分,我们将结合实际项目案例进行综合测试,分享常见问题和解决方案以及最佳实践。

好的,以下是文章的下一部分内容。


实战案例:综合运用

在实际项目中,综合运用 testing/quick 包可以显著提高测试的覆盖率和效率。通过真实的项目案例,我们可以更好地理解如何在实际开发中应用这些技巧和方法。

结合实际项目案例进行综合测试

下面我们以一个简单的订单处理系统为例,演示如何使用 testing/quick 包进行综合测试。

订单处理系统示例

假设我们有一个订单处理系统,其中包含订单创建和订单处理两个核心功能。我们需要对这两个功能进行全面的测试。

package main

import (
    "math/rand"
    "reflect"
    "testing"
    "testing/quick"
)

// 订单结构体
type Order struct {
    ID     int
    Amount float64
}

// 订单处理函数
func ProcessOrder(order Order) bool {
    // 假设处理订单的逻辑是订单金额必须大于 0
    return order.Amount > 0
}

// 实现 quick.Generator 接口生成随机订单
func (o Order) Generate(rand *rand.Rand, size int) reflect.Value {
    o.ID = rand.Intn(1000)
    o.Amount = rand.Float64() * 100 // 生成 0 到 100 之间的随机金额
    return reflect.ValueOf(o)
}

func TestProcessOrder(t *testing.T) {
    config := &quick.Config{
        MaxCount: 1000, // 测试次数
    }

    f := func(o Order) bool {
        return ProcessOrder(o)
    }

    if err := quick.Check(f, config); err != nil {
        t.Error(err)
    }
}

func main() {
    // 运行测试
    testing.M{}
}

在这个示例中,我们定义了一个 Order 结构体和一个处理订单的函数 ProcessOrder。我们实现了 Order 结构体的 quick.Generator 接口,用于生成随机订单。在测试函数 TestProcessOrder 中,我们使用 quick.Check 函数对 ProcessOrder 进行测试。

常见问题和解决方案

在使用 testing/quick 包进行测试时,可能会遇到一些常见问题。以下是一些常见问题及其解决方案:

问题 1:随机数据生成不符合预期

有时生成的随机数据可能不符合测试需求。这时可以通过自定义生成器或配置 quick.Config 来解决。

func TestCustomRange(t *testing.T) {
    config := &quick.Config{
        Values: func(args []reflect.Value, rand *rand.Rand) {
            for i := range args {
                args[i] = reflect.ValueOf(rand.Intn(100) + 100) // 生成 100 到 200 之间的整数
            }
        },
    }

    f := func(a int) bool {
        return a >= 100 && a <= 200
    }

    if err := quick.Check(f, config); err != nil {
        t.Error(err)
    }
}
问题 2:并发测试中的数据竞争

在并发测试中,可能会遇到数据竞争问题。这时需要确保代码中的共享数据是线程安全的。

type SafeCounter struct {
    mu    sync.Mutex
    count int
}

func (c *SafeCounter) Increment() {
    c.mu.Lock()
    defer c.mu.Unlock()
    c.count++
}

func TestConcurrentSafeCounter(t *testing.T) {
    config := &quick.Config{
        MaxCount: 1000,
    }

    f := func() bool {
        c := &SafeCounter{}
        var wg sync.WaitGroup
        for i := 0; i < 10; i++ {
            wg.Add(1)
            go func() {
                defer wg.Done()
                for j := 0; j < 100; j++ {
                    c.Increment()
                }
            }()
        }
        wg.Wait()
        return c.count == 1000
    }

    if err := quick.Check(f, config); err != nil {
        t.Error(err)
    }
}

通过以下最佳实践,可以更好地利用 testing/quick 包进行测试:

  1. 充分利用随机测试:尽量多使用随机测试来覆盖各种边界条件和异常情况。
  2. 自定义生成器:根据实际需求实现自定义生成器,以生成更符合测试要求的数据。
  3. 并发测试:在多线程环境下进行并发测试,确保代码的线程安全性。
  4. 合理配置测试参数:根据实际情况配置 quick.Config,控制测试次数和随机数生成策略。
  5. 定期复查测试用例:定期复查和更新测试用例,确保测试覆盖率和测试效果。

通过不断学习和实践,我们可以更好地利用 testing/quick 包进行高效的测试,提升代码的质量和稳定性。

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

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

相关文章

32 C 语言字符处理函数详解:isalnum、isalpha、iscntrl、isprint、isgraph、ispunct、isspace

1 isalnum() 函数 1.1 函数原型 #include <ctype.h>int isalnum(int c); 1.2 功能说明 isalnum() 函数用于检查传入的整数参数是否为 ASCII 编码的字母或数字字符&#xff08;A - Z、a - z、0 - 9&#xff0c;对应 ASCII 值 65 - 90、97 - 122、48 - 57&#xff09;。…

Qt实现一个悬浮工具箱源码分享

一、效果展示 二、源码分享 hoverToolboxWidget.h #ifndef HOVERTOOLBOXWIDGET_H #define HOVERTOOLBOXWIDGET_H#include <QWidget> #include <QMouseEvent> #include <QPropertyAnimation> #include <QStyleOption> #include <QPainter>namespa…

线夹金具测温在线监测装置:电力设备安全运行的“隐形卫士”

在电网系统中&#xff0c;线夹金具是连接导线与输电塔架的关键部件&#xff0c;其运行状态直接影响电力传输的稳定性。传统人工巡检方式存在效率低、盲区多、数据滞后等问题&#xff0c;而线夹金具测温在线监测装置的普及&#xff0c;正为电力设备运维带来革新。 一、工作原理&…

《TCP/IP 详解 卷1:协议》第4章:地址解析协议

ARP 协议 地址解析协议&#xff08;ARP, Address Resolution Protocol&#xff09;是IPv4协议栈中一个关键的组成部分&#xff0c;用于在网络层的IP地址与数据链路层的硬件地址&#xff08;如MAC地址&#xff09;之间建立映射关系。它的主要任务是&#xff1a; 将32位的IPv4地…

Windows下运行Redis并设置为开机自启的服务

下载Redis-Windows 点击redis-windows-7.4.0下载链接下载Redis 解压之后得到如下文件 右键install_redis.cmd文件&#xff0c;选择在记事本中编辑。 将这里改为redis.windows.conf后保存&#xff0c;退出记事本&#xff0c;右键后选择以管理员身份运行。 在任务管理器中能够…

网络编程之网络基础

基础理论&#xff1a;IP、子网掩码、端口号、字节序、网络基础模型、传输协议 socket&#xff1a;TCP、UDP、广播、组播、抓包工具的使用、协议头、并发服务器 Modbus协议 、HTTP协议、HTML、 分析服务器 源码、数据库 一、认识网络 网络&#xff1a;实现多设备通信 二、IP地址…

Spring AI(11)——SSE传输的MCP服务端

WebMVC的服务器传输 支持SSE&#xff08;Server-Sent Events&#xff09; 基于 Spring MVC 的服务器传输和可选的STDIO运输 导入jar <dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-server-webmvc</a…

计算机网络备忘录

计算机网络 - 网络互联与互联网 计算机网络重点学习本章&#xff0c;属于核心知识 包含网络层和传输层 的 相关协议 计算机网络层次重点掌握网络层与传输层。其中网络层主要是IP协议&#xff0c;解决主机-主机通信&#xff0c;传输层主要是TCP/UDP 协议&#xff0c;解决应用-…

Spring Boot论文翻译防丢失 From船长cap

本文内容 微服务 微服务风格的特性组件化&#xff08;Componentization &#xff09;与服务&#xff08;Services&#xff09;围绕业务功能的组织产品不是项目强化终端及弱化通道分散治理分散数据管理基础设施自动化容错性设计设计改进 微服务是未来吗其它 微服务系统多大微…

NuxtJS入门指南:环境安装及报错解决

在学习NuxtJS的过程中&#xff0c;正确的安装环境是非常重要的一步。然而&#xff0c;有时候在安装过程中会遇到一些问题&#xff0c;比如使用corepack安装pnpm时出现的错误。本文将详细介绍如何安装NuxtJS以及解决上述安装过程中遇到的问题。 Nuxt.js简介 Nuxt.js是一个强大的…

贪心算法应用:集合划分问题详解

贪心算法与集合划分问题详解 集合划分问题是组合优化中的经典问题&#xff0c;其核心目标是将元素集合划分为若干满足特定条件的子集。本文将深入探讨贪心算法在集合划分中的应用&#xff0c;涵盖算法原理、适用场景、Java实现细节及优化策略。 一、集合划分问题定义 1.1 基础…

数论~~~

质数 质数Miller-Rabin算法质因子分解质数筛埃氏筛欧拉筛如果只是计数&#xff0c;埃氏筛改进 快速幂乘法快速幂矩阵快速幂1维k阶实战(提醒&#xff1a;最好在mul函数中作乘法时加上&#xff08;long long&#xff09;的强制类型转换 &#xff0c;或者全部数组换成long long&am…

web第十次课后作业--Mybatis的增删改查

&#xff08;一&#xff09;删除操作 功能&#xff1a;根据主键删除数据 SQL 语句 -- 删除id17的数据 delete from emp where id 17;Mybatis 框架让程序员更关注于 SQL 语句 接口方法 Mapper public interface EmpMapper {//Delete("delete from emp where id 17&qu…

贪心算法应用:集合覆盖问题详解

贪心算法与集合覆盖问题详解 贪心算法在组合优化问题中展现出独特优势&#xff0c;集合覆盖问题&#xff08;Set Cover Problem&#xff09;是其中的经典案例。本文将用2万字全面解析贪心算法在集合覆盖/划分中的应用&#xff0c;涵盖算法原理、正确性分析、Java实现、复杂度证…

【知识点】第7章:文件和数据格式化

文章目录 知识点整理文件概述文件的打开和关闭文件的读操作文件的写操作 练习题填空题选择题​​ 知识点整理 文件概述 文件是一个存储在辅助存储器上的数据序列&#xff0c;可以包含任何数据内容。概念上&#xff0c;文件是数据的集合和抽象&#xff0c;类似地&#xff0c;函…

NetSuite Bundle - Dashboard Refresh

儿童节快乐&#xff01; 今朝发一个Bundle&#xff0c;解决一个NetSuite Dashboard的老问题。出于性能上的考虑&#xff0c;NetSuite的Dashboard中的Portlet&#xff0c;只能逐一手工刷新。有人基于浏览器做了插件&#xff0c;可以进行自动刷新。但是在我们做项目部署时&#…

智慧赋能:移动充电桩的能源供给革命与便捷服务升级

在城市化进程加速与新能源汽车普及的双重推动下&#xff0c;移动充电桩正成为能源供给领域的一场革命。传统固定充电设施受限于布局与效率&#xff0c;难以满足用户即时、灵活的充电需求&#xff0c;而移动充电桩通过技术创新与服务升级&#xff0c;打破了时空壁垒&#xff0c;…

斐波那契数列------矩阵幂法

斐波那契数列 斐波拉楔数是我们在学递归的使用看到的题目&#xff0c;但递归法是比较慢的&#xff0c;后面我们用循环递进来写的&#xff0c;但今天我有遇到了新的方法—— 矩阵幂法&#xff08;线性代数的知识点&#xff09;。 矩阵幂法&#xff1a; F11*F10*F2; F20*F11*…

【Web应用】若依框架:基础篇21二次开发-页面调整

文章目录 ⭐前言⭐一、课程讲解⭐二、怎样选择设计模式&#xff1f;&#x1f31f;1、寻找合适的对象✨1) ⭐三、怎样使用设计模式&#xff1f;&#x1f31f;1、寻找合适的对象✨1) ⭐总结 标题详情作者JosieBook头衔CSDN博客专家资格、阿里云社区专家博主、软件设计工程师博客内…

【 java 基础知识 第一篇 】

目录 1.概念 1.1.java的特定有哪些&#xff1f; 1.2.java有哪些优势哪些劣势&#xff1f; 1.3.java为什么可以跨平台&#xff1f; 1.4JVM,JDK,JRE它们有什么区别&#xff1f; 1.5.编译型语言与解释型语言的区别&#xff1f; 2.数据类型 2.1.long与int类型可以互转吗&…