Golang中刷题关于切片的一些坑

问题1

问题描述:递归的过程中,传递了一个切片作为参数,每次我们都需要对切片切取首元素,之后递归回来的时候发现切片中的元素还是没有切取首元素,是一个很严重的逻辑错误

问题解决:我们递归函数使用切片作为参数的时候,我们直接传入切片的地址。因为切片每次删除元素,地址也会改变。当切片增加元素引起扩容,地址也会发生改变,而如果只传入切片我们只是引用最开始的时候的切片的地址,因此会发现切片没有任何改变。

例如我们自己写的二叉树序列化和反序列化代码:在最开始只是传递一个切片,但是后来传递切片的地址进去发现代码逻辑正常运行。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//方法一:使用先序遍历进行序列化和反序列化
//进行序列化
func PreorderSerialize(root *TreeNode) string {
if root == nil {
return "#!"
}

var ret string

ret += strconv.Itoa(root.Val) + "!"
ret += PreorderSerialize(root.Left)
ret += PreorderSerialize(root.Right)
return ret
}

//进行反序列化
func PreorderDeserialize(ret string) *TreeNode {
strs := strings.Split(ret, "!")

//注意点:由于切片在执行过程中有可能会因为增加和删除元素而造成切片不是原来那个切片,但是我们递归回去的时候还是指向原来的切片,因此会有问题
//所以这里我们传递的是切片的地址
//因为切片扩容可能会生成一个新的底层数组,并且由于切片移除了元素,因此对应的头部地址一定会改变,所以会造成地址的改变
root := ReconstructTreeFromPreorder(&strs)
return root
}

//根据我们分割后的字符串建立二叉树
func ReconstructTreeFromPreorder(strs *[]string) *TreeNode {
if (*strs)[0] == "#" {
(*strs) = (*strs)[1:]
return nil
}

//首先将该值对应的字符串转换为int
val, _ := strconv.Atoi((*strs)[0])
//建立一个针对于该值的节点
node := &TreeNode{
Val: val,
}

//去掉我们建立过的节点的值
(*strs) = (*strs)[1:]
//之后进行递归建立左右子树
node.Left = ReconstructTreeFromPreorder(strs)
node.Right = ReconstructTreeFromPreorder(strs)

return node
}

go中的heap实现大根堆与小根堆

小根堆

几个注意点:

  1. 因为heap需要我们实现sort接口(3个方法,Less,Swap,以及Len)我们使用Less比较的时候决定了大根堆或小根堆
  2. push以及pop因为涉及到切片中元素个数的改变,可能进行扩容或缩容,所以要使用指针
  3. Push以及Pop的实现就按照对切片的处理即可
  4. 之后初始化我们的堆的时候需要先建立我们自己的堆,然后使用heap.Init()初始化
  5. 后面堆要弹出或加入元素都必须使用heap.Push()以及heap.Pop()

面试问题之Top K系列

思路整理:

内存泄漏与内存溢出

内存泄漏与内存溢出:

单工通信,半双工通信,双工通信

1. 单工通信(simplex)只有一个信道不可改变方向 单工通信只支持信号在一个方向上传输(正向或反向),任何时候不能改变信号的传输方向。为保证正确传送数据信号,接收端要对接收的数据进行校验,若校验出错,则通过监控信道发送请求重发的信号。 应用:此种方式适用于数据收集系统,如气象数据的收集、电话费的集中计算等。例如计算机和打印机之间的通信是单工模式,因为只有计算机向打印机传输数据,而没有相...

描述输入url到页面呈现的整个过程

大致过程客户端获取URL - > DNS解析 - > TCP连接 - >发送HTTP请求 - >服务器处理请求 - >返回报文 - >浏览器解析渲染页面 - > TCP断开连接 详细文字讲解客户端: (应用层开始)获取URL,通过负责域名解析的DNS服务获取网址的IP地址,根据HTT协议生成HTTP请求报文(应用层结束) (传输层开始)根据TCP协...

https面试题

https中ssl的握手过程,为什么不一致用非对称加密?https中ssl的握手过程为什么不一直用非对称加密? 使用非对称密钥用于传入对称密钥来保证传输过程的安全性,之后使用对称密钥加密进行通信来保证通信过程的效率 非对称加密加密解密算法效率较低,不适合客户端和服务器端这样高频率的通信过程,在某些极端情况下,甚至能比非对称加密慢上1000倍。 非对称加密的优势在于它可以很好帮助完成秘钥的交换...

并发,并行,异步,同步,长连接,短连接,阻塞,非阻塞

同步和异步区别同步和异步最大的区别就是被调用方的执行方式和返回时机。同步指的是被调用方做完事情之后再返回,异步指的是被调用方先返回,然后再做事情,做完之后再想办法通知调用方。 阻塞和非阻塞阻塞请求,A调用B,A一直等着B的返回,别的事情什么也不干。 非阻塞请求,A调用B,A不用一直等着B的返回,先去忙别的事情了。 区别阻塞和非阻最大的区别就是在被调用方返回结果之前的这段时间内,调用方是否一直...
面试

计算机网络面试题整理

操作系统协程,线程,进程,以及区别 操作系统为了跟踪每个进程的活动状态,维护了一个进程表。进程表的内部列出了每个进程的状态以及每个进程使用的资源等。 进程:正在执行程序的一个实例,是资源分配的基本单位。(进程控制块(process control block)描述进程的基本信息和运行状态,所谓的创建和撤销进程,都是指对PCB的操作)线程:进程中的单条流向,是程序独立调度的基本单位。 区别:...

操作系统高频面试

进程与线程区别 进程是资源分配的基本单位,线程是独立运行和独立调度的基本单位(CPU上真正运行的是线程) 进程拥有自己的资源空间,一个进程包含若干个线程,线程与CPU资源分配无关,多个线程共享同一进程内的资源 线程的调度与切换比进程快很多 并发与并行 并发:在操作系统中,某一时间段,几个程序在同一个CPU上运行,但在任意一个时间点上,只有一个程序在CPU上运行。 并行:当操作系统有多个CP...