数据定义 1.函数返回值问题: 在函数有多个返回值时,只要有⼀个返回值有名 称,那么其他返回值也⼀定要有名称 2.结构体的⽐较问题 : 结构体⽐较规则之⼀: 只有相同的类型的结构体才可以⽐较(1 结构体的属性类型 , 2 属性的顺序) 结构体⽐较规则之⼆: 即使两个结构体的属性类型和顺序相同,但是⾥⾯存在不可⽐较类型,依然是不可以直接==⽐较的。 由编译器⾃动分配和释 放,存放函数的参数值、函数的调⽤流程⽅法地址、局部变量等(局部变量如果 产⽣逃逸现象,可能会挂在在堆区) (2)堆区 空间充裕,数据存放时间较久。 (2)slice拼接问题: 两个slice在append的时候,记住需要进⾏将第⼆个slice进⾏...打散再拼接。 2、有⼦类去重写interface的接⼝。
本文是 Go 基础常见面试题,结合ChatGPT的详细解释版,全背是不可能,假如面试碰上了,挑出要点用自己的语言回答就好了。 1. 与其他语言相比,Go 语言的优点有哪些? 社区支持:Go 有活跃和支持下的社区,丰富的外部库以及有 Google 强有力的支持。 企业采用:许多大型科技企业在他们的生产环境中使用 Go,证明它的实用性和稳定性。 2. 扩容是通过内置的append函数来触发的,下面是一个简单的示例: func main() { slice := make([]int,0, 2) // 初始容量为2 for i := 0 新数组的容量通常时旧容量的 2 倍,这种策略可以达到折中的性能。 新的哈希表:一旦触发扩容,Go 会创建一个新的哈希表,其大小通常是当前map的 2 倍。 重新哈希:map中的每个键值对都会重新进行哈希计算来确定它们在新的哈希表中的位置。
go2school 系列的第二道题目 用 Go 语言实现一个简单的 HTTP Server。 题目 简要描述:实现 GET(get), POST(set) 两个功能 // 读取Redis的"path:path2" @GET /path/path2 // 将 value(=3) 写入 redis 的 "path:path2" @POST /path/path2 { "value": 3 } 现有可用的redis数据库(已脱敏): { "Addr":"t.kezaihui.com: 6580", "Password":"06ad0c72d5ce41ce9f04ad1237965a4d" } 交作业 使用go语言原生的http库作为route处理url:暂时不适用框架 使用go-redis 因为go的workspace和python还有c++实在是不同。因此习惯go的workspace,理解Gopath就至关重要了。
==*操作符==表示指针指向的底层值 与C不同,Go没有指针运算 func main (){ i,j:=12,31 p:=&i//p是指向i的指针 fmt.Println(*p x int y int } func main (){ v1=Vertex{1,2} v2=Vertex{x:1}//默认y:0 v3=Vertex{}//默认x :0,y:0 p=&Vertex{1,2}//p是指向{1,2}的结构体指针 } 数组 [n]T表示n个T类型的数组 var a[10]int var main (){ var a[ 0,且没有底层数组 用make创建切片 切片可以用内建函数make创建,这也是创建动态数组的方式 a:=make([]int,2,2)//切片a的长度为2,容量为2 func main (){ compute (fn func(float64,float64)float64)float64{ return (fn(3,4)) } 函数的闭包 闭包:能够读取其他函数内部变量的函数 Go
互斥锁在内部状态实现可能因 Go 语言的不同版本而有所不同。 值得注意的是,Go 的互斥锁实现可能因版本更新而发送变化,用于优化性能或实现细节。因此建议查看当前使用版本的源代码或官方文档来获取最准确的实现信息。 2. 需要注意的是,在实现细节方面,Go 的标准库不提供关于互斥锁内部行为的具体参数。自旋的逻辑和上述条件可能在 Go 不同的版本之间有所变化,以上内容主要基于 Go 语言当前和之前版本的实现。 func(i int){ defer wg.Done() // 在退出 goroutine 前递减计数 time.Sleep(2 * time.Second WaitGroup 实现原理 WaitGroup主要维护了 2 个计数器,一个是请求计数器 v,一个是等待计数器 w,二者组成一个 64bit 的值,请求计算器占高 32bit,等待计数器占低 32bit
(2)sliceTwo := sliceOne[2:4] 这种方式是基于其他切片或数据创建容量,长度为创建切片是指定的结束-起始位置, = 4-2=2;容量就等于切片的容量-起始位置=10-2=8.且两个切片共享同一个数据区 buckets unsafe.Pointer // bucket数组指针, 数组的大小为2^B ... } go的哈希表实现底层数据结构中有一个count标识当前元素个数,一个B成员标识桶的个数,还有一个 go语言中的哈希表触发扩容的条件有两个: 负载因子 > 6.5时, 也即平均每个bucket存储的键值对达到6.5个 overflow数量 > 2^15时, 也即overflow数量超过32768时 第一种情况负载因子过大 考虑到如果map存储了数以亿计的key-value, 一次性搬迁将会造成比较大的延时, Go采用逐步搬迁策略, 即每次访问map时都会触发一次搬迁, 每次搬迁2个键值对。 go语言的同步锁 (1) 当一个goroutine获得了Mutex后,其他goroutine就只能乖乖的等待,除非该goroutine释放这个Mutex (2) RWMutex在读锁占用的情况下,会阻止写
Go 语言笔试面试题 日常收集的题 一. 基础语法 1 = 和 := 的区别? 答案 := 声明+赋值 = 仅赋值 1var a int 2a = 10 3// 等价于 4a := 10 2 Go 有异常类型吗? 答案 Go 没有异常类型,只有错误类型(Error),通常使用返回值来表示异常状态。 1f, err := os.Open("/tmp/a.txt") 2if err ! 6 var y int = M 7 fmt.Println(x, y) 8} 答案 编译失败:cannot use M (type int32) as type int in assignment Go [0 1 2 3 4 1 6 7 8 9]
选择Go语言的原因: 并发和高并发:Go 语言在设计之初就考虑了并发和高并发方面的问题,将其内置于语言层面上,在编写代码时容易实现并发,提升程序的性能。 高效率:Go 语言的速度非常快(如 C/C++),同时又简单易用(如 Python)。Go 语言通过 Go 语言自身的编译器即可生成本地机器码,无需虚拟机,加快了执行效率。 开发工具丰富:Go语言是开源的,所以有很多优秀的开发工具,例如Goland、Visual Studio Code等。 学习曲线低:Go 语言语法类似于C/C++,容易学习,对于其他编程语言的用户来说更加容易上手。 例如,在高并发的Web应用程序中,Go 语言被广泛应用,如微服务框架、云原生应用开发、区块链等。 Go语言的优秀性能和高可靠性已经在实际应用中得到了验证。
并发简单:Go 语言提供的 goroutines 使并发编程变得更简洁易懂。通过go关键字,开发者可以非常方便地启动新的并发任务。 同时,它们与 channels 的结合使用也是 Go 并发模型的一个特色,提供了一种优雅的方式来进行 goroutines 之间的通信。 2. 需要注意的使,Go 的调度器细节可能随着版本更新而变化,上述描述适用于 1.x 系列的 Go 版本。 5. Go 1.14 版本引入了基于信号的抢占,这标志着 Go 语言实现了抢占式调度的一大步。 8. 如果超过 2 分钟没有垃圾回收,强制执行。 将长时间未处理的 netpoll 添加到全局队列。 向长时间运行的 G 任务发出抢占调度(超过 10ms 的 G,会进行 retake)。
:=[]int{} // len(s1)=0,cap(s1)=0, s2! 我们在go语言中通过 := 赋值引用类型就是 浅拷贝,即拷贝的是内存地址,两个变量对应的是同一个内存地址对应的同一个值 a := []string{1,2,3} b := a 如果我们通过copy a := []string{1,2,3} b := make([]string,len(a),cap(a)) copy(b,a) 八、new和make 一. new 1.new是GO语言一个内置的函数 ,它的函数签名如下: func new(Type) *Type 2.特点 Type表示类型,new函数只接受一个参数,这个参数是一个类型 *Type表示类型指针,new函数返回一个指向该类型内存地址的指针 九、go的map实现排序 我们知道go语言的map类型底层是有hash实现的,是无序的,不支持排序。 如果我们的数据使用map类型存储,如何实现排序呢?
2、数字证书携带的签名是CA通过CA密钥加密摘要后的结果,因此接收端通过一个解密函数F'对S进行“解密”。 步骤(1) ,生成CA自己的私钥 rootCA.key 步骤(2),根据CA自己的私钥生成自签发的数字证书,该证书里包含CA自己的公钥。 run server.go go run client.go Hi, This is an example of http service in golang! extended key usage doesn't permit it to be used for client authentication $go run client.go Get error 我们再来执行一下server和client: $ go run client.go Hi, This is an example of http service in golang!
Go函数的返回值或结果“形参”可被命名,并作为常规变量使用,就像传入的形参一样。 以下为数组在Go和C中的主要区别。在Go中, 数组是值。将一个数组赋予另一个数组会复制其所有元素。 特别地,若将某个数组传入某个函数,它将接收到该数组的一份副本而非指针。 数组的大小是其类型的一部分。 二维切片 Go的数组和切片都是一维的。 以下简单的例子 x := []int{1,2,3} x = append(x, 4, 5, 6) fmt.Println(x) 将打印 [1 2 3 4 5 6]。 初始化 尽管从表面上看,Go的初始化过程与C或C++并不算太大,但它确实更为强大。 在初始化过程中,不仅可以构建复杂的结构,还能正确处理不同包对象间的初始化顺序。 常量 Go中的常量就是不变量。
2.Go变量 1.什么叫变量 在前面的讲解案例中,我们是让计算机输出数据到屏幕上,那么有同学可能就要问了,怎样让计算机保存我们通过键盘输入的数据呢?这就要用到变量了。 // 问题2:以下程序的输出结果是多少? } 但是这种方式写起来非常的复杂,可以用如下的方式进行简化: a, b, c := 1, 2, 3 fmt.Println(a, b, c) 将1的值赋值给a,将2的值赋值给b,将3的值赋值给c. 那么我们GO语言怎样接收用户的键盘输入呢? 除了上面提到的规范要求以外,GO语言自己特有的,具有一定含义的一些字符,也不能作为变量名称。
这节讲一下go语言的变量定义。go是静态语言类型,不像python、php语言,它不能在运行期间改变变量的类型(除非进行类型转换,参见 go语言入门扩展--4种类型转换)。 type // x1,x2为同类型var x1, x2 = val1, val2 // x1,x2可以为不同类型,具体类型由编译器根据右边的值进行推断x1, x2 := val1, val2 // i = 2=号左边计算可确定的内存地址: i, dataList[2] =号右边计算可确定的值: dataList[2] , 222因而这个语句等效于:i, dataList[2] = dataList // 同时提供多个iotaconst (m1, n1 = iota, iota // m1=0 n1=0m2, n2 // m2=1 n2=1m3, n3 = "hello", iota // 打断第一个 ("m1=", m1, "n1=", n1) //m1= 0 n1= 0fmt.Println("m2=", m2, "n2=", n2) // m2= 1 n2= 1fmt.Println("m3="
相关题目1:能够使HTML和PHP分离开使用的模板 smarty,phplib等 相关题目2:您是否用过模板引擎?如果有您用的模板引擎的名字是? linux:traceroute,windows:tracert a=[0,1,2,3]; b=[1,2,3,4,5]; a+=b; var_dump( 基础问题。本质还是考PHP数组的结构和特点。 假设老鼠的个数为A,则有2^A>=10; A=4; 思路很简单,十瓶药编号:0,1,10,11....1001; 0不喝。 2)信号量 信号量是一个计数器,可以用来控制多个线程对共享资源的访问. 这也是TIME_WAIT状态的等待时间被设置为2MSL的原因,以确保网络上当前连接两个方向上尚未接收的TCP报文已经全部消失。
HTTP/2。一个明显的协议变化的例子是当Go 1.6添加了对HTTP/2的自动支持。假设一个Go 1.5客户端正在连接到一个支持HTTP/2的服务器,通过一个恰好破坏HTTP/2的中间网络。 2.为了兼容性添加的GODEBUG设置将被维护至少两年(四个Go版本)。一些,如http2client和http2server,将被维护得更长,甚至无限期。 关于Go 2的更新 在这篇文章顶部引用的Go 1和Go程序的未来[7]的文本中,省略号隐藏了以下限定词: 在某个不确定的点,可能会出现Go 2规范,但在那之前,[…所有的兼容性细节…]。 这提出了一个明显的问题:我们应该何时期待破坏旧Go 1程序的Go 2规范? 答案是永远不会。Go 2,以破坏过去和不再编译旧程序的意义来说,永远不会发生。 Go 2,以我们在2017年开始的Go 1的主要修订的意义来说,已经发生了。 不会有一个破坏Go 1程序的Go 2。相反,我们将加倍重视兼容性,这比任何可能的与过去的决裂更有价值。
Go语言、C++和Java语言是三种性能较好的编程语言,它们在某些方面有不同的优势。下面是一个简单的比较: 内存管理 C++需要手动管理内存,而Java和Go语言使用垃圾回收机制。 Go语言的垃圾回收机制与Java相似,但是Go语言在设计上更加注重高性能和高并发,在实际生产环境中表现也很好。 Java和Go语言在执行速度方面与C++相差不大,但是Go语言在处理高并发方面更加出色,因为Goroutines使Go代码并发执行非常容易。 而Go语言使用Goroutines和Channels来处理并发性,使得Go语言非常适合于高并发场景,简单易用。 如果你需要处理高并发,则选择Go语言。
答案 init() 函数是 Go 程序初始化的一部分。 10 // main: 10 Q2 Go 语言的局部变量分配在栈上还是堆上? Go 编译器发现 v 的引用脱离了 foo 的作用域,会将其分配在堆上。因此,main 函数中仍能够正常访问该值。 Q3 2 个 interface 可以比较吗? 答案 Go 语言中,interface 的内部实现包含了 2 个字段,类型 T 和 值 V,interface 可以使用 == 或 != 比较。 答案 这在 Go 中是安全的,Go 编译器将会对每个局部变量进行逃逸分析。如果发现局部变量的作用域超出该函数,则不会将内存分配在栈上,而是分配在堆上。
答案 := 声明+赋值 = 仅赋值 var foo int foo = 10 // 等价于 foo := 10 Q2 指针的作用? 答案 :指针用来保存变量的地址。 Q9 Go 支持默认参数或可选参数吗? 答案:Go 语言不支持可选参数(python 支持),也不支持方法重载(java支持)。 Q11 如何交换 2 个变量的值? 很方便地实现了 Go 结构体与不同规范的 json 文本之间的转换。 Q13 如何判断 2 个字符串切片(slice) 是相等的? fmt.Println(Type1, Type2, Type3, Type4) // 0, 1, 2, 3 } Q16 空 struct{} 的用途 答案 使用空结构体 struct{} 可以节省内存,
(time.Second * 2) <-ch }() ch <- true // 无缓冲,发送方阻塞直到接收方接收到数据。 ()) time.Sleep(time.Second * 5) } func main() { st := time.Now() ch := make(chan bool, 2) go func () { time.Sleep(time.Second * 2) <-ch }() ch <- true ch <- ().Sub(st).Seconds()) // cost 2.0 s time.Sleep(time.Second * 5) } Q2 什么是协程泄露(Goroutine Leak)? 因此对于 CPU 密集型的任务,若该值过大,例如设置为 CPU 逻辑核数的 2 倍,会增加线程切换的开销,降低性能。对于 I/O 密集型应用,适当地调大该值,可以提高 I/O 吞吐率。