260326 thinking kmp
1. kmp在计算机科学中,字符串匹配是一个非常基础且高频的问题:给定一个主串 S 和一个模式串 P,我们需要在 S 中找到 P 出现的位置。 最直观的暴力匹配算法(Brute-Force)十分简单粗暴:用两个指针 i 和 j 分别指向 S 和 P,如果字符匹配,就齐头并进;一旦遇到不匹配的字符,主串指针 i 就要被迫“回退”到上一次开始匹配的下一个位置,而模式串指针 j 则回到起点重新开始。这种做法在最坏情况下的时间复杂度高达 $O(n \times m)$。 KMP算法(由 Knuth、Morris 和 Pratt 三人共同发明)的伟大之处就在于:它向我们证明了主串指针 i 是不需要回退的。 为什么可以不回退?因为在发生不匹配之前,前面那部分字符我们已经实打实地比较过了。KMP 算法的核心思想就是榨干这些“已知匹配信息”的全部价值。既然已经知道前面有哪些字符是匹配的,当在某个位置发生失配时,我们不让 j 回到起点,而是让它滑动到一个“最合理”的位置继续和当前的主串字符比较。 比如模式串 p=aabaad,主串 s=aabaabaad。当 p[5] 与 s[5]...
251122 tool Nginx
1. 问题情景在aliyun服务器(ubuntu)上部署了一个后端服务,端口为 8080。然而,由于安全策略的限制,外部无法直接<ip>:8080访问该端口。 2. 解决方案配置 Nginx 作为反向代理,将外部请求转发到该后端服务即可。 2.1. 配置Nginx 安装Nginx 12sudo apt updatesudo apt install nginx 2.2. 反向代理编辑Nginx配置文件 1sudo vim /etc/nginx/sites-available/default 在 server 块中添加以下配置: 123456location /api/ { proxy_pass http://localhost:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;} 保存并退出编辑器,...
251122 thinking visitor
1. 什么是访问者模式访问者模式(Visitor Pattern)是一种行为型设计模式,它允许你在不改变对象结构(类)的情况下,定义作用于这些对象的新操作。 核心思想是将数据结构与数据操作分离。 通常情况下,对象的方法(操作)是定义在对象内部的。但在访问者模式中,我们将操作逻辑提取出来,封装在一个独立的“访问者”对象中。当我们需要对一组对象执行操作时,我们让这些对象“接受”访问者,然后访问者会根据对象的具体类型执行相应的逻辑。 2. 为什么需要访问者模式在软件开发中,我们经常面临这样的困境:我们有一个稳定的对象结构(例如一个包含不同类型节点的语法树,或者一个包含不同几何形状的绘图系统),但我们需要经常在这个结构上定义新的操作(例如语法检查、代码生成、计算面积、导出 XML...
251122 tool swagger
在后端开发中,接口文档与代码难以同步是常见的问题。Swagger 通过“代码即文档”的方式解决了这一点:开发者编写特定格式的代码注释,工具自动生成标准化的 API 文档和交互式调试页面。 本文主要介绍如何在 Go 后端项目中集成 Swagger。 1. 环境准备在项目根目下执行安装命令: 123456# 1. 安装文档生成器 (CLI)go install github.com/swaggo/swag/cmd/swag@latest# 2. 安装 Gin 适配器go get github.com/swaggo/gin-swagger@latestgo get github.com/swaggo/files@latest 2. swagger注释语法详解Swagger 的核心在于写对注释。注释分为全局配置和接口配置。 2.1 全局配置 (main.go)放在 main 函数上方,用于定义文档的通用信息。 123456// @title 项目名称 (如: 支付系统 API)// @version 1.0// @description ...
251122 thinking template
1. 什么是模板方法模式?模板方法模式(Template Method Pattern)是一种行为设计模式,它在一个方法中定义一个算法的骨架,而将一些步骤的实现延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。核心便是利用了多态性,父类定义了算法的骨架,子类实现具体的步骤。 在 Go 语言中,由于没有经典的类继承,模板方法模式通常通过接口和结构体嵌入来模拟。 2. 为什么需要模板方法模式?当你发现多个类有相似的算法,但只在某些细节上有所不同时,模板方法模式就非常有用。 代码复用:将所有子类中通用的算法逻辑提取到唯一的父类中,避免代码重复。 框架控制:它定义了一个框架,让子类在不改变框架结构的前提下,填充特定的业务逻辑。这在开发框架或库时非常常见。 遵循开闭原则:你可以在不修改模板方法的情况下,引入新的子类来扩展功能。 3. 模板方法模式的实现(go)以一个通用的“资源下载器”为例。无论从 HTTP 还是 FTP 下载,其核心流程是固定的:初始化 -> 下载数据 -> 保存文件 ->...
251122 thinking strategy
1. 什么是策略模式?策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端。 核心思想是:当一个任务有多种处理方式(策略)时,将这些方式抽象成一个共同的接口,并为每种方式提供一个具体的实现类。环境(Context)角色持有一个策略接口的引用,从而能在运行时动态地切换和使用不同的策略。 与状态模式不同,策略模式的各种策略是独立的,客户端需要知道所有的策略,才能选择合适的策略。而状态模式的各种状态是相关的,客户端只需要知道当前状态,就可以根据状态转换规则自动切换到下一个状态。 2. 为什么需要策略模式?在软件开发中,我们经常会遇到需要根据不同条件选择不同行为的场景。最直接的方法是使用 if-else 或 switch-case 结构。但当分支逻辑变得复杂,或者需要频繁增删新的分支时,这种方式会导致代码臃肿、难以维护,并且违反了“开闭原则”(对扩展开放,对修改关闭)。 策略模式正是为了解决这个问题而生。它有以下优点: 简化条件逻辑:将复杂的 if-else...
251122 thinking state
1. 什么是状态模式状态模式(State Pattern)是一种行为型设计模式,它允许对象在其内部状态改变时改变其行为。状态模式将对象的状态封装成独立的类,使客户端可以透明地切换对象的状态。 为了方便理解,这里引入有限状态机(Finite State Machine)的概念。 1.1 有限状态机有限状态机(Finite State Machine,FSM)是一个数学模型,它包含一组有限的状态、一组输入事件、一个初始状态以及一个状态转移函数。FSM 在任何给定时间点都处于其中一个状态。当接收到输入事件时,它会根据状态转移函数转换到新的状态。 状态模式可以看作是 FSM 的一种面向对象实现。 2. 为什么需要状态模式当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变行为时,可以使用状态模式。状态模式可以将与特定状态相关的行为局部化,并且使得状态转换显式化。 3. 状态模式的实现(go)让我们以一个自动售货机为例。售货机有以下几种状态: hasItem: 有商品状态 noItem: 无商品状态 itemRequested: 商品请求状态 hasMoney:...
251114 thinking jwt
1. 什么是 JWT?JWT 全称是 JSON Web Token,由三部分组成,用点 . 隔开。例如: xxxxx.yyyyy.zzzzz Header (头部) - xxxxx 内容 :记录令牌的类型(就是 JWT)和加密算法(比如 HMAC SHA256)。 作用 :告诉服务器怎么去解读这张令牌,包括令牌的类型和加密算法。 Payload (载荷) - yyyyy 内容 :承载声明,存放实际的用户信息。一般为Subject(主体标识)、ExpiresAt(过期时间)、IssuedAt(签发时间)、Issuer(签发者)、NotBefore(生效时间)等。这部分内容是公开的,任何人都能解码看到,所以不能放密码等敏感信息。 作用 :让服务器知道当前请求是谁发起的,有什么权限。 Signature (签名) - zzzzz 内容 :由服务器的密钥对前两部分签名,生成的防伪标识。它是通过把头部和载荷组合起来,再加上一个只有服务器知道的“密钥”(Secret),然后用头部声明的加密算法生成的。 作用 : 防伪...
251114 thinking observer
1. 什么是观察者模式?观察者模式(Observer Pattern)用于在对象状态变化时,通知依赖它的多个观察者,实现一种一对多的订阅关系。被观察者只负责发布事件,不关心有多少观察者、它们如何处理,达到发布方与订阅方的解耦。 2. 为什么需要观察者模式?当一个对象的变化需要联动多个组件时,若直接在对象内部逐个调用这些组件,将产生紧耦合和复杂的依赖。当组件增删或行为变化时,被观察者也不得不调整。通过观察者模式,我们将事件的发布与处理分离:被观察者只负责发出信号,观察者各自处理,从而降低耦合、提高扩展性。 3. 观察者模式的实现(go)1234567891011121314151617181920212223242526272829303132333435363738394041424344type Observer interface { Update(event string, data any)}type Subject interface { Register(o Observer) Unregister(o...
251114 thinking memento
1. 什么是备忘录模式?备忘录模式(Memento Pattern)用于在不破坏封装的前提下,捕获并保存对象的内部状态,以便之后将其恢复。核心思想是:状态快照应对外保持不透明,只有创建它的对象才能读写其内容。 2. 为什么需要备忘录模式?在需要撤销/重做、事务性修改或阶段性试错的场景中,我们希望随时回到某个稳定的历史状态。如果将内部状态直接暴露给外部组件,会破坏封装并引入脆弱耦合。备忘录提供了一种更稳妥的做法:外部只负责保存与传递快照,而不窥视其内容;状态的读写权严格归属于原始对象本身。 3. 备忘录模式的实现(go)下面的实现采用“封装最严格”的变体:看护者只能看到窄接口 Memento,无法读取或修改状态;只有发起者可以访问具体备忘录以进行恢复。 123456789101112131415161718192021222324252627282930313233type Memento interface{ mementoMarker() }type memento struct{ content string cursor...