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

golang入门笔记——测试

测试类型:

在这里插入图片描述

单元测试:

在这里插入图片描述

规则:

1.所有测试文件以_test.go结尾
2.func Testxxx(*testing.T)
3.初始化逻辑放到TestMain中

运行:

go test [flags][packages]

Go语言中的测试依赖go test命令。
go test命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录内,所有以_test.go为后缀名的源代码文件都是go test测试的一部分,不会被go build编译到最终的可执行文件中
测试函数:
每个测试函数必须导入testing包,测试函数名必须以Test开头,测试函数的基本格式(签名)如下:
在这里插入图片描述

覆盖率:

显示代码覆盖率的命令

go test [flags][packages] --cover

1.一般覆盖率:50%~60%,较高覆盖率80%+
2.测试分支相互独立、全面覆盖
3.测试单元粒度足够小,函数单一职责

依赖:

在这里插入图片描述

Mock

1.快速mock函数:
为一个函数打桩
为一个方法打桩

monkey打桩实例:
在这里插入图片描述

代码实例:

package split_stringimport ("strings"
)//切割字符串
//example:
//abc,b=>[a c]
func Split(str string, sep string) []string {var ret=make([]string,0,strings.Count(str,sep)+1)//预先分配好内存index := strings.Index(str, sep)for index >= 0 {ret = append(ret, str[:index])str = str[index+len(sep):]index = strings.Index(str, sep)}if str != "" {ret = append(ret, str)}return ret
}func TestMain(m *testing.M){
//测试前:数据装载、配置初始化等前置工作code:=m.Run()//测试后,释放资源等收尾工作
os.Exist(code)
}
package split_stringimport ("reflect""testing"
)func TestSplit(t *testing.T) {ret := Split("babcbef", "b")want := []string{"", "a", "c", "ef"}if !reflect.DeepEqual(ret, want) {//测试用例失败了t.Errorf("want:%v but got:%v\n", want, ret)}
} //测试用例一func Test2Split(t *testing.T) {ret := Split("a:b:c", ":")want := []string{"a", "b", "c"}if !reflect.DeepEqual(ret, want) {t.Fatalf("want:%v but get:%v\n", want, ret)}
} //测试用例二//一次测试多个
func Test3Split(t *testing.T) {type testCase struct {str  stringsep  stringwant []string}testGroup := []testCase{testCase{"babcbef", "b", []string{"", "a", "c", "ef"}},testCase{"a:b:c", ":", []string{"a", "b", "c"}},testCase{"abcdef", "bc", []string{"a", "def"}},testCase{"沙河有沙又有河", "有", []string{"沙河", "沙又", "河"}},}for _, test := range testGroup {got := Split(test.str, test.sep)if !reflect.DeepEqual(got, test.want) {t.Fatalf("want:%#v got:%#v\n", test.want, got)}}
}//子测试
func Test4Split(t *testing.T) {if testing.Short(){t.Skip("short模式下会跳过测试用例")}type testCase struct {str  stringsep  stringwant []string}testGroup := map[string]testCase{"case 1": testCase{"babcbef", "b", []string{"", "a", "c", "ef"}},"case 2": testCase{"a:b:c", ":", []string{"a", "b", "c"}},"case 3": testCase{"abcdef", "bc", []string{"a", "def"}},"case 4": testCase{"沙河有沙又有河", "有", []string{"沙河", "沙又", "河"}},}for name, test := range testGroup {t.Run(name, func(t *testing.T) {t.Parallel()	//将每个测试用例标记为能够彼此并行运行got := Split(test.str, test.sep)if !reflect.DeepEqual(got, test.want) {t.Fatalf("want:%#v got:%#v\n", test.want, got)}})}
} //会把每个map中的样例试结果都打印出来
func TestMain(m *testing.M) {//测试的入口函数m.Run()//测试开始
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

//在split_string终端下
go test //进行测试
go test -v//查看测试细节
go test -cover//语句覆盖率
go test -cover -coverprofile=cover.out//将测试结果生成文件
go tool -cover -html=cover.out  //生成html文件来分析cover.out,绿色覆盖,红色未覆盖
//好的测试,测试函数覆盖率:100%  测试覆盖率:60%
go test -run=Sep -v  //只运行测试函数名中带有Sep的测试
go test -short //会跳过某些耗时的测试用例

基准测试:

func BenchmarkSplit(b *testing.B){for i:=0;i<b.N;i++{//N不是一个固定的数,是使Split跑够1秒钟的一个数Split("a:b:c:d:e",":")}
}
go test -bench=Split
//goos: windows windows平台
// goarch: amd64  amd64位
// pkg: test/split_string
// cpu: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
// BenchmarkSplit-12  12核   3869991    执行次数      307.2 ns/op 307.2ns/次
// PASS
// ok      test/split_string       1.539s
go test -bench=Split -benchmem //增加了查看对内存的申请情况

网络测试:

func TestHelloHandler(t *testing.T) {ln, err := net.Listen("tcp", "localhost:0")handleError(t, err)defer ln.Close()http.HandleFunc("/hello", HelloHandler)go http.Serve(ln, nil)resp, err := http.Get("http://" + ln.Addr().String() + "hello")handleError(t, err)defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)handleError(t, err)if string(body) != "hello world!" {t.Fatal("expected hello world,but got", string(body))}
}

1.优化代码,需要对当前代码分析
2.内置的测试框架提供了基准测试的能力

func BenchmarkSelect(b *testing.B) {InitServerIndex()b.ResetTimer() //定时器重置for i := 0; i < b.N; i++ {Select()}
}func BenchmarkSelectParallel(b *testing.B) {InitServerIndex()b.ResetTimer()b.RunParallel(func(pb *testing.PB) {for pb.Next() {Select()}})
}

SqlMock

mock的核心在于屏蔽上游细节,使用一些实现设定好的数据来模拟上游返回的数据
sqlmock就是在测试过程中,指定你期望(Expectations)执行的查询语句,以及假定的返回结果(WillReturnResult)

sqlmock库的安装:

go get github.com/DATA-DOG/go-sqlmock

sqlmock.New()返回一个标准的sql.DB结构体实例指针,这是一个数据库连接句柄。除此之外还返回了一个sqlmock.Sqlmock结构体实例

	db, mock, err := sqlmock.New()if err != nil {t.Errorf("create sqlmock fail")}defer db.Close()mock.ExpectExec(`sql sentence`).WithArgs(sqlmock.AnyArg()).WillReturnResult(sqlmock.NewResult(1, 1))//ExpectExec里的sql sentence为期望执行的sql语句//WithArgs代表执行该语句所要带的参数//sqlmock.AnyArg()代表任意参数//WillReturnResult里面代表假定的返回//sqlmock.NewResult(1,1)代表自增主键为1,1条影响结果

gorm使用sqlmock测试时的示例

db, mock, err := sqlmock.New()
if nil != err {t.Fatalf("Init sqlmock failed, err %v", err)
}
defer db.Close()gormDB, err := gorm.Open(mysql.New(mysql.Config{SkipInitializeWithVersion: true,Conn: db,}), &gorm.Config{})
if err!=nil {t.Fatalf("Init DB with sqlmock failed, err %v", err)
} else {if db, err := database.KnodiDB.DB(); nil != err {db.SetMaxIdleConns(10)db.SetMaxOpenConns(10)db.Ping()}
}

增删改查 sqlmock示例

main.go

package mainimport ("database/sql"_ "github.com/go-sql-driver/mysql"
)type User struct {Id       int64Username stringPassword string
}func recordStats(db *sql.DB, userID, productID int64) (err error) {tx, err := db.Begin()if err != nil {return}defer func() {switch err {case nil:err = tx.Commit()default:tx.Rollback()}}()if _, err = tx.Exec("UPDATE products SET views = views + 1"); err != nil {return}if _, err = tx.Exec("INSERT INTO product_viewers (user_id, product_id) VALUES (?, ?)", userID, productID); err != nil {return}return
}func recordQuery(db *sql.DB, userID int64) (user *User, err error) {row := db.QueryRow("SELECT * FROM user where id =?", userID)user = new(User)err = row.Scan(&user.Id, &user.Username, &user.Password)return
}func recordDelete(db *sql.DB, userID int64) (err error) {_, err = db.Exec("DELETE FROM user where id=?", userID)if err != nil {return}return
}func main() {// @NOTE: the real connection is not required for testsdb, err := sql.Open("mysql", "root@/blog")if err != nil {panic(err)}defer db.Close()if err = recordStats(db, 1 /*some user id*/, 5 /*some product id*/); err != nil {panic(err)}
}

main_test.go

package mainimport ("fmt""regexp""testing""github.com/DATA-DOG/go-sqlmock"
)// a successful case
func TestShouldUpdateStats(t *testing.T) {db, mock, err := sqlmock.New()if err != nil {t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)}defer db.Close()mock.ExpectBegin()mock.ExpectExec("UPDATE products").WillReturnResult(sqlmock.NewResult(1, 1))mock.ExpectExec("INSERT INTO product_viewers").WithArgs(2, 3).WillReturnResult(sqlmock.NewResult(1, 1))mock.ExpectCommit()// now we execute our methodif err = recordStats(db, 2, 3); err != nil {t.Errorf("error was not expected while updating stats: %s", err)}// we make sure that all expectations were metif err := mock.ExpectationsWereMet(); err != nil {t.Errorf("there were unfulfilled expectations: %s", err)}
}// a failing test case
func TestShouldRollbackStatUpdatesOnFailure(t *testing.T) {db, mock, err := sqlmock.New()if err != nil {t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)}defer db.Close()mock.ExpectBegin()mock.ExpectExec("UPDATE products").WillReturnResult(sqlmock.NewResult(1, 1))mock.ExpectExec("INSERT INTO product_viewers").WithArgs(2, 3).WillReturnError(fmt.Errorf("some error"))mock.ExpectRollback()// now we execute our methodif err = recordStats(db, 2, 3); err == nil {t.Errorf("was expecting an error, but there was none")}// we make sure that all expectations were metif err := mock.ExpectationsWereMet(); err != nil {t.Errorf("there were unfulfilled expectations: %s", err)}
}func TestQuery(t *testing.T) {userInfo := []string{"id","username","password",}db, mock, err := sqlmock.New()if err != nil {t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)}mock.ExpectQuery(regexp.QuoteMeta("SELECT * FROM user")).WithArgs(1).WillReturnRows(sqlmock.NewRows(userInfo).AddRow(1, "zyj", "123"))if err = recordStats(db, 2, 3); err == nil {t.Errorf("was expecting an error, but there was none")}user, err := recordQuery(db, 1)if err != nil || user == nil {t.Errorf("this is something wrong")}t.Log(user)
}func TestDelete(t *testing.T) {db, mock, err := sqlmock.New()if err != nil {t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)}mock.ExpectExec("DELETE FROM user").WithArgs(1).WillReturnResult(sqlmock.NewResult(1, 1))err = recordDelete(db, 1)if err != nil {t.Errorf("this is something wrong")}
}

ginkgo和gomega

1.在引入ginkgo和gomega的时候前面加.这样每次调用时就可以直接使用包中的方法函数了。
2.ginkgo使用Describe()来描述这段代码的行为,使用Context()来描述表达该行为是在不同的环境下执行,一个it就是一个spec即一个测试用例
3.ginkgo使用BeforeEach()来为specs设置状态,并使用It()来指定单个spec,也是一个测试用例,且执行每一个It模块前都会执行一次Describe的BeforeEach和AfterEach,以确保每个Specs都处于原始状态
4.JustBeforeEach()模块在所有BeforeEach()模块执行之后,It模块执行之前运行,BeforeSuit函数在所有Specs运行前执行,AfterSuite函数在所有Specs运行后执行,不论测试是否失败
5.使用Gomega中的Expect()函数来设置期望

package mainimport ("database/sql""fmt""regexp""sync""github.com/DATA-DOG/go-sqlmock". "github.com/onsi/ginkgo". "github.com/onsi/gomega"
)var _ = Describe("Record Test", func() {var (once     sync.Oncemock     sqlmock.Sqlmockdb       *sql.DBerr      erroruserInfo []string)BeforeEach(func() {once.Do(func() {db, mock, err = sqlmock.New()if err != nil {fmt.Println(err)}})userInfo = []string{"id","username","password",}})Context("test update and insert", func() {It("text update and insert success", func() {mock.ExpectBegin()mock.ExpectExec("UPDATE products").WillReturnResult(sqlmock.NewResult(1, 1))mock.ExpectExec("INSERT INTO product_viewers").WithArgs(2, 3).WillReturnResult(sqlmock.NewResult(1, 1))mock.ExpectCommit()// now we execute our methoderr = recordStats(db, 2, 3)Expect(err).To(BeNil())// we make sure that all expectations were meterr = mock.ExpectationsWereMet()Expect(err).To(BeNil())})It("text update and insert failed", func() {mock.ExpectBegin()mock.ExpectExec("UPDATE products").WillReturnResult(sqlmock.NewResult(1, 1))mock.ExpectExec("INSERT INTO product_viewers").WithArgs(2, 3).WillReturnError(fmt.Errorf("some error"))mock.ExpectRollback()// now we execute our methoderr = recordStats(db, 2, 3)Expect(err).To(BeNil())// we make sure that all expectations were meterr := mock.ExpectationsWereMet()Expect(err).To(BeNil())})Context("test query", func() {It("test query", func() {mock.ExpectQuery(regexp.QuoteMeta("SELECT * FROM user")).WithArgs(1).WillReturnRows(sqlmock.NewRows(userInfo).AddRow(1, "zyj", "123"))err = recordStats(db, 2, 3)Expect(err).To(BeNil())user, err := recordQuery(db, 1)Expect(err).To(BeNil())Expect(user.Id).To(Equal(int64(1)))})})Context("text delete", func() {It("test delete", func() {mock.ExpectExec("DELETE FROM user").WithArgs(1).WillReturnResult(sqlmock.NewResult(1, 1))err = recordDelete(db, 1)Expect(err).To(BeNil())})})})
})

RedisMock

redismock的安装:

go get github.com/go-redis/redismock/v9

简单示例:

main.go

package mainimport ("context""fmt""time""github.com/redis/go-redis/v9"
)func NewsInfoForCache(redisDB *redis.Client, newsID int) (info string, err error) {cacheKey := fmt.Sprintf("news_redis_cache_%d", newsID)ctx := context.TODO()info, err = redisDB.Get(ctx, cacheKey).Result()if err == redis.Nil {// info, err = call api()info = "test"err = redisDB.Set(ctx, cacheKey, info, 30*time.Minute).Err()}return
}

main_test.go

package mainimport ("errors""fmt""sync""time""github.com/go-redis/redismock/v9". "github.com/onsi/ginkgo". "github.com/onsi/gomega""github.com/redis/go-redis/v9"
)var _ = Describe("Record Test", func() {var (once        sync.Oncemock        redismock.ClientMockredisClient *redis.Client)BeforeEach(func() {once.Do(func() {redisClient, mock = redismock.NewClientMock()})})Context("test set", func() {id := 123key := fmt.Sprintf("new_redis_cache_%d", id)It("test set success", func() {mock.ExpectGet(key).RedisNil()mock.Regexp().ExpectSet(key, `[a-z]+`, 30*time.Second).SetErr(errors.New("FAIL"))_, err := NewsInfoForCache(redisClient, id)Expect(err).To(BeNil())})})})

Monkey

monkey是go语言非常常用的一个打桩工具,它在运行时通过汇编语言重写可执行文件,将目标函数或方法的实现跳转到桩实现。

monkey库很强大,但是使用时需注意以下事项:

1.monkey不支持内联函数,在测试的时候需要通过命令行参数-gcflags=-1关闭Go语言的内联优化
2.monkey不是线程安全的,所以不能把它放到并发的单元测试中

安装monkey库的命令:

go get bou.ke/monkey

简单的monkey打桩示例:

main.go

package mainimport ("fmt"
)type Student struct {
}func (S *Student) GetInfoByUID(id int64) (string, error) {return "", nil
}func MyFunc(uid int64) string {var varys Studentu, err := varys.GetInfoByUID(uid)if err != nil {return "welcome"}// 这里是一些逻辑代码...return fmt.Sprintf("hello %s\n", u)
}

main_test.go

package mainimport ("bou.ke/monkey". "github.com/onsi/ginkgo". "github.com/onsi/gomega"
)var _ = Describe("Record Test", func() {Context("test myfunc", func() {var varys Studentmonkey.Patch(varys.GetInfoByUID, func(num int64) (string, error) {return "zyj", nil})ret := MyFunc(123)Expect(ret).NotTo(Equal("welcome"))})})

相关文章:

golang入门笔记——测试

测试类型&#xff1a; 单元测试&#xff1a; 规则&#xff1a; 1.所有测试文件以_test.go结尾 2.func Testxxx&#xff08;*testing.T&#xff09; 3.初始化逻辑放到TestMain中 运行&#xff1a; go test [flags][packages]Go语言中的测试依赖go test命令。 go test命令是一…...

【CSAPP】整数运算

文章目录无符号加法练习1练习2补码加法练习1练习2练习3练习4补码的非练习无符号乘法补码乘法练习1练习2练习3乘以常数练习1练习2除以2的幂练习1练习2关于整数运算的最后思考练习无符号加法 考虑两个非负整数x和y&#xff0c;满足0≤x,y<2w0 \le x, y < 2^w0≤x,y<2w&…...

使用 xshell 远程连接(使用 xftp 远程传输)

xshell 和 xftp的使用都基于ssh协议&#xff0c;我们需要先在远程服务端或者虚拟机上安装ssh服务&#xff0c;然后才能远程连接。 目录 1、什么是ssh协议&#xff1f; 2、安装 openssh (1) 安装 openssh 服务器 (2) 关闭服务器防火墙&#xff08;或者开放端口22&#xff09…...

一个例子搞懂子网划分及子网掩码的计算

前置知识&#xff1a; 1、标准ip地址分为A、B、C、D、E五类&#xff0c;分类标准是ip地址的前几个比特位的值。 我们知道ip地址是32位比特-4字节组成&#xff0c;A类地址则是由首位为0&#xff0c;首字节为网络地址&#xff0c;其余3字节为主机地址组成&#xff0c;A类网络地址…...

SPI机制源码:JDK Dubbo Spring

JDK 17 Dubbo 3.1.6 JDK SPI JDK SPI在sql驱动类加载、以及slf4j日志实现加载方面有具体实现。 示例 public class Test {private static final Logger logger LoggerFactory.getLogger(Test.class);public static void main(String[] args) {ServiceLoader<JdkSpiServi…...

Spring Security+jwt+redis+自定义认证逻辑 权限控制

Spring Securityjwtredis自定义认证逻辑 权限控制 1.拦截访问基本思路 2.创建数据库表&#xff1a;角色表&#xff08;应该6个表&#xff0c;这里只用用户表代替角色表&#xff09;、权限表、路径表、角色-权限表、权限-路径表 /* SQLyog Professional v12.14 (64 bit) MySQL…...

打游戏什么蓝牙耳机好用?打游戏比较好的蓝牙耳机

游戏耳机提供身临其境的细致声音&#xff0c;同时也是与朋友在线聊天的绝佳通信设备&#xff0c;尤其对于游戏玩家来说&#xff0c;聆听和被聆听的最佳方式之一就是游戏耳机&#xff0c;那2023年到底有哪些值得购买的游戏耳机呢&#xff1f;现在就让我们一起来看看吧。 第一款…...

炔基点击交联试剂1704097-05-1,Alkyne-A-DSBSO crosslinker,发生相应点击反应

1、理论分析&#xff1a;中文名&#xff1a;炔基-A-DSBSO crosslinker&#xff0c;英文名&#xff1a;Alkyne-A-DSBSO crosslinkerCAS号&#xff1a;1704097-05-1化学式&#xff1a;C25H32N2O12S2分子量&#xff1a;616.652、产品详情&#xff1a;外观&#xff1a;白色固体&…...

刷题记录:牛客NC24309Overplanting (Silver)

传送门:牛客 题目描述: Farmer John has purchased a new machine that is capable of planting grass within any rectangular region of his farm that is "axially aligned" (i.e., with vertical and horizontal sides). Unfortunately, the machine malfunc…...

Spring Boot中使用Sa-Token实现轻量级登录与鉴权

1. Sa-Token 介绍 Sa-Token 是一个轻量级 Java 权限认证框架&#xff0c;主要解决&#xff1a;登录认证、权限认证、单点登录、OAuth2.0、分布式Session会话、微服务网关鉴权 等一系列权限相关问题。 功能结构图 2. 登录认证 对于一些登录之后才能访问的接口&#xff08;例如&…...

《分布式技术原理与算法解析》学习笔记Day20

CAP理论 什么是CAP理论&#xff1f; CAP理论用来指导分布式系统设计&#xff0c;以保证系统的可用性、数据一致性等。 C&#xff0c;Consistency&#xff0c;一致性&#xff0c;指所有节点在同一时刻的数据是相同的&#xff0c;即更新操作执行结束并响应用户完成后&#xff…...

【2023-2-23】FastDeploy 安装教程

【2023-2-22】FastDeploy 安装编译教程 该测试 FastDeploy CPU版本。 1. fastDeploy库编译 1.1 官方预编译库下载 预编译库下载安装 1.2 自定义CPU版本库编译 官方编译FastDeploy教程 CMakeGUI VS 2019 IDE编译FastDeploy 本人编译教程 CMAKE_CONFIGURATION_TYPES 属性设…...

rollup.js 一个简单实用的打包工具

最近在看vue3相关的知识的时候&#xff0c;发现了一个新的打包工具&#xff0c;至少于我而言是新鲜的。它就是rollup.js。一说到JS打包、合并、压缩、模块处理等都会想到webpack&#xff0c;这是王者&#xff0c;当然入门的难度偏高。而vue3中搭配的vite运行速度确实非常快&…...

数据结构与算法之最小爬楼梯费用动态规划

继续上一道题目&#xff0c;在上一道题目的基础之上&#xff0c;我们来解决这一道爬楼梯最小费用题。一.题目描述二.思路(动态规划五部曲)确定dp数组以及下标的含义使用动态规划&#xff0c;就要有一个数组来记录状态&#xff0c;本题只需要一个一维数组dp[i]就可以了。dp[i]的…...

阿里云ACA认证如何获取?

获取阿里云ACA&#xff08;Alibaba Cloud Certification Associate&#xff09;认证&#xff0c;需要按照以下步骤进行操作&#xff1a; 注册阿里云账号。如果您还没有阿里云账号&#xff0c;请先注册一个账号。登录阿里云官网。登录后&#xff0c;进入阿里云认证中心。选择AC…...

【Python入门第十六天】Python If ... Else

Python 条件和 If 语句 Python 支持来自数学的常用逻辑条件&#xff1a; 等于&#xff1a;a b不等于&#xff1a;a ! b小于&#xff1a;a < b小于等于&#xff1a;a < b大于&#xff1a;a > b大于等于&#xff1a;a > b 这些条件能够以多种方式使用&#xff0c…...

两数之和的解法

给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案…...

领导催我优化SQL语句,我求助了ChatGPT。这是ChatGPT给出的建议,你们觉得靠谱吗

作为一个程序员&#xff0c;无论在面试还是工作中&#xff0c;优化SQL都是绕不过去的难题。 为啥&#xff1f;工作之后才会明白&#xff0c;随着公司的业务量增多&#xff0c;SQL的执行效率对程系统运行效率的影响逐渐增大&#xff0c;相对于改造代码&#xff0c;优化SQL语句是…...

ArcGIS手动分割矢量面要素从而划分为多个面部分的方式:Cut Polygons Tool

本文介绍在ArcGIS下属ArcMap软件中&#xff0c;通过“Cut Polygons Tool”工具&#xff0c;对一个面要素矢量图层加以手动分割&#xff0c;从而将其划分为指定形状的多个部分的方法。 对于一个面要素矢量文件&#xff0c;有时我们需要对其加以划分&#xff0c;通过手动勾勒新的…...

【LeetCode】剑指 Offer 13. 机器人的运动范围 p92 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/ 1. 题目介绍&#xff08;13. 机器人的运动范围&#xff09; 地上有一个m行n列的方格&#xff0c;从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动&#xff0…...

[oeasy]python0091_仙童公司_八叛逆_intel_8080_altair8800_牛郎星

编码进化 个人电脑 计算机 通过电话网络 进行连接 极客 利用技术 做一些有趣的尝试 极客文化 是 认真研究技术的 文化 计算机 不再是 高校和研究机构高墙里面的 神秘事物而是 生活中常见的 家用电器 ibm 蓝色巨人脚步沉重 dec 小型机不断蚕食低端市场甚至组成网络干掉大型机…...

crontab 执行脚本报错,手动执行脚本正常的解决方法

一、出现的问题 有一个守护脚本XXX.sh&#xff0c;需要使用oracle用户在linux上配置定时任务&#xff0c;每1分钟检查执行一次。但是发现该脚本使用oralce用户手动启动没问题&#xff0c;能正常把程序启动起来&#xff0c;而使用crontab并没有把程序启动起来。 二、排查分析问…...

扎心话题 | 设计院背后的潜规则你知道吗?

大家好&#xff0c;我是建模助手。 大家都知道&#xff0c;在过去的2022年经济是真难&#xff01;以小编所在的广东为例&#xff0c;全年GDP增长仅1.9%。 这个数据足以呈现一个社会现象——不仅消费力咔咔下降&#xff0c;各行各业更有不同程度地嗝屁。这其中也包括一些设计院…...

【JavaEE初阶】第二节.多线程( 进阶篇 ) 锁的优化、JUC的常用类、线程安全的集合类

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、synchronized的优化操作 1.1 锁膨胀/锁升级 1.2 锁消除 1.3 锁粗化二、JUC 2.1 Callable接口 2.2 ReentrantLock类&…...

大数据核心技术是什么

大数据的核心层&#xff1a;数据采集层、数据存储与分析层、数据共享层、数据应用层&#xff0c;可能叫法有所不同本质上的角色都大同小异。 大数据的核心技术都包括什么&#xff1f; 1、数据采集 数据采集的任务就是把数据从各种数据源中采集和存储到数据存储上&#xff0c…...

「TCG 规范解读」初识 TPM 2.0 库续一

可信计算组织&#xff08;Ttrusted Computing Group,TCG&#xff09;是一个非盈利的工业标准组织&#xff0c;它的宗旨是加强在相异计算机平台上的计算环境的安全性。TCG于2003年春成立&#xff0c;并采纳了由可信计算平台联盟&#xff08;the Trusted Computing Platform Alli…...

task与function

task和function主要是有助于代码的可重用性&#xff0c;都可以在module-endmodule之外声明。 1.function 1.1.function逻辑的综合 function&#xff1a;一个只有1个wire型输出值、全是组合逻辑的函数&#xff0c;且函数名即输出信号名&#xff0c;小括号中按顺序例化输入信号。…...

Android 基础知识4-3.1 TextView(文本框)详解

一、前言 TextView就是一个显示文本标签的控件&#xff0c;就是用来显示文本。可以在代码或者 XML中设置字体&#xff0c;字体大小&#xff0c;字体颜色 &#xff0c;字体样式 &#xff08;加粗级斜体&#xff09;&#xff0c;文字截断&#xff08;比如&#xff1a;只显示10个字…...

点击化学 PEG 试剂1858242-47-3,Propargyl丙炔基-PEG1-乙酸活性酯

Propargyl-PEG1-Acetic acid-NHS ester&#xff0c;丙炔基-聚乙二醇-乙酸琥珀酰亚胺酯&#xff0c;丙炔基-PEG1-乙酸活性酯&#xff0c;丙炔基-PEG1-乙酸-NHS 酯产品规格&#xff1a;1.CAS号&#xff1a;1858242-47-32.分子式&#xff1a;C9H9NO53.分子量&#xff1a;211.174.包…...

正则表达式是如何运作的?

在日常的开发工作当中&#xff0c;我们必不可免的会碰到需要使用正则的情况。 正则在很多时候通过不同的组合方式最后都可以达到既定的目标结果。比如我们有一个需要匹配的字符串&#xff1a; hello&#xff0c;我们可以通过 / .</p>/ 以及 / .?</p>/ 来匹配&…...