- 博客(23)
- 收藏
- 关注
原创 互联网到底是怎么组成的?它又为我们提供了哪些通信服务?
本文从构成和服务两个角度解析互联网。构成角度:网络由节点和边组成,互联网是以TCP/IP协议连接的全球网络,包含主机节点和数据交换节点,数据在各层封装成不同PDU。服务角度:互联网提供TCP(可靠、有序)和UDP(快速、不可靠)两种服务方式,分别适用于网页/文件传输和视频/游戏等场景。互联网通过标准化协议实现不同设备的互操作,由IETF制定RFC标准。
2026-05-17 20:58:34
341
原创 深入理解 Go 反射:原理、实践与性能陷阱
Go 反射是一套强大但复杂的机制,它扎根于接口的运行时表示,提供了和两大核心 API。通过三定律我们可以快速上手:从接口到反射对象、从反射对象回到接口、通过可寻址实现修改。然而,反射带来的性能损失、类型安全缺失、二进制膨胀等问题也不容忽视。在实际项目中,应当权衡使用反射的收益与成本。对于框架类、通用库的编写,适度的反射(如 JSON 编解码、依赖注入)可以大幅减少重复代码;但对于业务逻辑中的常规操作,优先考虑泛型、接口和代码生成。
2026-05-17 17:39:29
385
原创 深入理解 Go 语言文件操作:从基础到最佳实践
时,如果不加锁,就会出现竞态条件(race condition)—— 两个 goroutine 同时读取,彼此的偏移量互相覆盖,导致数据错乱或丢失。本文将带你系统学习 Go 语言中的文件处理知识,从打开文件、读写数据到权限控制、性能优化,逐步建立起完整的知识体系。的代价较高(涉及磁盘 I/O),适用于数据库日志、重要配置文件、事务记录等对持久性要求严格的场景。,它不仅要表达 Unix 经典的读/写/执行九位权限,还要存储文件类型(目录、符号链接等)和特殊属性位(Setuid、Sticky 等)。
2026-05-10 13:06:47
439
原创 深入理解 Go 语言错误处理:Error、Panic 与 Fatal
Msg stringErr errorCode int这种设计保留了原始错误的引用,同时增加了业务字段(如错误码)。上层代码可以用errors.As将MyError提取出来,读取Code字段。虽然panic听起来可怕,但它在一些场景下非常有用:比如在递归解析中遇到不可恢复的输入格式错误;或者在一个init函数中检查致命依赖。关键是如何用好recover。error 是值,要处理它:不要用忽略错误,除非有充分理由并添加注释说明。优先使用%w包装错误:这样可以保留错误链,方便上层用Is/As判断。
2026-05-05 16:15:41
359
原创 Go 迭代器与数据流处理
摘要:Go语言迭代器与数据流处理 本文系统介绍了Go语言中的迭代器模式和数据流处理技术。主要内容包括: 迭代器模式:分为推送式(生产者控制)和拉取式(消费者控制)两种实现方式。Go 1.18引入泛型后,迭代器实现更加统一,通过iter包和range over func特性简化了推送式迭代器的使用。 链式调用:一种通过方法返回对象本身实现连续调用的编程风格,常用于构建复杂查询或配置,具有表达力强、减少临时变量等优点。 数据流处理:利用Go的goroutine和channel特性构建高效流水线,支持实时数据处理
2026-04-26 09:44:35
372
原创 单调栈原理、模板与应用
单调栈是一种特殊的栈结构,它保证栈内元素(通常是数组的下标或值)从栈底到栈顶保持单调递增或单调递减。单调递增栈:栈底到栈顶元素值递增(即栈顶最小)。单调递减栈:栈底到栈顶元素值递减(即栈顶最大)。单调栈主要用于解决“下一个更大/更小元素”问题,以及由此衍生的接雨水、最大矩形面积等经典问题。它的核心优势是O(n) 时间复杂度,远优于暴力法的 O(n²)。单调栈是解决“下一个更大/更小元素”问题的利器,时间复杂度 O(n)。核心在于维护栈的单调性,并在破坏时弹出栈顶进行结算。
2026-04-20 23:50:12
371
原创 Go 泛型从原理到实践
Go语言泛型(Go 1.18+)通过参数化多态机制解决了类型安全与代码复用问题。采用基于"形状"的分组单态化方案,在性能、编译速度和代码体积间取得平衡。语法上支持泛型函数、类型及类型集约束(如comparable、any),允许定义并集/交集类型约束。泛型简化了通用数据结构(如对象池)的实现,同时保持类型安全,显著提升了代码复用性而不牺牲性能。
2026-04-18 09:26:07
392
原创 Go 语言接口:从基本接口到通用接口
Go语言接口是构建灵活程序的核心工具,通过定义方法签名实现"面向接口编程"。1.18版本引入泛型后,接口概念扩展为"通用接口"。基本接口通过方法签名实现多态,空接口(any)可容纳任意类型但存在运行时开销。接口底层由iface/eface结构体实现,包含类型信息和数据指针。类型断言和类型选择用于从接口还原原始类型。设计时应权衡接口的灵活性与性能开销,遵循开闭原则实现扩展性。
2026-04-12 17:45:27
371
原创 拓扑排序与关键路径详解
拓扑排序是 DAG 的线性化,Kahn 算法和 DFS 方法均能高效求解,且可检测环的存在。关键路径基于拓扑排序,通过正向求 etv 和反向求 ltv 找出关键活动,帮助项目经理合理调配资源、压缩工期。两种算法紧密关联:关键路径的计算依赖于拓扑序列,而拓扑排序又是处理依赖图的基础。
2026-04-06 11:09:39
343
原创 简单贪心(洛谷刷题笔记)
贪心算法虽然简单高效,但并非万能。当问题不满足局部最优无法保证全局最优,此时就需要动态规划来求解。选择之间存在依赖关系:当前选择会影响未来可选集合的质量。存在后效性:当前决策会影响后续状态。无法通过单一排序规则确定最优顺序。
2026-03-24 09:31:39
395
原创 自平衡二叉搜索树——AVL树
当child有右节点grand_child时,将grand_child作为node的左子节点,让node成为child节点的右节点,让node的父节点指向child。记失衡节点为node,左子节点为child,让node节点成为child节点的右节点,让node的父节点指向child。失衡节点的右子树高度比左子树高度大2,且失衡节点右孩子的平衡因子通常为0或-1(右子树等高或更高)失衡节点的左子树高度比右子树高度大2,且失衡节点左孩子的平衡因子通常为0或1(左子树等高或更高)(空节点高度为-1)
2026-03-21 21:16:03
319
原创 go语言基础语法
是操作系统进行资源分配和保护的基本单位,有独立的内存空间,进程间默认不共享内存,若需要通信必须用进程间通信机制,由操作系统内核调度,创建和销毁开销较大。只有直接父目录及其子目录下的包,才能访问内部包里的内容,外部包(同级目录中的包)无法访问内部包中的任何内容。iota是一个内置的常量标识符,在const中,从0开始,每遇到一个常量声明(每换一行)就自动加1。导入后,该包中所有类型被导入当前包作用域,无需使用一般的访问包的方法,直接使用标识符即可。内置函数,从Go 1.21开始引入的。
2026-03-15 16:00:23
395
原创 简单动态规划刷题笔记
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,每当爬上一个阶梯都要花费对应的体力值,一旦支付了相应的体力值,就可以选择向上爬一个阶梯或者爬两个阶梯。分隔完成后,每个子数组的中的所有值都会变为该子数组中的最大值。已编码的消息时,你意识到有许多不同的方式来解码,因为有些编码被包含在其它编码当中(**注意:**不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。今天的有氧运动训练内容是在一个长条形的平台上跳跃。
2026-03-07 23:58:49
363
原创 双指针法(力扣总结)
这道题就是使用同向指针,让左指针为最终结果,右指针来判断是否是val,若不应删除,则可以将右指针的值赋给左指针,若应删除,则不让左指针的值成为右指针中的值。最终的数组长度应以左指针的位置为准。这道题不能开新的数组来存放字符串,进行原地修改时,就需要用到对撞指针,让左指针在开头开始移动,右指针在最后开始移动,交换两个指针中的值,不断逼近,直到相遇。判断的方法就是典型的快慢指针,后一个指针的移动速度大于前一个指针的移动速度,只要链表中有环,就一定会在一个节点处相遇。类型的指针,还可以是数组的下标、链表的节点。
2025-12-14 00:46:12
1100
原创 二叉搜索树
二叉搜索树又称为二叉排序树它的特点:任意子树的左子树值<根节点值<右子树值这样的特点使二叉搜索树在进行中序遍历的时候,会以升序的方式读取每个节点。
2025-12-01 22:35:42
630
原创 树、二叉树的遍历、线索二叉树
树: 一个或多个节点的有限集合 存在一个称为根的特定节点节点:树中的一个独立单元节点的度: 节点所拥有的子树数称为节点的度树的度: 树内各节点度的最大值叶子: 度为0的节点非终端节点: 度不为0的节点双亲和孩子: 节点的子树的根称为该节点的孩子,相应的,该节点称为孩子的双亲层次:节点的层次从根开始定义,根为第一层,根的孩子为第二层,以此类推。
2025-11-26 22:40:53
922
原创 [数据结构]哈希表 (环形链表)
哈希表是通过索引值直接访问具体数值的数据结构,通过建立键与值之间的映射,实现高效的元素查询。哈希表(Hashing)也被成为散列表。
2025-11-23 11:47:47
849
原创 时间复杂度和空间复杂度
解决一个问题会有很多的思路方法,不同的方法是好是坏需要一个评判的标准。那么如何评价一个算法的优劣呢?如果单纯是通过计算机上运行来看,如果同一个算法在不同电脑上运行,电脑的硬件不同,执行代码速度不同,就很难比较算法的优劣。就算保证了硬件条件的统一,对于少量的数据处理,执行速度也很难被直接观察到,需要大量大规模的数据,才能辨析哪种算法的速度快。为了避免这样的缺陷,算法的优劣不依赖于实际执行所需时间来判断,时间复杂度和空间复杂度就成为评估算法效率的两个核心标准。
2025-11-13 22:14:05
1027
原创 c语言写出学生管理系统
一个完整的代码,头文件是不可少的,这个系统要用到以下头文件(这包含输入输出、文件操作)(这包含动态分配、系统命令执行)(这包含了字符串的比较、复制、搜索)用户的账户密码使用数组存放,数组的大小是固定的,提前使用宏定义在开头来规定最大值,易于修改,最大值一致,也可以避免缓冲区溢出和内存浪费,虽然可以用const来声明一个一致的常量,但是const在某些编译器中不能声明数组大小202020201020缓冲区是计算机中用于临时存储数据的一块内存区域,用于在不同速度的设备和程序之间暂存数据。
2025-11-09 13:24:34
579
原创 链表的基础知识和单向链表的基本操作
链表是一种物理存储上非连续,数据元素的逻辑顺序通过链表中的指针链接次序,实现的一种线性存储结构。与数组的功能非常相似,数组是存放一组相同类型元素的集合与数组的比较中,可以看出它们的不同适用场景由链表的定义可知,在物理储存上不连续,所以在创建的时候由一个个节点组成,节点会包括两部分,一个是,用来将不连续的地址联系起来,有了连续的逻辑顺序后,需要有,用来存放所需数据本身以单链表为例链表按连接方式可以分为。
2025-10-28 21:52:56
669
原创 递归的理解
第二个例子中,当我输入40运行的时候,发现电脑卡顿了一会儿才出现值,通过ai搜索,我发现递归的写法会出现很多重复计算的过程。把⼀个复杂的问题中不断拆分成小的问题,并将拆分出来的小问题的结果一层一层组合,最终得到原问题的过程。实际上只需要计算一次,当数字变大的时候,被重复计算的数字越来越多,导致计算时间变长。每个函数调用都会创建一个栈帧 栈的空间是有限的 递归调用后不会立即返回,会积累栈帧。栈溢出是程序使用的栈内存超过了系统为其分配的栈空间限制,导致程序的异常行为。栈的内岑布局是栈底—栈帧—栈帧—栈帧……
2025-10-24 22:57:06
360
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅