Go-知识测试-模糊测试

Go-知识测试-模糊测试

  • 1. 定义
  • 2. 例子
  • 3. 数据结构
  • 4. tesing.F.Add
  • 5. 模糊测试的执行
  • 6. testing.InternalFuzzTarget
  • 7. testing.runFuzzing
  • 8. testing.fRunner
  • 9. FuzzXyz
  • 10. RunFuzzWorker
  • 11. CoordinateFuzzing
  • 12. 总结

建议先看:https://blog.csdn.net/a18792721831/article/details/140062769

Go-知识测试-工作机制

1. 定义

模糊测试(Fuzzing)是一种通过构造随机数据对代码进行测试的测试方法,相比于单元测试,
它能提供更为全面的测试覆盖,从而找出代码中的潜在漏洞。
从1.18开始,Go开始正式支持模糊测试。
模糊测试要保证测试文件以_test.go结尾。
测试方法必须以FuzzXxx开头。
模糊测试方法必须以*testing.F作为参数。

2. 例子

假设有个函数,根据输入内容,将输入进行翻转然后在和输入拼接,从而返回一个回文串(不一定是严格意义下的回文串)
函数如下:

func PalindromeStr(in string) string {
	b := []byte(in)
	for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {
		b[i], b[j] = b[j], b[i]
	}
	return in + string(b)
}

接着使用单元测试

func TestPalindromeStr(t *testing.T) {
	testCase := []struct{ in, out string }{
		{"abc", "abccba"},
		{"abcdef", "abcdeffedcba"},
		{"abcdefg", "abcdefggfedcba"},
		{" ", "  "},
	}
	for _, c := range testCase {
		o := PalindromeStr(c.in)
		if o != c.out {
			t.Error("Not equal", c.out, "got:", o)
		}
	}
}

使用go test -v 执行示例测试,-v 表示控制台输出结果
在这里插入图片描述

接着使用模糊测试

func FuzzPalindromeStr(f *testing.F) {
	testCase := []string{"abc", "def", " ", "a", "aaa", "aaaaaaaaaaaaaaaaaaaa"}
    for _, c := range testCase {
        f.Add(c) // 输入测试种子
    }
    f.Fuzz(func(t *testing.T, a string) {
        b := PalindromeStr(a)
		// 返回结果进行判断,回文串的规则就是第一个字符和最后一个字符相同,依次类推
        for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {
            if b[i] != b[j] {
                t.Error("Not palindrome")
            }
        }
    })
}

使用go test -fuzz=Fuzz -fuzztime=100s启动模糊测试,-fuzz表示执行模糊测试,-fuzztime表示持续时间
在这里插入图片描述

发现执行了100s,也没法问题。
那么我们就自动构造一个错误,如果是utf-8字符,返回回文串,否则返回输入内容,模拟异常逻辑:

func PalindromeStr(in string) string {
	b := []byte(in)
	if !utf8.Valid(b) {
		return in
	}
	for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {
		b[i], b[j] = b[j], b[i]
	}
	return in + string(b)
}

因为单元测试中没有中文字符,所以单元测试通过,但是模糊测试呢:
在这里插入图片描述

报错了,同时testdata目录中有相应的输入和输出
在这里插入图片描述

非utf8字符串,触发了错误逻辑

3. 数据结构

由于模糊测试可以覆盖人类经常忽略的边界用例,因此模糊测试对于发现安全漏洞特别有价值。
模糊测试的结构如下:
在这里插入图片描述

看起来很像单元测试的扩展。
一个模糊测试可以分为两部分,一是通过 f.Add 添加随机种子,二是通过 f.Fuzz 函数开始随机测试。标记测试结果的方法与之前的单元测试是通用的。
模糊测试的testing.F结构:
go在1.18中,在testing的包中增加了fuzz.go文件,支持模糊测试:

type F struct {
	common // 通用测试结构,更多见 https://blog.csdn.net/a18792721831/article/details/140062769
	fuzzContext *fuzzContext // 与 testContext 类似,用于控制执行
	testContext *testContext
	inFuzzFn bool // 标记 fuzz 是否在运行中
	corpus []corpusEntry // 种子,语料库
	result     fuzzResult // 模糊测试结果
	fuzzCalled bool // 是否启动
}

通用测试结构 common 提供了诸如标记测试结果的能力,而增加的 corpus 则用于保存通过 f.Add 添加的种子和测试过程中生成的随机输入。
每次执行 f.Add 都会生成一个 corpusEntry 对象,然后加入 corpus 语料库中。
corpusEntry 结构用于保存待测函数的所有输入:

type corpusEntry = struct {
	Parent     string
	Path       string
	Data       []byte
	Values     []any // Values 要与待测函数索旭耀的参数完全一致
	Generation int
	IsSeed     bool
}

f.Add 每次添加的种子个数需要与待测函数所需要的参数完全一致,因为测试执行时,每次取出一组种子作为函数的入参。

4. tesing.F.Add

func (f *F) Add(args ...any) {
    // 将输入的参数加入到数组中
	var values []any
	for i := range args {
	    // 模糊测试只能支持基本数据类型,对于复杂类型是不支持的
		if t := reflect.TypeOf(args[i]); !supportedTypes[t] {
			panic(fmt.Sprintf("testing: unsupported type to Add %v", t))
		}
		values = append(values, args[i])
	}
	f.corpus = append(f.corpus, corpusEntry{Values: values, IsSeed: true, Path: fmt.Sprintf("seed#%d", len(f.corpus))})
}

支持模糊测试的参数类型:

var supportedTypes = map[reflect.Type]bool{
	reflect.TypeOf(([]byte)("")):  true,
	reflect.TypeOf((string)("")):  true,
	reflect.TypeOf((bool)(false)): true,
	reflect.TypeOf((byte)(0)):     true,
	reflect.TypeOf((rune)(0)):     true,
	reflect.TypeOf((float32)(0)):  true,
	reflect.TypeOf((float64)(0)):  true,
	reflect.TypeOf((int)(0)):      true,
	reflect.TypeOf((int8)(0)):     true,
	reflect.TypeOf((int16)(0)):    true,
	reflect.TypeOf((int32)(0)):    true,
	reflect.TypeOf((int64)(0)):    true,
	reflect.TypeOf((uint)(0)):     true,
	reflect.TypeOf((uint8)(0)):    true,
	reflect.TypeOf((uint16)(0)):   true,
	reflect.TypeOf((uint32)(0)):   true,
	reflect.TypeOf((uint64)(0)):   true,
}

除了这些之外的类型都不支持。

5. 模糊测试的执行

src/tesing/fuzz.goinitFuzzFlags中定义了模糊测试的参数:

func initFuzzFlags() {
	matchFuzz = flag.String("test.fuzz", "", "run the fuzz test matching `regexp`")
	flag.Var(&fuzzDuration, "test.fuzztime", "time to spend fuzzing; default is to run indefinitely")
	flag.Var(&minimizeDuration, "test.fuzzminimizetime", "time to spend minimizing a value after finding a failing input")

	fuzzCacheDir = flag.String("test.fuzzcachedir", "", "directory where interesting fuzzing inputs are stored (for use only by cmd/go)")
	isFuzzWorker = flag.Bool("test.fuzzworker", false, "coordinate with the parent process to fuzz random values (for use only by cmd/go)")
}

首先使用-fuzz=reg触发模糊测试,-fuzztime=30s指定模糊测试持续的时间,如果不指定,则一直运行。
-fuzzminimizetime最小失败时间,默认一分钟,-fuzzcachedir缓存目录,默认是命令执行目录,fuzzworker工作目录,默认是命令执行目录。

6. testing.InternalFuzzTarget

testing.M中,对于单元测试,示例测试和性能测试,都有一个内部类型用于存储编译生成的执行参数。模糊测试也有:
在这里插入图片描述

在1.18中三种内部类型增加成4种了。
在编译的时候,load操作也增加了 Fuzz开头的模糊测试函数
在这里插入图片描述

在渲染测试的main入口中,也增加了模糊测试的模板
在这里插入图片描述

在testing.M.Run中,增加了模糊测试的支持
在这里插入图片描述

InternalFuzzTarget的结构:

type InternalFuzzTarget struct {
	Name string
	Fn   func(f *F)
}

很简单,和单元测试等的结构非常类似,name和对应的func,func 的参数是 *testing.F

7. testing.runFuzzing

在runFuzzing中首先对全部的模糊测试进行匹配,找到本次期望执行的模糊测试case
在这里插入图片描述

接着构造testing.F对象,调用testing.fRunner执行case
在这里插入图片描述

8. testing.fRunner

在testing.fRunner中启动执行,类似于单元测试的 testing.tRunner。
在这里插入图片描述

性能测试是 testing.runN
示例测试是 testing.runExample
单元测试是 testing.tRunner

第一个defer函数主要处理这几个事情:失败后资源清理,保证测试报告完成,失败退出,等待子测试完成,成功输出报告。
第二个defer函数是等待所有的子测试完成后,发送信号,表示子测试结束。

9. FuzzXyz

接着回到模糊测试中:

func FuzzPalindromeStr(f *testing.F) {
	testCase := []string{"abc", "def", " ", "a", "aaa", "你好"}
	for _, c := range testCase {
		f.Add(c) // 输入测试种子
	}
	f.Fuzz(func(t *testing.T, a string) {
		b := PalindromeStr(a)
		// 返回结果进行判断,回文串的规则就是第一个字符和最后一个字符相同,依次类推
		for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {
			if b[i] != b[j] {
				t.Error("Not palindrome")
			}
		}
	})
}

模糊测试可以认为是两部分,第一部分是输入测试种子,第二部分是判决模糊的参数执行是否成功。
在testing.F.Add中,将参数种子放到了testing.F.corpus里面,并且要求输入的种子参数的数量,每次Add的时候,必须和被测试方法的入参一致。
在第二部分的Fuzz中,首先对入参进行了校验:
在这里插入图片描述

入参是一个func类型的参数,并且第一个参数是*testing.T的参数,后面是可变参数。
第一个*testing.T主要是复用了单元测试的测试管理能力,比如报告输出,成功失败的标记等等。
后面的可变参数则是被模糊测试的函数入参列表。
接着对可变参数列表进行类型判断,只有基本类型才能模糊测试,如果入参中存在复杂类型,那么是无法模糊测试的。
在这里插入图片描述

接下来就是模糊的核心逻辑了,如何根据输入的参数种子,派生更多的入参用例:
在这里插入图片描述

模糊测试的goroutine分为三种
在这里插入图片描述

这三种的含义先存疑。
在CheckCorpus中,对入参种子和可变参数进行校验,确保种子数组中每一组都符合要求。
在ReadCorpus中,则是随机取出本次执行的参数,如果是指定fuzz的目录和id,那么会使用指定的目录下的指定参数去执行
在这里插入图片描述

ReadCorpus调用了internal的fuzz实现
在这里插入图片描述

在ReadCorpus中调用了readCorpusData
在这里插入图片描述

不过上面都是执行特定的模糊case 。
在前面已知模糊测试的goroutine中有三种:

const (
	seedCorpusOnly fuzzMode = iota
	fuzzCoordinator
	fuzzWorker
)

第一种 seedCorpusOnly 是 testing.runFuzzTests 中创建的,由testing.M调用
在这里插入图片描述

第二种 fuzzCoordinator 是 默认的,如果执行的go命令中没有指定 test.fuzzworker , 默认是 false
在 testing.runFuzzing 中创建的
在这里插入图片描述

第三种 fuzzWorker 是由 命令行参数指定的。

在这里插入图片描述

根据这里的逻辑,基本上可以看出,seedCorpusOnly 是读取指定模糊case, fuzzCoordinator是生成模糊case,fuzzWorker是执行case。
在这里插入图片描述

接着创建一个 testing.T 的对象,然后调用 testing.tRunner 执行case 。
在这里插入图片描述

testing.tRunner执行case的参数是 corpusEntry 类型的输入。

也就是说,对于模糊测试,会先直接调用测试种子执行,然后会根据执行情况,在进行随机参数。

如果是 fuzzCoordinator 类型的,那么执行 CoordinateFuzzing
在这里插入图片描述

如果是 fuzzWorker ,执行 RunFuzzWorker
在这里插入图片描述

如果是 seedCorpusOnly ,执行 run func,相当于直接用测试种子运行
在这里插入图片描述

在 fuzzWorker中,对于输出做了重定向。

10. RunFuzzWorker

RunFuzzWorker方法是在internal中实现的
在这里插入图片描述

如果一个case经过了10还没有被执行,就认为是饿死了
在serve方法中调用了workerServer.Fuzz 方法
在这里插入图片描述

并且是持续性调用的
在workerServer.fuzz中进行模糊测试
在workerServer.fuzz中,第一次调用直接使用种子
在这里插入图片描述

接着就是持续性测试了
在这里插入图片描述

在 mutator.mutate 中根据种子进行随机
在这里插入图片描述

会对一次随机的多个参数,随机选择一个参数,然后对这个参数进行随机
比如对于整型,会随机加或者减一个数
在这里插入图片描述

对于字符串,对字节码随机加减
在这里插入图片描述

也就是说,如果你的种子里面有中文,才会随机中文。

contains
accepts
calls
calls
passes
returns
TestDeps
RunFuzzWorker
fn
workerServer.fuzz
mutator.mutate
fuzz.CorpusEntry
error

11. CoordinateFuzzing

CoordinateFuzzing方法在internal中实现的
在这里插入图片描述

首先会对并发数,缓存目录,日志等进行初始化
在这里插入图片描述

根据并发数,创建多个 worker 执行模糊测试
在这里插入图片描述

在coordinate中也是持续测试
在这里插入图片描述

如果没有启动,那么就调用启动初始化等操作,如果收到了退出信号,那么就退出
如果随机输入已经生成,那么就使用随机输入调用
在这里插入图片描述

接着是for-select进行持续性测试,除非模糊测试失败,或者执行模糊测试的时候,有设置超时时间,或者主动退出等
在这里插入图片描述

在workerClient.fuzz中执行
在这里插入图片描述

也是调用 mutator.mutate 进行随机
在这里插入图片描述

同时,在调用FuzzXyz后,会记录case的执行情况,用于分析执行的覆盖率等等
在这里插入图片描述

12. 总结

Go 1.18 的 Fuzz 测试使用了一种称为 “coverage-guided fuzzing” 的技术来生成随机输入。这种技术的基本思想是通过监视被测试代码的覆盖率来引导输入的生成。

具体来说,Fuzz 测试首先使用你提供的种子值(seed values)来运行测试。然后,它会监视这些测试运行过程中哪些代码被执行了,以及输入值如何影响代码的执行路径。

接着,Fuzz 测试会尝试修改种子值或者组合种子值,生成新的输入,以尝试覆盖更多的代码路径。例如,如果你的种子值是字符串,Fuzz 测试可能会改变字符串的长度,添加、删除或修改字符,等等。

如果新的输入导致了更多的代码被执行,或者触发了新的代码路径,那么这个输入就会被保存下来,用作后续测试的种子值。这样,Fuzz 测试就可以逐渐 “学习” 如何生成能够触发更多代码路径的输入。

这种方法可以有效地发现一些难以预见的边界情况,特别是那些可能导致程序崩溃或者行为异常的情况。

需要注意的是,虽然 Fuzz 测试可以自动生成大量的输入,但是它并不能保证完全覆盖所有可能的输入。因此,你仍然需要编写单元测试和集成测试,以确保你的代码在预期的输入下能够正确工作。

Coverage-Guided Fuzzing 相关论文和链接

Coverage-guided fuzzing 是一种基于代码覆盖率的模糊测试技术,通过生成输入数据并监控代码覆盖率来发现潜在的错误和漏洞。这种方法的核心思想是通过最大化代码覆盖率来提高测试的有效性。

  1. “American Fuzzy Lop (AFL)”
    AFL 是一种流行的 coverage-guided fuzzing 工具,由 Michał Zalewski 开发。虽然 AFL 本身不是一篇论文,但它的设计和实现对该领域有着重要影响。
  • 链接: AFL GitHub Repository
  1. “Fuzzing: Brute Force Vulnerability Discovery”
    这篇论文由 Michael Sutton, Adam Greene, 和 Pedram Amini 撰写,详细介绍了模糊测试的基本概念和技术,包括 coverage-guided fuzzing。
  • 链接: Fuzzing: Brute Force Vulnerability Discovery
  1. “Coverage-based Greybox Fuzzing as Markov Chain”
    这篇论文由 Marcel Böhme, Van-Thuan Pham, 和 Abhik Roychoudhury 撰写,提出了一种基于覆盖率的灰盒模糊测试方法,并将其建模为马尔可夫链。
  • 链接: Coverage-based Greybox Fuzzing as Markov Chain
  1. “AFLFast: A Framework for Extremely Fast Fuzzing”
    这篇论文由 Marcel Böhme, Van-Thuan Pham, Manh-Dung Nguyen, 和 Abhik Roychoudhury 撰写,介绍了 AFLFast,这是一种改进的 AFL 版本,通过优化输入生成策略来提高模糊测试的效率。
  • 链接: AFLFast: A Framework for Extremely Fast Fuzzing
  1. “LibFuzzer: A Library for Coverage-Guided Fuzz Testing”
    LibFuzzer 是 LLVM 项目的一部分,提供了一个用于覆盖率引导模糊测试的库。虽然没有正式的论文,但其设计和实现文档非常详细。
  • 链接: LibFuzzer Documentation
  1. “Fuzzing with Code Fragments”
    这篇论文由 Patrice Godefroid, Hila Peleg, 和 Rishabh Singh 撰写,提出了一种基于代码片段的模糊测试方法,通过组合代码片段来生成新的测试输入。
  • 链接: Fuzzing with Code Fragments
  1. “Evaluating Fuzz Testing”
    这篇论文由 Marcel Böhme, Van-Thuan Pham, Manh-Dung Nguyen, 和 Abhik Roychoudhury 撰写,评估了不同模糊测试工具和技术的有效性,包括 coverage-guided fuzzing。
  • 链接: Evaluating Fuzz Testing
  1. “Fuzzing: Art, Science, and Engineering”
    这篇论文由 Patrice Godefroid 撰写,全面介绍了模糊测试的艺术、科学和工程,包括 coverage-guided fuzzing 的技术细节和应用。
  • 链接: Fuzzing: Art, Science, and Engineering

这些论文和资源提供了关于 coverage-guided fuzzing 的深入理解和最新研究成果。通过阅读这些文献,你可以更好地理解这种技术的原理、实现和应用。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智能家居开发新进展:乐鑫 ESP-ZeroCode 与亚马逊 ACK for Matter 实现集成

日前&#xff0c;乐鑫 ESP-ZeroCode 与亚马逊 Alexa Connect Kit (ACK) for Matter 实现了集成。这对智能家居设备制造商来说是一项重大进展。开发人员无需编写固件或开发移动应用程序&#xff0c;即可轻松设计符合 Matter 标准的产品。不仅如此&#xff0c;开发者还可以在短短…

Python(四)---序列

文章目录 前言1.列表1.1.列表简介1.2.列表的创建1.2.1.基本方式[]1.2.2.list()方法1.2.3.range()创建整数列表1.2.4.推导式生成列表 1.3. 列表各种函数的使用1.3.1.增加元素1.3.2.删除元素1.3.3.元素的访问和计数1.3.4.切片1.3.5.列表的排序 1.4.二维列表 2.元组2.1.元组的简介…

内网安全:域内信息探测

1.域内基本信息收集 2.NET命令详解 3.内网主要使用的域收集方法 4.查找域控制器的方法 5.查询域内用户的基本信息 6.定位域管 7.powershell命令和定位敏感信息 1.域内基本信息收集&#xff1a; 四种情况&#xff1a; 1.本地用户&#xff1a;user 2.本地管理员用户&#x…

短链接day4

短链接管理 创建短链接数据库表 URI、URL和URN区别 : URI 指的是一个资源 &#xff1b;URL 用地址定位一个资源&#xff1b; URN 用名称定位一个资源。 举个例子&#xff1a; 去寻找一个具体的人&#xff08;URI&#xff09;&#xff1b;如果用地址&#xff1a;XX省XX市XX区…

使用 Google 的 Generative AI 服务时,请求没有包含足够的认证范围(scopes)

题意&#xff1a; Google generativeai 403 Request had insufficient authentication scopes. [reason: "ACCESS_TOKEN_SCOPE_INSUFFICIENT" 问题背景&#xff1a; I have tried the simple POC for generativeai on its own to do generate_content and it works…

【初阶数据结构】2.顺序表

文章目录 1.线性表2.顺序表2.1 概念与结构2.2 分类2.2.1 静态顺序表2.2.2 动态顺序表 2.3 动态顺序表的实现2.4 顺序表算法题2.4.1 移除元素2.4.2 删除有序数组中的重复项2.4.3 合并两个有序数组 2.5 顺序表问题与思考 1.线性表 线性表&#xff08;linear list&#xff09;是n…

JavaFx+MySql学生管理系统

前言: 上个月学习了javafx和mysql数据库,于是写了一个学生管理系统,因为上个月在复习并且有一些事情,比较忙,所以没有更新博客了,这个项目页面虽然看着有点简陋了,但是大致内容还是比较简单的,于是现在跟大家分享一下我的学生管理系统,希望对这方面有兴趣的同学提供一些帮助 &a…

19185 01背包问题

解决这个问题的关键是使用动态规划的方法。我们可以创建一个二维数组dp[i][j]&#xff0c;其中i表示考虑前i件物品&#xff0c;j表示背包的容量。dp[i][j]的值表示在考虑前i件物品&#xff0c;且背包容量为j时能获得的最大价值。 ### 算法步骤 1. 初始化一个二维数组dp&#x…

Qt常用基础控件总结—容器部件(QGroupBox类)

五、容器部件 按钮框控件QDialogButtonBox 类(很少用) 按钮组控件QButtonGroup 类(很少用) 组框控件QGroupBox 类 QGroupBox 类介绍 QGroupBox(组框),直接继承自 QWidget 类,因此使用该类创建的对象,可作为窗口使用,组框在外观上是可见的。 QGroupBox 类(组框),…

数据平滑处理(部分)

一、 移动平均&#xff08;Moving Average&#xff09; 是一种最简单的数据平滑方法&#xff0c;用于平滑时间序列数据。它通过计算一定窗口内数据点的平均值来减少噪音&#xff0c;同时保留数据的趋势。移动平均包括简单移动平均&#xff08;SMA&#xff09;或指数加权移动平均…

【爬虫】爬虫基础

目录 一、Http响应与请求1、Http请求2、Http响应3、状态码 二、Requests库1、发起GET请求2、发起POST请求3、处理请求头 三、BeautifulSoup库1、解析HTML文档2、查找和提取数据Ⅰ、查找单个元素Ⅱ、查找所有元素Ⅲ、使用CSS选择器Ⅳ、获取元素属性 四、爬取豆瓣电影榜 一、Http…

YOLOv10训练自己的数据集(交通标志检测)

YOLOv10训练自己的数据集&#xff08;交通标志检测&#xff09; 前言相关介绍前提条件实验环境安装环境项目地址LinuxWindows 使用YOLOv10训练自己的数据集进行交通标志检测准备数据进行训练进行预测进行验证 参考文献 前言 由于本人水平有限&#xff0c;难免出现错漏&#xff…

【Linux】日志

日志是记录软件运行过程中发生的事件的一种手段&#xff0c;通常包含以下内容&#xff1a; 时间戳&#xff1a;记录日志条目创建的确切时间。这对于追踪事件发生的时间顺序至关重要。日志级别&#xff1a;表示日志信息的严重性或重要性&#xff0c;常见的级别包括 DEBUG、INFO…

RisingWave 用例:流式 ETL、实时分析、事件驱动应用

RisingWave 非常适合以下类别的用例。 流式 ETL实时分析事件驱动应用 流式 ETL 是实时分析和事件驱动应用的基础。实时分析通过引入数据看板&#xff0c;扩展了流式 ETL&#xff0c;而事件驱动应用则在实时分析的基础上增加了逻辑&#xff0c;以评估条件是否触发后续行动。 …

【测开能力提升-fastapi框架】fastapi模版引擎简单使用

1.6 通过模版引擎返回HTM页面 import uvicorn from fastapi import FastAPI, Request from fastapi.templating import Jinja2Templatesapp FastAPI()# 初始化模版引擎存放位置 templates Jinja2Templates(directory"templates")app.get("/") async def…

2024年西安铁一中集训DAY1---- 杂题选讲

文章目录 牛客练习赛125 E 联谊活动&#xff08;枚举&#xff0c;分讨&#xff09;牛客练习赛125 F 玻璃弹珠&#xff08;类莫队&#xff0c;离线询问&#xff0c;数据结构&#xff09;2024ccpc长春邀请赛 D Parallel Lines&#xff08;随机化&#xff09;2024ccpc长春邀请赛 E…

分布式应用系统设计:即时消息系统

即时消息(IM)系统&#xff0c;涉及&#xff1a;站内消息系统 组件如下&#xff1b; 客户端&#xff1a; WEB页面&#xff0c;IM桌面客户端。通过WebSocket 跟ChatService后端服务连接 Chat Service&#xff1a; 提供WebSocket接口&#xff0c;并保持跟“客户端”状态的维护。…

彻底解决找不到d3dcompiler_43.dll问题,总结几种有效的方法

运行软件时提示找不到d3dcompiler_43.dll无法继续执行代码&#xff0c;如何解决&#xff1f;解决这个问题的方法有很多&#xff0c;但具体问题需要具体分析&#xff0c;有些方法可能并不适用于解决d3dcompiler_43.dll的问题。因此&#xff0c;需要根据实际情况来选择合适的方法…

8627 数独

为了判断数独解是否合法&#xff0c;我们需要遵循以下步骤&#xff1a; 1. **检查每一行**&#xff1a;确保1到9每个数字在每一行中只出现一次。 2. **检查每一列**&#xff1a;确保1到9每个数字在每一列中只出现一次。 3. **检查每个3x3的宫**&#xff1a;确保1到9每个数字在…

模式物种葡萄基因组(T2T)--文献精读29

The complete reference genome for grapevine (Vitis vinifera L.) genetics and breeding 葡萄&#xff08;Vitis vinifera L.&#xff09;遗传学和育种的完整参考基因组 摘要 葡萄是全球最具经济重要性的作物之一。然而&#xff0c;以往版本的葡萄参考基因组通常由成千上万…