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

100天精通Golang(基础入门篇)——第20天:Golang 接口 深度解析☞从基础到高级

在这里插入图片描述


🌷🍁 博主猫头虎🐅🐾 带您进入 Golang 语言的新世界✨✨🍁
🦄 博客首页——🐅🐾猫头虎的博客🎐
🐳 《面试题大全专栏》 🦕 文章图文并茂🦖生动形象🐅简单易学!欢迎大家来踩踩~🌺
🌊 《IDEA开发秘籍专栏》 🐾 学会IDEA常用操作,工作效率翻倍~💐
🌊 《100天精通Golang(基础入门篇)》 🐅 学会Golang语言,畅游云原生领域,无厂不可去~💐

🪁🍁 希望本文能给您带来价值🌸如果有任何不足,欢迎批评指正!🐅🐾🍁🐥


100天精通Golang(基础入门篇)

  • 100天精通Golang(基础入门篇)——第20天:接口
      • 摘要
      • 导语
      • 引言
      • 1.1 什么是接口?
      • 1.2 接口的定义语法
      • 1.3 interface值
      • 1.4 接口的类型
      • 1.5 接口断言
      • 1.6 接口的组合
      • 1.7 接口的零值和nil
      • 1.8 接口和指针
      • 1.9 接口嵌套和方法冲突
      • 1.10 接口的实用技巧
      • 1.11 错误处理与接口
      • 1.12 测试与接口
      • 总结
      • 参考资料
  • 结语

100天精通Golang(基础入门篇)——第20天:接口

摘要

📝 第二十天来了,继续我们的 “100天精通Golang(基础入门篇)” 旅程!今天的重点是:Golang 接口深度解析☞从基础到高级。本篇将全方位地揭示接口在 Golang 中的重要性,以及如何让你的代码更加模块化、可测试和可维护。🎯

📝 探究 Golang 的接口机制如何使代码更加模块化、可测试和可维护。本文将从接口的定义、使用,到高级特性进行全面剖析。

导语

👋 大家好,我是猫头虎!今天我们将一同进入 Golang 的神秘花园,探寻接口(Interface)的无穷魅力。如果你对如何有效地使用 Golang 的接口机制感到好奇,那么这篇文章一定适合你。🌟

引言

🎙 在面向对象编程中,接口是一个非常重要的概念。但在 Golang 中,接口不仅用于描述对象的行为,还有许多高级的用途和特性。这使得 Golang 在类型系统的设计上显得非常独特和灵活。接口可以用于多态、代码解耦、错误处理等多个方面,其强大的功能和灵活性使得它成为 Golang 不可或缺的一部分。🛠

1.1 什么是接口?

面向对象世界中的接口的一般定义是“接口定义对象的行为”。它表示让指定对象应该做什么。实现这种行为的方法(实现细节)是针对对象的。

在Go中,接口是一组方法签名。当类型为接口中的所有方法提供定义时,它被称为实现接口。它与OOP非常相似。接口指定了类型应该具有的方法,类型决定了如何实现这些方法。

它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口

接口定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了该接口。

1.2 接口的定义语法

定义接口

/* 定义接口 */
type interface_name interface {method_name1 [return_type]method_name2 [return_type]method_name3 [return_type]...method_namen [return_type]
}/* 定义结构体 */
type struct_name struct {/* variables */
}/* 实现接口方法 */
func (struct_name_variable struct_name) method_name1() [return_type] {/* 方法实现 */
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {/* 方法实现*/
}

示例代码:

package mainimport ("fmt"
)type Phone interface {call()
}type NokiaPhone struct {
}func (nokiaPhone NokiaPhone) call() {fmt.Println("I am Nokia, I can call you!")
}type IPhone struct {
}func (iPhone IPhone) call() {fmt.Println("I am iPhone, I can call you!")
}func main() {var phone Phonephone = new(NokiaPhone)phone.call()phone = new(IPhone)phone.call()}

运行结果:

I am Nokia, I can call you!
I am iPhone, I can call you!
  • interface可以被任意的对象实现
  • 一个对象可以实现任意多个interface
  • 任意的类型都实现了空interface(我们这样定义:interface{}),也就是包含0个method的interface

1.3 interface值

package mainimport "fmt"type Human struct {name  stringage   intphone string
}
type Student struct {Human  //匿名字段school stringloan   float32
}
type Employee struct {Human   //匿名字段company stringmoney   float32
} //Human实现Sayhi方法
func (h Human) SayHi() {fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
} //Human实现Sing方法
func (h Human) Sing(lyrics string) {fmt.Println("La la la la...", lyrics)
} //Employee重写Human的SayHi方法
func (e Employee) SayHi() {fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name,e.company, e.phone) //Yes you can split into 2 lines here.
}// Interface Men被Human,Student和Employee实现
// 因为这三个类型都实现了这两个方法
type Men interface {SayHi()Sing(lyrics string)
}func main() {mike := Student{Human{"Mike", 25, "222-222-XXX"}, "MIT", 0.00}paul := Student{Human{"Paul", 26, "111-222-XXX"}, "Harvard", 100}sam := Employee{Human{"Sam", 36, "444-222-XXX"}, "Golang Inc.", 1000}Tom := Employee{Human{"Sam", 36, "444-222-XXX"}, "Things Ltd.", 5000}//定义Men类型的变量ivar i Men//i能存储Studenti = mikefmt.Println("This is Mike, a Student:")i.SayHi()i.Sing("November rain")//i也能存储Employeei = Tomfmt.Println("This is Tom, an Employee:")i.SayHi()i.Sing("Born to be wild")//定义了slice Menfmt.Println("Let's use a slice of Men and see what happens")x := make([]Men, 3)//T这三个都是不同类型的元素,但是他们实现了interface同一个接口x[0], x[1], x[2] = paul, sam, mikefor _, value := range x {value.SayHi()}
}

运行结果:

	This is Mike, a Student:Hi, I am Mike you can call me on 222-222-XXXLa la la la... November rainThis is Tom, an Employee:Hi, I am Sam, I work at Things Ltd.. Call me on 444-222-XXXLa la la la... Born to be wildLet's use a slice of Men and see what happensHi, I am Paul you can call me on 111-222-XXXHi, I am Sam, I work at Golang Inc.. Call me on 444-222-XXXHi, I am Mike you can call me on 222-222-XXX

那么interface里面到底能存什么值呢?如果我们定义了一个interface的变量,那么这个变量里面可以存实现这个interface的任意类型的对象。例如上面例子中,我们定义了一个Men interface类型的变量m,那么m里面可以存Human、Student或者Employee值

当然,使用指针的方式,也是可以的

但是,接口对象不能调用实现对象的属性

interface函数参数

interface的变量可以持有任意实现该interface类型的对象,这给我们编写函数(包括method)提供了一些额外的思考,我们是不是可以通过定义interface参数,让函数接受各种类型的参数

嵌入interface

package mainimport "fmt"type Human interface {Len()
}
type Student interface {Human
}type Test struct {
}func (h *Test) Len() {fmt.Println("成功")
}
func main() {var s Students = new(Test)s.Len()
}

示例代码:

package testimport ("fmt"
)type Controller struct {M int32
}type Something interface {Get()Post()
}func (c *Controller) Get() {fmt.Print("GET")
}func (c *Controller) Post() {fmt.Print("POST")
}
package mainimport ("fmt""test"
)type T struct {test.Controller
}func (t *T) Get() {//new(test.Controller).Get()fmt.Print("T")
}
func (t *T) Post() {fmt.Print("T")
}
func main() {var something test.Somethingsomething = new(T)var t Tt.M = 1//	t.Controller.M = 1something.Get()
}

Controller实现了所有的Something接口方法,当结构体T中调用Controller结构体的时候,T就相当于Java中的继承,T继承了Controller,因此,T可以不用重写所有的Something接口中的方法,因为父构造器已经实现了接口。

如果Controller没有实现Something接口方法,则T要调用Something中方法,就要实现其所有方法。

如果something = new(test.Controller)则调用的是Controller中的Get方法。

T可以使用Controller结构体中定义的变量

1.4 接口的类型

接口与鸭子类型:

先直接来看维基百科里的定义:

If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.

翻译过来就是:如果某个东西长得像鸭子,像鸭子一样游泳,像鸭子一样嘎嘎叫,那它就可以被看成是一只鸭子。

Duck Typing,鸭子类型,是动态编程语言的一种对象推断策略,它更关注对象能如何被使用,而不是对象的类型本身。Go 语言作为一门静态语言,它通过通过接口的方式完美支持鸭子类型。

而在静态语言如 Java, C++ 中,必须要显示地声明实现了某个接口,之后,才能用在任何需要这个接口的地方。如果你在程序中调用某个数,却传入了一个根本就没有实现另一个的类型,那在编译阶段就不会通过。这也是静态语言比动态语言更安全的原因。

动态语言和静态语言的差别在此就有所体现。静态语言在编译期间就能发现类型不匹配的错误,不像动态语言,必须要运行到那一行代码才会报错。当然,静态语言要求程序员在编码阶段就要按照规定来编写程序,为每个变量规定数据类型,这在某种程度上,加大了工作量,也加长了代码量。动态语言则没有这些要求,可以让人更专注在业务上,代码也更短,写起来更快,这一点,写 python 的同学比较清楚。

Go 语言作为一门现代静态语言,是有后发优势的。它引入了动态语言的便利,同时又会进行静态语言的类型检查,写起来是非常 Happy 的。Go 采用了折中的做法:不要求类型显示地声明实现了某个接口,只要实现了相关的方法即可,编译器就能检测到。

总结一下,鸭子类型是一种动态语言的风格,在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由它"当前方法和属性的集合"决定。Go 作为一种静态语言,通过接口实现了鸭子类型,实际上是 Go 的编译器在其中作了隐匿的转换工作。

Go语言的多态性:

Go中的多态性是在接口的帮助下实现的。正如我们已经讨论过的,接口可以在Go中隐式地实现。如果类型为接口中声明的所有方法提供了定义,则实现一个接口。让我们看看在接口的帮助下如何实现多态。

任何定义接口所有方法的类型都被称为隐式地实现该接口。

类型接口的变量可以保存实现接口的任何值。接口的这个属性用于实现Go中的多态性。

1.5 接口断言

前面说过,因为空接口 interface{}没有定义任何函数,因此 Go 中所有类型都实现了空接口。当一个函数的形参是interface{},那么在函数中,需要对形参进行断言,从而得到它的真实类型。

语法格式:

// 安全类型断言<目标类型的值><布尔参数> := <表达式>.( 目标类型 )//非安全类型断言<目标类型的值> := <表达式>.( 目标类型 )

示例代码:

package mainimport "fmt"func main() {var i1 interface{} = new (Student)s := i1.(Student) //不安全,如果断言失败,会直接panicfmt.Println(s)var i2 interface{} = new(Student)s, ok := i2.(Student) //安全,断言失败,也不会panic,只是ok的值为falseif ok {fmt.Println(s)}
}type Student struct {}

断言其实还有另一种形式,就是用在利用 switch语句判断接口的类型。每一个case会被顺序地考虑。当命中一个case 时,就会执行 case 中的语句,因此 case 语句的顺序是很重要的,因为很有可能会有多个 case匹配的情况。

示例代码:

switch ins:=s.(type) {case Triangle:fmt.Println("三角形。。。",ins.a,ins.b,ins.c)case Circle:fmt.Println("圆形。。。。",ins.radius)case int:fmt.Println("整型数据。。")}

1.6 接口的组合

在 Go 语言中,一个接口可以由多个小接口组合而成。这样的组合方式提供了一种“继承”的感觉,使得接口更加模块化。

type Reader interface {Read(p []byte) (n int, err error)
}type Writer interface {Write(p []byte) (n int, err error)
}type ReadWriter interface {ReaderWriter
}

在这个例子中,ReadWriter 接口组合了 ReaderWriter 接口,一个实现了 ReadWriter 接口的类必须实现所有 ReaderWriter 接口中定义的方法。

1.7 接口的零值和nil

在 Go 中,接口内部有两个组件,一个是具体的类型,另一个是该类型的值。当我们定义一个接口变量时,这两个组件都会初始化为 nil。

var a interface{}
fmt.Printf("%v, %T\n", a, a) // "nil, nil"

当一个接口变量的类型和值都为 nil 时,我们称该变量为 nil 接口变量。

1.8 接口和指针

指针类型和它所指向的值类型是两个不同的类型,因此,如果一个接口类型的方法集合包含使用值接收者定义的方法,那么这个接口可以存储这个指针类型的值。

type Describer interface {Describe()
}type Person struct {name string
}func (p Person) Describe() {fmt.Println("I am a person.")
}func main() {var d1 Describerp1 := Person{"Sam"}d1 = &p1d1.Describe()
}

1.9 接口嵌套和方法冲突

接口也可以嵌套接口,但要注意方法不要冲突。

type ReadCloser interface {ReaderCloser
}
type Closer interface {Close() error//Read() // 这里如果定义Read方法,将与Reader接口冲突
}

1.10 接口的实用技巧

  1. 类型查询: 除了类型断言,你还可以使用 , ok 语法来安全地查询值的类型。

    if val, ok := myVar.(MyType); ok {// ...
    }
    
  2. 使用接口收集不同类型的值: 你可以创建接受接口类型参数的函数或方法,以处理不同类型的值。

  3. 使用接口实现模板模式: 通过定义一个接口来封装算法的变化,然后通过具体的类型来实现算法的可替换部分。

1.11 错误处理与接口

Go 语言中的错误处理也是基于接口的。标准库中有一个 error 接口用于处理错误:

type error interface {Error() string
}

自定义错误通常会实现这个接口,提供更多的上下文信息和错误处理能力。

1.12 测试与接口

在 Go 中进行单元测试时,接口非常有用。你可以创建模拟对象来代替真实的依赖,这些模拟对象实现了同样的接口。

这样的话,你可以在测试环境下替换这些依赖,使得单元测试更加容易编写和维护。

总结

🔍 通过本文,你应该对 Golang 的接口有了全面且深入的理解。无论是基础的类型实现,还是高级的接口组合和多态性,接口都能让我们的代码更加简洁和高效。掌握接口不仅可以让你更加自如地使用 Golang,也会极大地提升你的编程水平。记住,掌握接口就是走向 Golang 高手之路的关键一步。🔑

接口在 Go 中是一种非常强大和灵活的机制,用于解耦和组织代码。它们提供了一种方式来规范对象行为,允许我们编写可复用和可测试的代码。了解和掌握接口是成为 Go 语言高手的关键之一。

参考资料

📚

  1. Go Programming Language Specification
  2. Effective Go
  3. Go Blog: Interfaces in Go
  4. Go by Example: Interfaces

希望大家喜欢这篇文章!如果你有任何问题或想要进一步探讨,随时在下方留言。👇 不要忘了点赞和分享!👍🚀

在这里插入图片描述

结语

通过今天的学习,您已经踏上了Golang的学习之旅。在未来的日子里,您将探索Golang的各个方面,从基础概念到高级技巧,从实际应用到性能优化。
学习一门编程语言是一个持续的过程,每一天都是您向Golang的精通迈进的重要一步。我鼓励您坚持每天学习,保持热情和好奇心,解决挑战并享受成功的喜悦。

在您的学习旅程中,不要忘记参与社区和与其他Golang开发者交流。分享您的见解和经验,向他人学习,并在开源项目或实际应用中展示您的技能。

如果您在学习过程中遇到困难或有任何问题,不要犹豫向社区和专家寻求帮助。持续学习,勇敢探索,您将在Golang领域取得令人瞩目的成就。

最后,感谢您的阅读和支持!祝愿您在未来的每一天中都能够成为一名精通Golang的开发者!

期待听到您在学习过程中的进展和成就。如果您需要进一步的帮助,请随时告诉我。祝您在学习Golang的旅程中取得巨大成功!

点击下方名片,加入IT技术核心学习团队。一起探索科技的未来,共同成长。

如果您在学习过程中有任何疑惑,请点击下方名片,带您一对一快速入门 Go语言 的世界 ~

相关文章:

100天精通Golang(基础入门篇)——第20天:Golang 接口 深度解析☞从基础到高级

&#x1f337;&#x1f341; 博主猫头虎&#x1f405;&#x1f43e; 带您进入 Golang 语言的新世界✨✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文并茂&#x1f…...

ESXi 6.7添加螃蟹2.5g网卡支持

安装了ESXi 6.7&#xff0c;结果机器两块网卡只能识别一块&#xff0c;然后想着不能让另一块浪费啊&#xff0c;开始折腾&#xff0c;看着网上都是找的驱动然后封装进iso&#xff0c;可是我已经装完了&#xff0c;怎么办&#xff0c;然后找到了下面解决方法 1.找驱动 下载RTL81…...

机器学习笔记之最优化理论与方法(四) 凸函数:定义与基本性质

机器学习笔记之最优化理论与方法——再回首&#xff1a;凸函数定义与基本性质 引言凸函数的定义严格凸函数凸函数的推论&#xff1a;凹函数 常见凸函数凸函数的基本性质几种保持函数凸性的运算凸集与凸函数之间的关联关系 引言 本节将介绍凸函数定义及其基本性质。 本文是关于…...

【Git】git tag 查看版本号 | 删除本地 | 删除远程仓库| 批量删除

一、删除指定tag 使用场景&#xff1a;比如我们在本地git tag了一个错误的版本号&#xff0c;但是还没有push&#xff0c;想直接删掉避免污染远程仓库 1、删除指令 要删除指定的Git标签&#xff08;版本号&#xff09;&#xff0c;您可以使用以下命令&#xff1a; git tag -d 标…...

thinkphp:数据库查询,嵌套别的表的查询(别的表做子查询)

例子 从 vendors 表中选择记录。在 vendors 表中&#xff0c;筛选出具有满足以下条件的 vendor_code 值&#xff1a; 对应的采购订单&#xff08;在 po_headers_all 表中&#xff09;存在未完全接收的采购行&#xff08;在 po_lines_all 表中&#xff09;。相应的采购订单状态…...

《Linux 系统命令及Shell脚本实践指南》

Linux 系统命令及Shell脚本实践指南 《Linux 系统命令及Shell脚本实践指南》该书从结构上分为三部分:第一部分1.1Linux的历史发展1.2用户管理1.3任务管理单一时刻执行一次任务使用at周期性任务使用&#xff1a;cron表达式&#xff0c;命令crontab 1.4文件管理1.4.1 Linux shell…...

代码随想录算法训练营第三十八天 | ● 理论基础 ● 509. 斐波那契数 ● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯

题目链接&#xff1a;509. 斐波那契数 代码随想录 视频&#xff1a;手把手带你入门动态规划 | LeetCode&#xff1a;509.斐波那契数_哔哩哔哩_bilibili 看完代码随想录之后的想法&#xff1a; 我们要知道动态规划的五部曲&#xff1b; 1&#xff0c;确定dp数组的含义&#x…...

Java分别用BIO、NIO实现简单的客户端服务器通信

分别用BIO、NIO实现客户端服务器通信 BIONIONIO演示&#xff08;无Selector&#xff09;NIO演示&#xff08;Selector&#xff09; 前言&#xff1a; Java I/O模型发展以及Netty网络模型的设计思想 BIO Java BIO是Java平台上的BIO&#xff08;Blocking I/O&#xff09;模型&a…...

React Portals

什么是React Portals React Portals&#xff08;React 门户&#xff09;是 React 提供的一种机制&#xff0c;用于将组件渲染到 DOM 树中的不同位置&#xff0c;而不受组件层次结构的限制。它允许你将一个组件的渲染内容“传送”到 DOM 结构中的任何位置&#xff0c;通常用于处…...

Python基础之高级函数

异常捕获 Python中&#xff0c;使用trycatch两个关键字来实现对异常的处理。在我们平时的工作中&#xff0c;异常的出现是在所难免的&#xff0c;但是异常一旦出现&#xff0c;极有可能会直接导致程序崩溃&#xff0c;无法正常运行&#xff0c;所以异常一定要及时的做出对应的…...

CSS3常用的新功能总结

CSS3常用的新功能包括圆角、阴渐变、2D变换、3D旋转、动画、viewpor和媒体查询。 圆角、阴影 border-redius 对一个元素实现圆角效果&#xff0c;是通过border-redius完成的。属性为两种方式&#xff1a; 一个属性值&#xff0c;表示设置所有四个角的半径为相同值&#xff…...

Lvs+KeepAlived高可用高性能负载均衡

目录 1.环境介绍 2.配置keepalived 3.测试 1.测试负载均衡 2.测试RS高可用 3.测试LVS高可用 3.1测试lvs主服务宕机 3.2.测试lvs主服务器恢复 4.我在实验中遇到的错误 1.环境介绍 环境&#xff1a;centos7 RS1---RIP1:192.168.163.145 VIP 192.168.163.200 RS2---RIP2…...

无涯教程-Android Online Test函数

Android在线测试模拟了真正的在线认证考试。您将看到基于 Android概念的多项选择题(MCQ),将为您提供四个options。您将为该问题选择最合适的答案,然后继续进行下一个问题,而不会浪费时间。完成完整的考试后,您将获得在线考试分数。 总问题数-20 最长时间-20分钟 Start Test …...

蓝桥杯打卡Day1

文章目录 全排列八皇后 一、全排列IO链接 本题思路:本题是一道经典的全排列问题&#xff0c;深度优先搜索即可解决。 #include <bits/stdc.h>constexpr int N10;std::string s; std::string ans; int n; bool st[N];void dfs(int u) {if(un){std::cout<<ans<…...

zipkin2.24.2源码install遇见的问题

1、idea导入项目后将Setting中的关于Maven和Java Compile相关的配置改为jdk11,同时Project Structure改为jdk11 2、将pom配置中的fork标签注释 标题未修改以上配置产生的问题 Compilation failure javac: Ч ı : --release : javac <options> <source files&g…...

yapi密码是如何生成的

yapi密码是如何生成的 关闭yapi注册功能后&#xff0c;想要通过手动插入用户数据到db中&#xff0c;那么密码是如何生成的呢&#xff1f; exports.generatePassword (password, passsalt) > { return sha1(password sha1(passsalt)); }; 所以如果想要创建一个用户&#x…...

2023-09-02 LeetCode每日一题(最多可以摧毁的敌人城堡数目)

2023-09-02每日一题 一、题目编号 2511. 最多可以摧毁的敌人城堡数目二、题目链接 点击跳转到题目位置 三、题目描述 给你一个长度为 n &#xff0c;下标从 0 开始的整数数组 forts &#xff0c;表示一些城堡。forts[i] 可以是 -1 &#xff0c;0 或者 1 &#xff0c;其中&…...

k8s环境部署配置

目录 一.虚拟机准备 二.基础环境配置&#xff08;各个节点都做&#xff09; 1.IP和hosts解析 2.防火墙和selinux 3.安装基本软件 4.配置时间同步 5.禁用swap分区 6.修改内核参数并重载 7.配置ipvs 三.docker环境&#xff08;各个节点都做&#xff09; 1.配置软件源并…...

Java之文件操作与IO

目录 一.认识文件 1.1文件是什么&#xff1f; 1.2文件的组织 1.3文件路径 1.4文件的分类 二.文件操作 2.1File概述 三.文件内容操作--IO 3.1JavaIO的认识 3.2Reader和Writer ⭐Reader类 ⭐Writer类 3.2FileInputStream和FileOutputStream ⭐FileInputStream类 …...

指令系统(408)

一、拓展操作码指令格式 【2017 统考】某计算机按字节编址&#xff0c;指令字长固定且只有两种指令格式&#xff0c;其中三地址指令29条、二地址指令107条&#xff0c;每个地址字段6位&#xff0c;则指令字长至少应该是&#xff08; A&#xff09; A、24位 B、26位 …...

Pygame中Trivia游戏解析6-3

3.3 Trivia类的show_question()函数 Trivia类的show_question()函数的作用是显示题目。主要包括显示题目框架、显示题目内容和显示题目选项等三部分。 3.3.1 显示题目的框架 在show_question()函数中&#xff0c;通过以下代码显示题目的框架。 print_text(font1, 210, 5, &q…...

热释电矢量传感器设计

1 概述 使用4个热释电传感器组成一个2X2的矩阵。通过曲线的相位差、 峰峰值等特征量来计算相关信息。本文使用STM32单片机设计、制作了热释电传感器矩阵&#xff1b;使用C#.NET设计了上位机软件。为以上研究做了试验平台。 2 硬件电路设计 2.1 热释电传感器介绍 热释电红外…...

MySql学习笔记10——视图介绍

视图 概述 view view可以看作是一张“虚拟表”&#xff0c;&#xff08;但是他也是会作为文件存在的&#xff09; 当我们通过复杂的查询语句获取一张表的时候&#xff0c;可以将这张表作为一个视图&#xff0c;和创建一个新表不同&#xff0c;在视图上进行的DML操作会对数据…...

【探索Linux】—— 强大的命令行工具 P.7(进程 · 进程的概念)

阅读导航 前言一、冯诺依曼体系结构二、操作系统&#xff08;OS&#xff09;1. 概念 三、进程1. 进程的概念2. PCB&#xff08;Process Control Block&#xff09;3. 查看进程 四、fork函数1. 函数简介2. 调用方式3. 返回值4. 使用示例 五、进程的几种状态1. 状态简介2. 进程状…...

JAVA宝典----容器(理解记忆)

目录 一、Java Collections框架是什么&#xff1f; 二、什么是迭代器&#xff1f; 三、Iterator与ListIterator有什么区别&#xff1f; 四、ArrayList、Vector和LinkedList有什么区别&#xff1f; 五、HashMap、Hashtable、TreeMap和WeakHashMap有哪些区别&#xff1f; 六…...

JS中的扩展操作符...(点点点)

标题 前言概述拓展操作符&#xff08;Spread Operator&#xff09;赋值与扩展操作符的区别 剩余操作符&#xff08;Rest Operator&#xff09; 前言 大家应该都在代码中用过或者看到…方法&#xff0c;我每次用到这个方法的时候都会想到第一次见到这个方法一头雾水的样子&#…...

找redis大key工具rdb_bigkeys

github官网 https://github.com/weiyanwei412/rdb_bigkeys 在centos下安装go [roothadoop102 rdb_bigkeys-master]# wget https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz [roothadoop102 rdb_bigkeys-master]# tar -zxf go1.13.5.linux-amd64.tar.gz -C /usr/local将g…...

ElasticSearch进阶

一、 search检索文档 ES支持两种基本方式检索&#xff1b; 通过REST request uri 发送搜索参数 &#xff08;uri 检索参数&#xff09;&#xff1b;通过REST request body 来发送它们&#xff08;uri请求体&#xff09;&#xff1b; 1、信息检索 API&#xff1a; https://w…...

Nor flash 页写地址与数据大小的限制

厂商提供的flash手册如下 如果页写指令的地址不是256的整数倍&#xff0c;并且写入的数据量超过了当前地址所在页的边界&#xff0c;则超过的那些数据会重新写入当前页的首地址&#xff08;即256的整数倍地址&#xff09;&#xff0c;所以&#xff0c;在进行页写的时候&#x…...

python 深度学习 解决遇到的报错问题4

目录 一、DLL load failed while importing _imaging: 找不到指定的模块 二、Cartopy安装失败 三、simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 四、raise IndexError("single positional indexer is out-of-bounds") 五、T…...