自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

  • 博客(26)
  • 收藏
  • 关注

原创 Gin 框架核心架构解析

Gin是一个基于Go语言的轻量级Web框架,其核心设计利用了Go的net/http库和并发模型。框架通过Engine结构体实现http.Handler接口,关键流程包括:为每个请求分配可复用的gin.Context对象(通过sync.Pool优化性能),处理请求时解析路由并执行中间件链,最后将上下文对象归还对象池。这种设计实现了业务逻辑与网络细节的解耦,同时通过goroutine和对象池技术保证了高并发性能。

2025-08-11 20:22:37 1124

原创 数字图像处理(图像增强)——拉普拉斯算子

二阶微分与微积分中定义的微分略有不同,数字图像中处理的是离散的值,因此对于一维函数的一阶微分的基本定义是差值: ∂f∂x=f(x+1)−f(x)∂f∂x=f(x+1)−f(x) \frac{\partial f}{\partial x} = f(x+1) - f(x) 类似的,二阶微分定义为: ∂2f∂x2=f(x+1)+f(x−1)−2f(x)∂2f∂x2=f(x+1)+f(x−1)...

2018-07-09 12:11:26 18967 3

原创 Goroutine + Channel 高效在哪?一文吃透 Go 并发底层 G-M-P 调度与实现

Go语言的高效并发实现解析 Go语言凭借其独特的并发模型在服务端和云计算领域脱颖而出。其核心优势源于对CSP(通信顺序进程)范式的实践,通过"通过通信来共享内存"的理念取代传统共享内存模型。Go语言通过两个核心组件实现这一哲学:轻量级执行单元Goroutine和通信管道Channel。 Goroutine采用M:N调度模型,将大量应用级并发单元复用到少量OS线程上,极大降低了资源开销。每个Goroutine初始仅分配2KB栈空间,且切换由用户空间的Go运行时管理,避免了昂贵的内核上下文切

2025-12-08 16:33:06 1100

原创 深入浅出 Go slices 包:类型安全、内存安全与高性能实践

Go 1.21引入了slices包,提供类型安全、高效的原生切片操作API,替代传统的append和闭包排序等模式化代码。主要功能包括查找、排序、修改、容量管理、组合连接、比较和迭代器操作。本文先列出slices包的功能概览,之后对删除、排序功能进行详细的解析

2025-10-13 15:53:41 646

原创 Go 泛型实战:一行代码封装 sync.Pool,性能与安全兼得

摘要:本文介绍如何使用Go泛型构建类型安全的sync.Pool包装器,解决原生sync.Pool存在的类型安全和代码冗余问题。通过分析Gin框架案例,指出原生sync.Pool需要手动类型断言的痛点。文章详细展示了如何设计泛型Pool结构体,包括New构造器、类型安全的Get/Put方法实现,并通过零值处理保证健壮性。该方案在保持sync.Pool高性能优势的同时,提供了编译期类型检查、更简洁的API,且不引入额外开销。最终实现已开源为gpool库,包含完整测试和CI保障。

2025-09-10 22:38:40 702

原创 深度揭秘 sync.Pool:Go 高性能对象池的设计哲学与源码实现

文章首先从CPU多级缓存架构引入,类比分析sync.Pool的分级缓存设计哲学,揭示其通过private(一级本地缓存)和shared(二级共享队列)的双层结构实现高效对象复用。随后详细解析了Put和Get操作的源码实现,包括优先访问本地无锁private槽位、共享队列操作以及跨处理器窃取机制。特别指出sync.Pool通过victim缓存机制在GC时保留对象,显著减少了内存分配和GC压力。这种设计使得Gin框架在高并发场景下能够高效处理请求,避免频繁创建销毁Context对象带来的性能损耗。

2025-09-03 14:19:56 654

原创 告别重复,用Go泛型精简Gin代码

本文介绍如何利用Go泛型优化Gin框架中的CRUD接口开发。通过定义`CURD`类型约束,可以大幅减少重复代码,文中展示了具体的实现方法:只需让资源类型实现CURD接口,就能用一行代码注册Create路由。这种泛型方案显著提高了代码复用性和开发效率。

2025-08-26 17:24:28 410

原创 Go泛型实战:告别interface{}地狱,从零拆解数据流处理库

【Go泛型实战:从入门到掌握】 你是否曾被Go泛型复杂的类型约束困扰?本文通过一个数据流处理库LaPluma,带你轻松掌握泛型核心概念。

2025-08-19 20:28:26 588

原创 La Pluma: 一个轻盈的 Go 数据流处理库

La Pluma 是一个轻量级 Go 数据处理工具库,提供串行(Iterator)和并发(Pipe)两种数据处理方式。库设计强调简洁性和可组合性,包含 Map、Filter、Reduce 等基础操作,支持链式调用构建数据处理流水线。Iterator用于串行处理,Pipe则利用 channel 和 context 实现并发处理及超时控制。库采用两种错误处理模式:前置过滤和 TryMap 容错机制。支持将结果转换为标准 Go 迭代器,便于集成。未来计划增加更多转换操作并完善并发控制。

2025-08-12 17:47:24 622

原创 lua 实现简单的ip4过滤

基于lua实现的对ip地址的过滤器,支持掩码,网络段的方式。目前只支持ipv4格式的ip地址

2023-04-29 20:37:12 1067

原创 从零开始的Socket编程 一

本文先介绍了socket通信的基本流程,然后介绍了socket通信相关的接口.

2022-11-06 17:47:16 1134

原创 从零开始的Socket编程 零

介绍Socket的概念,了解Socket是什么以及Socket被设计出来是为了做什么的;然后介绍Socket的原理

2022-11-05 15:29:40 575

原创 C++实现Go中的Slice

使用C++实现类似Go中的slice的功能

2022-05-22 11:36:09 836

原创 《软件设计的哲学》读后感

引言在知乎上看到有人推荐《软件设计的哲学》,遂找来读了。或许是由于个人水平有限,虽然感觉确实不错,但是却没有推荐的那么好。复杂度书中的核心观点认为软件开发的关键在于控制复杂度,以便后续的维护和扩展功能。类似的观点在《代码大全》中也有看到过——《代码大全》提到,管理软件实质上是管理复杂度。《软件设计的哲学》认为,复杂度会导致:修改放大、增加认知负荷和“未知的未知”,这三种现象最终导致了软件的难以维护。而软件的复杂度不是一下子就变得很复杂的,而是在开发的过程中不断积累,最终导致整个软件变得越来越复杂,

2022-05-16 23:06:30 458

原创 Go的声明语法

Go的声明语法引言Go的声明语法与C家族的声明语法不同,在Go’s Declaration Syntax中解释了为什么Go要选择这种与众不同的语法。本文为该文的翻译,个人水平有限,权做参考,如有错误,欢迎指出C 语法先来看看C语言的语法。C语言采用了一种不寻常但是巧妙地声明语法——不是用特殊语法描述类型,而是编写一个包含要声明的项的表达式,并声明该表达式的类型。如:int x;将x声明为int类型:表达式x的类型是int。一般来说,要声明一个新变量的类型,需要写一个包含该变量的表达式,该表达式

2021-10-24 12:00:38 213

原创 uuid与自增id的区别与使用

最近在使用数据库要建表选择主键的时候,突然想到经常使用的两类主键id——自增id和UUID有什么区别,用那种更好?之前使用MySql的时候通常直接就选择了自增id了,工作的时候也看到有些项目使用UUID做主键,但是都没怎么考虑两者的区别,优缺点之类的。现在要键新表选择主键的时候,就需要考虑选择哪种做主键了,因此就有了这篇文章本文首先分别简单为什么数据库需要主键,然后介绍自增id和UUID,接着比较两者的区别,最后给出何时使用哪种类型做主键更好。关系型数据库中的主键在关系型数据库模型中,关系型数据库是一

2021-10-10 17:50:49 8633

原创 C++解析multipart/form-data

背景使用boost.beast实现简单的HTTP服务,但是boost.beast没有提供对表单数据的解析,为此需要自己实现解析表单数据。application/x-www-form-urlencoded的格式与URL的查询字符串格式一样,只是会被URL编码,比较容易处理但multipart/form-data相对而言比较复杂multipart/form-datamultipart/form-data主要是为了解决application/x-www-form-urlencoded编码格式在传输大量二

2021-08-03 15:01:22 8388 13

原创 基于mongocxx实现对MongoDB存储的文件的随机读取

背景最近所开发的项目使用MongoDB的GridFS保存文件,且文件大部分均大于500M,在程序运行过程中需要读取文件数据进行处理。但是MongoDB提供的mongocxx只能将整个文件下载下来或者暂时保存在内存中。每次处理数据都需要下载到本地是比较耗时的,且每次处理完还需要删除临时文件。GridFS是将一个大文件分成多个chunk进行保存的,因此考虑每次进下载文件的一个chunk到内存中。总体设计为了对读取MongoDB中的文件与读取本地文件的接口统一起来,增加了一个抽象基类,对本地文件的读取也通

2021-08-03 08:55:47 506

原创 C++ const的使用

摘要在C++中,const可以用在很多的场合,本文尝试说明const常用的几种场景,并解释为什么要这样使用。const的含义在进行讨论之前,先说明const是个什么东西。const其实是一个语义约束,告诉编译器和其他程序员某值应该保持不变。在程序编译的过程中该约束由编译器保证,如果违反了const约束,编译报错。函数形参数列表最常使用const的大概就是在函数的参数列表了吧,如:int max(const int a, const int b);通常应该将函数的参数声明为const,告诉编

2021-03-28 21:15:22 630

原创 C++编程注意事项——构造函数

C++ 编程注意事项 —— 构造函数摘要构造函数使用explicit阻止隐式类型转换区分拷贝构造函数和赋值运算符的不同使用引用传递,避免值传递构造函数对于自定义的类型,使用explicit阻止执行隐式类型初始化对于用户自定义的类型,初始化由构造函数执行。将构造函数声明为explicit可以阻止隐式类型转换。被声明为explicit的构造函数通常比non-explicit的构造函数更好,除非有充分的理由,否则所有的构造函数都应该声明为explicit在显式类型转换使得程序员真的知道自己在做什么

2021-03-13 22:58:01 255 1

原创 SQL Server分页查询优化

在SQL Server上进行分页查询时,通常是使用offset-fetch实现select * from table_name order by keys offset begin_index rows fetch next counts rows only当然也可以使用Top或者RowNum实现分页查询,但这里讨论的主要的是使用offset-fetch进行分页的情况。一般来说,orde...

2019-12-07 22:56:18 1518

原创 C++实现ANSI编码转换为UTF-8编码格式文件

文章结构:本文的先介绍了常见的几种编码格式:ANSI,Unicode,UTF-8,在进行编码转换之前,需要先判断文件的编码格式,在编码转换完成之后,需要将文件保存为UTF-8编码格式的文件。文本文件编码格式介绍在计算机内部,所有的数据都是以二进制的形式存储的。在存储文本时,需要把文本信息转换为二进制进行保存,而在显示时则需要把二进制转换为文本信息显示出来。编码就是二进制与显示的字符之间转行的规...

2019-08-10 14:47:36 6864

原创 基数排序(C++实现)

基本思想基数排序(radix sort)又称桶排序(bucket sort)。主要用于整数的排序。通过提取整数的各个位的 值,将其存放到对应的桶中,再将各个桶按照顺序,将桶里面的值依次提取出来。进行多次循环,单次循环后数据还是处于无序状态,但是当最后依次循环完成时,数据是有序的。步骤得到要统计的数据中最大数的位数,作为循环的次数i从要排序的数据中取出一个数据提取出该值的当前位的值,将其...

2019-05-30 23:31:37 1221

原创 C++ 模板函数 二分查找

C++ 模板函数 二分查找简单二分查找使用模板函数实现二分查找接收函数指针作为比较函数进一步优化简单二分查找二分查找也称对半查找,是一种很常用的,高效率的搜索算法,时间复杂度为O(log N)。该算法假定要查找的数据已经升序排序完毕。算法的思路比较简单,在这里主要是作为一个C++模板函数的一次练习。下面是百度百科上对二分查找查找过程的介绍,忘记了的同学可以看看。首先,假设表...

2018-12-30 21:49:54 3951

原创 PHP system 调用外部程序并传递参数

PHP system() 调用外部程序并传递参数使用PHP的时候,需要调用已有的程序作为项目的一部分,因为已经存在程序,所以直接使用system()函数是最直接的想法。system的详细说明可以查看PHP手册的system注意事项使用system()函数调用外部程序时,当需要传递参数时,要注意书写的格式。当不需要要传递参数时,可以直接写成:$cmd = "path\...

2018-04-29 23:10:55 4057 1

原创 C++ lambda表达式

C++ lambda表达式C++11引入了lambda表达式,主要用来解决调用函数时需要传入一个可调用对象的情况。因为很多情况下,传入的函数只用一次,如果特地去声明一个函数,但是后面没有再次调用,此时的函数就失去了重用性。同时,有的函数接收的可调用对象只能接受含有一个参数的可调用对象,此时用lambda表达式可以很好的处理这种情况语法[捕获列表](参数列表)->返回类型{...

2018-04-15 22:05:11 457

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除