2026-01-11
其他
00

相关信息

TCP粘包和拆包理解

  • tcp粘包的原因
    • tcp本身是面向流的协议,是没有消息边界的
    • TCP 为了效率,会把多个小的数据包合并成一个大的发出去(Nagle 算法);
    • 接收方处理不够快,多个包积压在接收缓冲区里,一次性读出来了
  • 拆包
    • 数据包太大,超过了 MSS(最大报文段长度),
    • IP 层进行了分片,导致一个完整的消息被切断成两半发送。
    • 解决方案
      • 包设置固定长度
      • 增加分隔符
      • 消息头带长度(Length Field Based)(把包分成“头”和“体”)
      • 自定义序列化协议
        • 使用 Protobuf、JSON 等。虽然它们本身不解决粘包,但通常配合方案 C 使用
2025-12-16
后端技术
00

相关信息

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

js
package main import ( "fmt" ) // 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 // 最近公共祖先的定义:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x, // 满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。” // 例如,如下二叉树: Integer[] levelOrder = {3,5,1,6,2,0,8,null,null,7,4}; // 3 // 5 1 // 6 2 0 8 // 7 4 type TreeNode struct { Val int Left *TreeNode Right *TreeNode } func main() { // 构建二叉树 root := &TreeNode{Val: 3} root.Left = &TreeNode{Val: 5} root.Right = &TreeNode{Val: 1} root.Left.Left = &TreeNode{Val: 6} root.Left.Right = &TreeNode{Val: 2} root.Right.Left = &TreeNode{Val: 0} root.Right.Right = &TreeNode{Val: 8} root.Left.Right.Left = &TreeNode{Val: 7} root.Left.Right.Right = &TreeNode{Val: 4} // 测试最近公共祖先 p := root.Left.Right.Left q := root.Left.Right.Right lca := lowestCommonAncestor(root, p, q) fmt.Println("最近公共祖先:", lca.Val) // fmt.Println("Hello world!") } func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { if root == nil || root == p || root == q { return root } left := lowestCommonAncestor(root.Left, p, q) right := lowestCommonAncestor(root.Right, p, q) if left != nil && right != nil { return root } if left != nil { return left } return right }
2025-12-15
golang
00

相关信息

接雨水,这道题最大的问题在于理解怎么才能接到雨水

接雨水其实就是看当前位置的左右是否存在格挡,存在格挡可以存雨水,能存放的最大容积为左右出现的格挡的最大高度

第一步 声明变量初始值 left right maxLeft Maxleft res

第二步 从左右两边开始对比: for left < right {}

第三步 if height[left] < height[right] 则处理左边,否则处理右边

第四步 处理左边 如果当前位置(left)大于等于 maxLeft 则更新maxLeft 否则说明左边的高度是超出当前位置的,可以进行容积增加: maxLeft - height[left]

右边的逻辑和左边一样,发现右边的格挡更高,则增加高度差,否则更新高度最大值(当前值比maxRight更大)

js
func trap(height []int) int { left, right := 0, len(height)-1 leftMax, rightMax := 0, 0 res := 0 for left < right { if height[left] < height[right] { if height[left] >= leftMax { leftMax = height[left] } else { res += leftMax - height[left] } left++ } else { if height[right] >= rightMax { rightMax = height[right] } else { res += rightMax - height[right] } right-- } } return res }
2025-12-08
golang
00

相关信息

算法实现-golang实现交替打印数字字母

该题的关键在意通过channel进行控制

  • 声明一个数字ch,一个字母ch
  • 分别启动一个go 协程, 一直读取channel,读取到则进行消费,消费后,写入对方的信号到通道中
2025-11-27
golang
00

相关信息

golang基础学习

  • init的执行时机(一般可以理解为main执行之前)
      1. 运行时先初始化变量(非全局变量)
      1. init
      1. main
  • 字符串的小问题
go
①可以用==比较 ②不可以通过下标的方式改变某个字符,字符串是只读的 ③不能和nil比较
  • 数组定义问题 数组是可以通过下标定义的。case:
js
array := [...]int{1,2,3,9:34} 表示array[9]==34len(array)就是10
  • Go 支持什么形式的类型转换? 支持显示类型的转换
  • 空结构体
js
js
不包含任何字段的结构体叫做空结构体 struct{} 定义: var et struct{} et := struct{}{} type ets struct {} / et := ets{} / var et ets 特性: * 所有的空结构体的地址都是同一地址,都是zerobase的地址,且大小为0 使用场景: * 用于保存不重复的元素的集合,Go的map的key是不允许重复的,用空结构体作为value,不占用额外空间。 * 用于channel中信号传输,当我们不在乎传输的信号的内容的时候,只是说只要用信号过来,通知到了就行的时候,用空结构体作为channel的类型 * 作为方法的接收者,然后该空结构体内嵌到其他结构体,实现继承