[Go] go基础4

news2024/11/19 0:45:20

1. 并发编程

1.1 并发和并行

并发: 多个线程在同个核心的CPU上运行.并发的本质是串行.

并行: 多个线程在多个核心的CPU上运行.

1.2 协程和线程

协程: 独立的栈空间,共享堆空间,调度由用户控制,本质上有点类似用户及线程,这些用户及线程的调度也是自己实现的.

线程: 一个线程上可以跑多个协程,协程是轻量级的线程.(操作系统调度的)

1.3 goroutine

Go 语言中goroutine就是一种机制,类似于线程,但它是由Go运行时(runtime)调度和管理
Go程序会智能地将goroutine中的任务合理分配给每个CPU
Go语言之所以被称为现代化的编程语言,就是因为它在语言层面已经内置了调度和上下文切换机制.
在Go语言编程中你不需要自己去写进程,线程,协程,你的技能包里只要有一个goroutine就可以.
当你需要让某个任务并发执行时,只需要把这个任务包装成一个函数.
开启一个goroutine去执行这个函数就可以了,就是这么简单粗暴.

1.4 协程的使用

正常情况下

func main() {
	test()
}

func test() {
	for i := 0; i < 10; i++ {
		fmt.Println(i)
	}
}
结果
0
1
2
3
4
5
6
7
8
9

开启协程方法1:

go 方法名()

go test()

可以看到这里main和test是一起打印的.

func main() {
	go test()
	for i := 0; i < 10; i++ {
		fmt.Println("main", i)
		time.Sleep(time.Microsecond * 100)
	}
	time.Sleep(time.Second)
	fmt.Println("done")
}

func test() {
	for i := 0; i < 10; i++ {
		fmt.Println("test", i)
		time.Sleep(time.Microsecond * 100)
	}
}
结构:
main 0
test 0
test 1
main 1
main 2
test 2
main 3
test 3
main 4
test 4
main 5
test 5
test 6
main 6
main 7
test 7
test 8
main 8
main 9
test 9
done

1.4.2 sync.WaitGroup

线程开启时候协程
goroutine 开启wait.add(1) 计数器加1
goroutine结束wait.Done()计数器减1
groutine退出wait.wait()判断当前grouproutine是否为0,为0就退出.

// 1. 定义计数器
var wait sync.WaitGroup

func main() {
	// 2.开启一个协程计算器+1
	wait.Add(1)
	go test()
	// 4.计算器为0时退出
	wait.Wait()
	fmt.Println("Done!")
}
func test() {
	for i := 0; i < 10; i++ {
		fmt.Println("main", i)
		time.Sleep(time.Microsecond * 100)
	}
	// 3.协程执行完毕,计数器-1
	wait.Done()
}

2. channel

2.1 Channel说明

  • 共享内存交互数据弊端

    • 单纯地将函数并发执行是没有意义的,函数与函数间需要交换数据才能体现并执行函数的意义.
    • 虽然可以使用共享内存进行数据交互,但是共享内存在不同的goroutine中容易发生竞态问题.
    • 为了保证数据交换的正确性,必须使用互斥量对内存进行加锁,这种做法势必造成性能问题.
  • channel好处

    • Go语言中的通道(channel)是一种特殊的类型.
    • 通道像一个传送带或者队列,总是遵循先进先出规则,保证收发数据的顺序.
    • 每一个通道都是一个具体类型的管道,也就是声明channel的时候需要为其指定元素类型.
    • goroutine并发执行时,channel就是他们之间的连接
    • channel是让一个goroutine发送特定的值到另一个goroutine的通讯机制

2.2 channel类型

var 变量 chan 元素类型

var ch1 chan int //整形管道
var ch2 chan bool //布尔型
var cha3 chan []int //切片管道

func main() {
	// 1. 定义channel
	// make 可以给切片,map,channel分配内存
	// chan 关键字,int channel类型,5 channel的长度大小,就是最多可以往ch1里存多少个数据,如果存第6个就会出错.
	ch1 := make(chan int, 5)
	// 2. 向channel存入数据
	ch1 <- 10
	// 3. 从channel取数据
	v1 := <-ch1
	fmt.Println("v1", v1)
	// 4. 空channel且没有关闭 取值会报错
}
	结果:
	v1 10

2.3 channel 循环取值

func main() {
	ch1 := make(chan int, 5)
	ch1 <- 1
	ch1 <- 2
	ch1 <- 3
	ch1 <- 4
	ch1 <- 5
	close(ch1)
	for i := range ch1 {
		fmt.Println(i)
	}
}
结果:
1
2
3
4
5

如果没有close就会报错

fatal error: all goroutines are asleep - deadlock!

2.4 select 多路复用

  1. select说明

    • 传统的方法遍历管道时,如果不关闭会阻塞而导致deadlock,在实际开发中,我们不能确定具体什么时间该关闭管道.
    • 这种方式可以实现从多个管道接收值的需求,但运行性能会差很多
    • 为了应对这种场景,Go内置了select关键字,可以同时响应多个管道的操作.
    • select使用类似switch语句,他有一系列case分支和一个默认的分支.
    • 每个case会对应一个管道的通信(接收和发送)过程.
    • select会一直等待,直到某个case的通信操作完成时,就会执行case分支对应的语句.
    func main() {
    	// 1. 定义channel
    	ch1 := make(chan int, 10)
    	for i := 0; i < 10; i++ {
    		ch1 <- i
    	}
    	ch2 := make(chan string, 10)
    	for i := 0; i < 10; i++ {
    		ch2 <- strconv.Itoa(i)
    	}
    	for {
    		select {
    		case v := <-ch1:
    			fmt.Println("int channel", v)
    			time.Sleep(100 * time.Millisecond)
    		case s := <-ch2:
    			fmt.Println("string channel", s)
    			time.Sleep(100 * time.Millisecond)
    		default:
    			fmt.Println("Channel 中数据已经取完.")
    			return
    		}
    	}
    }
    结果
    int channel 0
    string channel 0
    int channel 1
    string channel 1
    int channel 2
    string channel 2
    int channel 3
    string channel 3
    int channel 4
    string channel 4
    int channel 5
    int channel 6
    int channel 7
    string channel 5
    string channel 6
    int channel 8
    int channel 9
    string channel 7
    string channel 8
    string channel 9
    Channel 中数据已经取完.
    

    3. 互斥锁

    • 互斥锁是一种常用的控制共享资源访问的方法,它能够保证同时只有一个goroutine可以访问共享资源.
    • Go语言中使用sync包的Mutex类型来实现互斥锁
    var x int
    
    func main() {
    	fmt.Println(x)
    	add()
    	fmt.Println(x)
    }
    func add() {
    	for i := 1; i <= 5000; i++ {
    		x += 1
    	}
    }
    结果
    0
    5000
    

    当开启了多个协程对一个资源进行操作,就出现了资源竞争.

    var x int
    var wg sync.WaitGroup
    
    func main() {
    	wg.Add(2)
    	fmt.Println(x)
    	go add()
    	go add()
    	wg.Wait()
    	fmt.Println(x)
    }
    func add() {
    	for i := 1; i <= 5000; i++ {
    		x += 1
    	}
    	wg.Done()
    }
    结果
    0
    7606
    第二次运行结果是
    0   
    8813
    

    为了保证数据正常,需要加上互斥锁.

    var x int
    var wg sync.WaitGroup
    
    // 1. 定义互斥锁
    var lock sync.Mutex
    
    func main() {
    	wg.Add(2)
    	fmt.Println(x)
    	go add()
    	go add()
    	wg.Wait()
    	fmt.Println(x)
    }
    func add() {
    	for i := 1; i <= 5000; i++ {
    		// 2. 执行前加锁
    		lock.Lock()
    		x += 1
    		// 3. 执行完解锁
    		lock.Unlock()
    	}
    	wg.Done()
    }
    结果
    0
    10000
    

3. fmt

常用占位符

参数功能
%v按值的本来值输出
%+v在%v基础上,对结构体字段名和值进行展开
%#v输出go语言语法格式的值
%T类型的值
%%输出%%本体
%b以二进制显示
%o以8进制显示
%d以10进制显示
%x以16进制显示
%X以16进制显示,字母大写
%UUnicode字符
%f浮点数
%p指针,16进制方式显示

3.1 Sprint

将格式化的数据复制给其他变量

s := fmt.Sprintf("姓名: %s age: %d","张三",24)
fmt.Println(s)
结果
姓名: 张三 age: 24

fmt.Printf 不换行
fmt.Println 换行

4. 时间

4.1 时间转换

  • 时间对象, golang中定义的一个对象
    • time.Now()
  • 时间戳: 秒整数形式,1970年1月1日开始
    • now.Unix()
  • 格式化时间:人看
    • now.Format(“2006-01-02 15:04:05”)
func main() {
	// 1. 获取时间对象
	now := time.Now()
	fmt.Printf("%T %v\n", now, now)
	// 2. 格式化时间 将时间对象,转换为格式化的时间
	strTime := now.Format("2006-01-02 15:04:05")
	fmt.Printf("%T %v\n", strTime, strTime)
	// 3. 时间戳格式 秒的整数形式
	ts := now.Unix()
	fmt.Printf("%T %v\n", ts, ts)
	// 4. 格式化时间转换成时间对象
	// 4.1 设置时区
	loc, _ := time.LoadLocation("Asia/Shanghai")
	// 4.2 传入时间标记2006-01-02 15:04:05 这个值是不能修改的
	timeObj, _ := time.ParseInLocation("2006-01-02 15:04:05", strTime, loc)
	fmt.Println(timeObj.Unix())
}
结果
time.Time 2022-12-05 14:00:40.2687082 +0800 CST m=+0.004188601
string 2022-12-05 14:00:40
int64 1670220040          
1670220040   

4.2 时间类型

func main() {
	now := time.Now()
	year := now.Year()
	month := now.Month()
	day := now.Day()
	hour := now.Hour()
	minute := now.Minute()
	second := now.Second()
	fmt.Printf("%v %v %v %v %v %v", year, month, day, hour, minute, second)
}
	// %02d 保留2位十进制数字,不够就高位补0
	Today := fmt.Sprintf("%02d-%d-%02 %d:%d:%d", year, month, day, hour, minute, second)
	fmt.Printf("%T %v", Today, Today)
结果
2022 December 5 14 10 53
2022-12-05 14:15:11
string

4.3 时间间隔

参数含义
nanosecond纳秒 , 十亿分之一秒
Microsecond1000*nanosecond微秒,一百万分之一秒
Millisecond1000*Microsecond毫秒,千分之一秒
Second1000*Microsecond,秒
Minute60*second,分
Hour60*Minute,小时

4.3.1 Add方法

func main() {
	now := time.Now()
	fmt.Println("现在是:", now)
	m, _ := time.ParseDuration("-1m")
	m1 := now.Add(m)
	fmt.Println("前1分钟是:", m1)
}
结果
现在是: 2022-12-05 14:42:46.8769096 +0800 CST m=+0.003688201
前1分钟是: 2022-12-05 14:41:46.8769096 +0800 CST m=-59.996311799

5. Flag

Go语言内置的flag包实现了命令行参数的解析,flag包使得开发命令行工具更为简单.

func main() {
	// 1. String variables
	var name string
	var address string
	flag.StringVar(&name, "name", "张三", "姓名")
	flag.StringVar(&address, "address", "上海", "地址")
	flag.Parse()
	fmt.Println(flag.Args())
}

在命令行下执行--help
PS D:\golang\day3\03.flag> go run main.go --help
Usage of C:\Users\Q\AppData\Local\Temp\go-build1568490171\b001\exe\main.exe:
  -address string
        地址 (default "上海")
  -name string
        姓名 (default "张三")

命令行传参

&name 变量的指针,传入的数据赋值给他

name 命令行里的key

“张三” 如果不传递张三就作为默认值

“姓名” --help里的提示信息.

func main() {
	// 1. String variables
	var name string
	var address string
	flag.StringVar(&name, "name", "张三", "姓名")
	flag.StringVar(&address, "address", "上海", "地址")
	flag.Parse()
	fmt.Println(name, address)
}
命令行执行,如果不传值,就会用默认值替代
PS D:\golang\day3\03.flag> go  run main.go -name "李四" -address "北京"
李四 北京
PS D:\golang\day3\03.flag> go  run main.go -name "李四"                
李四 上海
	fmt.Println(name, address)
	// Args 可以接收除了name和address以外的传入变量
	fmt.Println(flag.Args())
结果
PS D:\golang\day3\03.flag> go  run .\main.go  1 3 2 4
张三 上海
[1 3 2 4]

6. net-http

它既能提供server端,又能提供client端.

6.1 Get请求

方法名称描述
Header()用户设置或获取响应头信息
write()用于写入数据响应体
WriteHeader()用于设置响应状态码,若不调用则默认状态码为200 OK.

6.1.1 返回数据

启动一个http服务,进行简单的返回一个数据

/*
1. 路由
2. 处理函数
 1. 解析请求数据
 2. 处理函数将结果进行返回

3. 启动服务
*/
func main() {
	// 1. 定义路由
	http.HandleFunc("/req/get", dealGetHandler)
	fmt.Println("http://127.0.0.1:8080/req/get")
	// 3. 启动服务
	// addr: 当前server监听的端口号,handler:处理函数
	http.ListenAndServe(":8080", nil)

}

// 2. 定义处理函数,用驼峰命名,以xxxHandler为函数名
// Get 请求
// http.ResponseWriter 返回数据给浏览器的,本质是一个interface接口,定义了三个方法,进行返回数据
// *http.Request 将传过来的参数放入Request结构体中. 解析url中的数据或post请求body的数据
func dealGetHandler(w http.ResponseWriter, r *http.Request) {
	// 直接返回数据
	w.Write([]byte("hello world"))
}

6.1.2 解析数据

	// 1. 解析请求的数据
	query := r.URL.Query()
	fmt.Println(query)
当浏览器输入http://127.0.0.1:8080/req/get?name=zhangsan时,得到以下返回
http://127.0.0.1:8080/req/get?name=zhangsan

请添加图片描述

请添加图片描述

6.1.3 通过get取值

func deal2GetHandler(w http.ResponseWriter, r *http.Request) {
	query := r.URL.Query()
	name2 := query.Get("name")
	fmt.Println(name2)
	// 直接返回数据
	w.Write([]byte("hello world"))
}

6.1.4 返回json值

func deal2GetHandler(w http.ResponseWriter, r *http.Request) {
	query := r.URL.Query()
	name2 := query.Get("name")
	fmt.Println(name2)
	// 1.1 直接返回字符串
	//w.Write([]byte("hello world"))
	// 1.2 返回json
	type Info struct {
		Name     string
		Password string
		Age      int64
	}
	u := Info{
		Name:     name2,
		Password: "123456",
		Age:      18,
	}
	json.NewEncoder(w).Encode(u)
}
返回内容:
{"Name":"张三","Password":"123456","Age":18}

请添加图片描述

6.2 Post请求

func main() {
	// 1. 定义路由
	http.HandleFunc("/req/get", deal2GetHandler)
	http.HandleFunc("/req/post", dealPostHandler)
	fmt.Println("http://127.0.0.1:8080/req/get")
	// 3. 启动服务
	// addr: 当前server监听的端口号,handler:处理函数
	http.ListenAndServe(":8080", nil)
}
// Get部分省略

// 和Get请求一样写法
func dealPostHandler(w http.ResponseWriter, r *http.Request) {
	// r.URL.query() 从url取参数
	// post 从http的body取中获取数据
	bodyContent, _ := ioutil.ReadAll(r.Body)
	fmt.Printf("%T %v\n", bodyContent, bodyContent)
	w.Write([]byte("hello Post"))
}

请添加图片描述

6.2.1 解析POST传入的值

  1. 通过iouttil.ReadAll 读出http.Request.body的结构体
  2. 通过json的绑定,将数据绑定到定义的结构体
func dealPostHandler(w http.ResponseWriter, r *http.Request) {
	// r.URL.query() 从url取参数
	// post 从http的body取中获取数据
	bodyContent, _ := ioutil.ReadAll(r.Body)
	// uint8 转string
	//strData := string(bodyContent)
	// string 转结构体
	// 定义个一个格式一样的struct
	var d Info2
	json.Unmarshal(bodyContent, &d)
	// 获取到的name的数据
	fmt.Println(d.Name, d.Password)
	//fmt.Printf("%T %v\n", bodyContent, strData)
	w.Write([]byte("hello Post"))
}

type Info2 struct {
	Name     string `json:"name"`
	Password string `json:"password"`
}
结果
zhangsan root123

请添加图片描述

6.3 请求数据

6.3.1 Get方法

  1. 通过body进行解析
func main() {
	apiUrl := fmt.Sprintf("http://127.0.0.1:8080/req/get?name=zhangsan")
	resp, err := http.Get(apiUrl)
	if err != nil {
		fmt.Println(err)
		return
	}
	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(body))
	var b Info
	json.Unmarshal(body, &b)
	fmt.Println(b.Name)
}

type Info struct {
	Name string `json:"name"`
}
结果
{"Name":"zhangsan","Password":"123456","Age":18}

zhangsan
  1. 通过url进行解析
func main() {
		//从这里开始
	apiUrl := "http://127.0.0.1:8080/req/get"
	data := url.Values{}
	data.Set("name", "zhangsan1")
	u, _ := url.ParseRequestURI(apiUrl)
	u.RawQuery = data.Encode()
		// 到这里其实就是在拼接url
	// 后面的和之前的一样
	resp, err := http.Get(u.String())
	if err != nil {
		panic(err)
	}
	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(body))
	var i Info
	json.Unmarshal(body, &i)
	fmt.Println(i.Name, i.Password, i.Age)
}

type Info struct {
	Name     string `json:"name"`
	Password string `json:"Password"`
	Age      int    `json:"Age"`
}
结果:
{"Name":"zhangsan1","Password":"123456","Age":18}

zhangsan1 123456 18

6.3.2 Post方法

func main() {
	url := "http://127.0.0.1:8080/req/post"
	// 表单数据提交 form submission
	//contentType := "application/x-www-form-urlencoded"
	// Json数据提交
	contentType := "application/json"
	data := `{
    "name": "zhangsan",
    "password": "root123"
}`
	resp, _ := http.Post(url, contentType, strings.NewReader(data))
	b, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(b))
}
结果:
hello Post
服务器端结果:
zhangsan root123

7. Os模块

func main() {
	// 1. 获取当前目录
	fmt.Println(os.Getwd())
	// 2. 切换路径
	os.Chdir("d:\\game\\")
	fmt.Println(os.Getwd())
	// 3. 创建文件夹
	os.Mkdir("test", 0777)
	// 4. 删除
	//os.Remove("test")
	// 5. 重命名
	os.Rename("test", "test2")
	// 6. 新建文件
	os.Create("test2/test.txt")
}

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

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

相关文章

[附源码]JAVA毕业设计网络饮品销售管理系统(系统+LW)

[附源码]JAVA毕业设计网络饮品销售管理系统&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目…

全新社交电商模式来袭,消费增值结合共享经济完成消费升级

大家好&#xff0c;我是林工&#xff0c;不知道大家是否了解消费增值&#xff1f;这是一个消费储量为基础的理念&#xff0c;体现的是消费者的消费与回报问题&#xff0c;普遍的消费返利&#xff0c;消费全返渐渐地已经不能够满足目前的客户&#xff0c;也就有了一个满足与这部…

【嵌入式硬件芯片开发笔记】4-20mA DAC芯片AD5421配置流程

【嵌入式硬件芯片开发笔记】4-20mA DAC芯片AD5421配置流程 16位、串行输入、环路供电、4 mA至20 mA DAC 可用于HART协议相关电路 同AD5700配合使用 AD5421的SPI和普通的不一样 回读时要发两段 CS中间拉高一次 数据在SCLK上升沿逐个输出&#xff0c;而且在 SCLK下降沿有效 固CP…

使用方法丨艾美捷Caspase-1活性分析试剂盒介绍

如何动态检测活细胞内的Caspase-1的活性&#xff0c;做更真实的实验&#xff1f;艾美捷推荐Immunochemistry Tech&#xff08;ICT&#xff09;的FLICA系列科研工具&#xff0c;轻松检测活细胞Caspase-1 活性。 艾美捷Immunochemistry Caspase-1活性分析试剂盒原理&#xff1a…

Qt第三十四章:总结【隐藏标题栏边框、隐藏背景、窗体透明】

目录 隐藏标题栏边框 ①隐藏标题栏代码&#xff1a; ​编辑②自定义标题栏(可以直接Copy) 使用 隐藏背景 ①隐藏背景代码,此时背景上的样式都是无效的。 ②自定义背景,通过重写paintEvent事件来完成 中间绘制的部分是我们想要的&#xff0c;只需要将标题栏边框隐藏掉就可…

五、卷积神经网络CNN5(图像卷积与反卷积)

图像卷积 首先给出一个输入输出结果那他是怎样计算的呢&#xff1f; 卷积的时候需要对卷积核进行 180 的旋转&#xff0c;同时卷积核中心与需计算的图像像素对齐&#xff0c;输出结构为中心对齐像素的一个新的像素值&#xff0c;计算例子如下&#xff1a;这样计算出左上角(即第…

【畅购商城】内网穿透之EchoSite

目录 概述 注册用户 抢注域名 ​​​​​​​下载客户端 ​​​​​​​编写配置文件 ​​​​​​​启动 ​​​​​​​访问 ​​​​​​​概述 EchoSite一款收费的内网映射工具&#xff08;已下架&#xff09; 花生壳&#xff1a;内网穿透工具&#xff0c;免费版…

springboot集成Lombok、MybaitsPlus、SwaggerUI

springboot集成Lombok、MybaitsPlus、SwaggerUI 基础环境&#xff1a;JDK8或者JDK11版本 Maven3.5(采⽤默认) IDEA旗舰版 Mysql5.7以上版本 创建springboot项目 在线构建⼯具 https://start.spring.io/ 修改pom.xml中内容 <!-- 代码库 --> <repositories> &l…

如何提高量化策略回测的效率

数量技术宅团队在CSDN学院推出了量化投资系列课程 欢迎有兴趣系统学习量化投资的同学&#xff0c;点击下方链接报名&#xff1a; 量化投资速成营&#xff08;入门课程&#xff09; Python股票量化投资 Python期货量化投资 Python数字货币量化投资 C语言CTP期货交易系统开…

教你轻松设计圣诞节日活动的邀请函?

即将迎来一年一度的圣诞活动&#xff0c;商家们要如何对此次活动展开宣传呢&#xff1f;要如何制作出一张符合节日气氛的活动邀请函&#xff1f;下面小编就教你如何使用在线工具乔拓云&#xff0c;用在线邀请函模板设计活动邀请函&#xff0c;一键就能生成活动邀请函链接&#…

springmvc整体运行流程

请求处理的流程 1&#xff1a;浏览器发送请求送至前端控制器DispatcherServlet。 2&#xff1a;DispatcherServlet收到请求后调用HandlerMapping处理器映射器。 3&#xff1a;处理器映射器找到具体的Handler处理器&#xff0c;封装成为执行链 4&#xff1a;返回执行链给Disp…

SpringBoot+MyBatis多表查询:以点餐系统的订单管理为例

文章目录项目场景数据库设计POJODaoServiceTest运行结果问题及解决项目场景 SpringBoot MyBatis &#xff0c;实现点餐系统的订单查询。 参考&#xff1a;SpringBootMyBatis多表联合查询 数据库设计 通常一个订单中会包含多个菜品&#xff0c;即一条 order 里含多个 item&am…

使用 Zotero Citation Counts Manager 自动获取文献引用数

前言 最近习惯了搜完文献把文献的引用贴进 Zotero 文献条目的 Note 里&#xff0c;但是自己一点一点打字太累。想到了 Zotero 有插件&#xff0c;简单调研一下&#xff0c;发现了一个可以用的插件。支持 CrossRef 和 SemanticScholar 的引用数获取。&#xff08;相对来说个人比…

QT QSlider、QHorizontalSlider、QVerticalSlider 控件 使用详解

本文详细的介绍了QSlider、QHorizontalSlider、QVerticalSlider控件的各种操作&#xff0c;例如&#xff1a;新建界面、设置刻度显示、设置范围值、设置值、获取值、设置步长、刻度间隔、改变方向、滑动信号、按下信号、滑动信号、释放滑块、样式表等操作。 本系列QT全面详解文…

职业生涯交叉点,7年测试工程师经历,继续做测试还是转开发?

我毕业后一直从事软件测试工作&#xff0c;今年28岁了。所做的工作都是功能测试&#xff0c;对于性能测试、自动化测试完全没有接触。 我是在深圳的一个小公司上班&#xff0c;每天朝九晚五的&#xff0c;工作不累。属于那种要来活了半天就可以搞定&#xff0c;剩下的时间都是…

三车道交通流元胞自动机研究附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

app提交上架最新流程 ios​

一、上架基本需求资料 1、苹果开发者账号&#xff08;公司已有可以不用申请&#xff0c;需要开通开发者功能&#xff0c;每年 99 美元&#xff09;​ 2、开发好的APP​ 二、证书 上架版本需要使用正式的证书​ 1、创建证书 ​​Apple Developer​​​ 2、上传证书 Sign In …

设计模式之工厂方法模式

factory method design pattern 工厂方法模式的概念、工厂方法模式的结构、工厂方法模式的优缺点、工厂方法模式的使用场景、工厂方法模式的实现示例、工厂方法模式的源码分析 1、工厂方法的概念 工厂方法模式&#xff0c;及简单工厂模式的升级版&#xff0c;其抽象了对象的创…

进阶 - Git分支管理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zGglo72S-1670494545297)(https://lili40342.gitee.io/my-images/page/p_git.png)] 本篇文章&#xff0c;是基于我自用Linux系统中的自定义文件夹“test_rep”&#xff0c;当做示例演示 具体Git仓库的目…

用无代码,「低」人力成本也能做出「高」质量售后服务

目录 智能派单提升响应速度,移动端处理高效便捷 主动提升客户满意度,统一管理客户信息 标准化领、退料流程,精细化控制物料成本 沉淀数据资产,实时掌握最新状况 双十一大促热潮刚过,部分商家就开始因为“重销售,轻售后”的经营策略,而面临消费者的维权投诉,导致庆功…