├── .gitignore ├── Java ├── Java.md └── 资料库 │ └── 高质量网站.md ├── README.md ├── Redis ├── redis分布式锁及双重校验.md └── 面经 │ └── redis面经.md ├── elasticsearch ├── README.md ├── go.mod ├── go.sum ├── images │ ├── es_interview │ │ ├── img.png │ │ ├── img_1.png │ │ ├── img_2.png │ │ ├── img_3.png │ │ └── img_4.png │ └── es_restful │ │ ├── img.png │ │ ├── img_1.png │ │ └── img_2.png ├── study │ ├── ES_RESTFUL_README.md │ ├── exercise │ │ ├── elastic-go-elasticsearch.go │ │ ├── go-elasticsearch.go │ │ └── olivere-elastic.go │ ├── search │ │ └── search.go │ ├── ♥ElasticSearch知识体系详解♥ │ │ ├── ES详解 - 优化:ElasticSearch性能优化详解.md │ │ ├── ES详解 - 入门:查询和聚合的基础使用.md │ │ ├── ES详解 - 原理:ES原理之索引文档流程详解.md │ │ ├── ES详解 - 原理:ES原理之读取文档流程详解.md │ │ ├── ES详解 - 原理:ES原理知识点补充和整体结构.md │ │ ├── ES详解 - 原理:从图解构筑对ES原理的初步认知.md │ │ ├── ES详解 - 安装:ElasticSearch和Kibana安装.md │ │ ├── ES详解 - 索引:索引模板(Index Template)详解.md │ │ ├── ES详解 - 索引:索引管理详解.md │ │ ├── ES详解 - 认知:Elastic Stack生态和场景方案.md │ │ └── ES详解 - 认知:ElasticSearch基础概念.md │ └── 各种查询的golang实现 │ │ ├── es实现mysql or查询.md │ │ ├── es实现mysql where in 查询.md │ │ ├── es根据app.Id分组,统计每组的OwnerBid数量,过滤空值并去重.md │ │ ├── es根据appId分组,对某一字段求和es根据appId分组,对某一字段求和.md │ │ ├── 根据 series_Id 字段分组,对dna中id字段count总数,dna_price字段sum求和.md │ │ └── 根据app.Id分组,统计每组dna数量.md ├── 场景 │ ├── 哈啰:记录一次ElasticSearch的查询性能优化.md │ ├── 腾讯Elasticsearch海量规模背后的内核优化剖析.md │ └── 腾讯万亿级 Elasticsearch 技术解密.md └── 面经 │ └── ES_INTERVIEW_README.md ├── go.mod ├── go.sum ├── golang ├── README.md ├── go-Interview │ ├── GOALNG_INTERVIEW_COLLECTION.md │ ├── data-structure │ │ ├── array │ │ │ ├── array.go │ │ │ └── array_test.go │ │ ├── linear_list │ │ │ ├── link_list │ │ │ │ ├── circular_linked_list.go │ │ │ │ ├── circular_linked_list_test.go │ │ │ │ ├── double_linked_list.go │ │ │ │ ├── double_linked_list_test.go │ │ │ │ ├── link_list.go │ │ │ │ ├── link_list_test.go │ │ │ │ └── 单链表.go │ │ │ └── sequence_list │ │ │ │ ├── sq_list.go │ │ │ │ └── sq_list_test.go │ │ └── 二叉树 │ │ │ └── 二叉树.go │ ├── 实战 │ │ ├── MetaApp │ │ │ └── 第一题.go │ │ ├── meatApp │ │ │ ├── A.go │ │ │ └── B.go │ │ ├── meatapp9.2 │ │ │ ├── 第一题.go │ │ │ └── 第二题.go │ │ ├── 一览科技 │ │ │ ├── 校招 │ │ │ │ └── Go语言实现并行分段求和计算.go │ │ │ └── 社招 │ │ │ │ └── a.go │ │ ├── 三七互娱 │ │ │ ├── a.go │ │ │ └── 面经.md │ │ ├── 上海弘连网络8月23 │ │ │ ├── 10.go │ │ │ ├── 2.go │ │ │ ├── 3.go │ │ │ ├── 4.go │ │ │ ├── 5.go │ │ │ ├── 6.go │ │ │ ├── 7.go │ │ │ ├── 8.go │ │ │ └── 9.go │ │ ├── 乐城堡校招 │ │ │ ├── 一.go │ │ │ ├── 三.go │ │ │ ├── 校招笔试题V2.pdf │ │ │ └── 笔试题目.md │ │ ├── 依对-2024-7-9 │ │ │ └── a.go │ │ ├── 决策数后端测试题 │ │ │ └── 字符串中连续重复出现次数最多的字符和次数.go │ │ ├── 北京枫悦互动 │ │ │ └── CrazyMapleStudio枫叶互动.md │ │ ├── 北京竞业达数码科技股份有限公司 │ │ │ ├── a.go │ │ │ └── 面经.md │ │ ├── 北京蓝城兄弟-24-8-27 │ │ │ ├── a.go │ │ │ └── 面经.md │ │ ├── 哈乐沃德 │ │ │ ├── a.go │ │ │ └── 面经.md │ │ ├── 哔哩哔哩 │ │ │ ├── a.go │ │ │ └── 面经.md │ │ ├── 天龙互娱 │ │ │ └── 面经.md │ │ ├── 好未来 │ │ │ ├── 实习 │ │ │ │ └── README.md │ │ │ ├── 技术体系-数字效能部-知音楼-golang开发工程师-24-08-12 │ │ │ │ ├── a.go │ │ │ │ ├── b.go │ │ │ │ └── 面经.md │ │ │ └── 数字效能部-用户中台-07-31 │ │ │ │ ├── a.go │ │ │ │ └── 面经.md │ │ ├── 广州伽马 │ │ │ ├── 岗位要求作业—计数器.zip │ │ │ └── 计数器 │ │ │ │ ├── main.go │ │ │ │ └── statistics │ │ │ │ └── statistics.go │ │ ├── 度小满 │ │ │ ├── 后端开发工程师—技术体系-24-9-3 │ │ │ │ └── a.go │ │ │ └── 实习 │ │ │ │ ├── Golang使用协程和channel顺序打印1-10.go │ │ │ │ ├── 协程调度2.go │ │ │ │ ├── 线程调度-waitgroup.go │ │ │ │ └── 线程调度.go │ │ ├── 得物-2024-7-10 │ │ │ ├── a.go │ │ │ ├── b.go │ │ │ ├── c.go │ │ │ └── 面经.md │ │ ├── 懂球帝 │ │ │ ├── a.go │ │ │ └── 面经.md │ │ ├── 搜狐畅游 │ │ │ ├── 0802 │ │ │ │ └── a.go │ │ │ └── AI 系统工程师 0723 │ │ │ │ └── 面经.md │ │ ├── 昆仑万维-2024-7-9 │ │ │ └── 面经.md │ │ ├── 格林深瞳 │ │ │ ├── CircularBuffer │ │ │ │ └── CircularBuffer.go │ │ │ └── area.go │ │ ├── 格林深瞳9月21面 │ │ │ ├── a.go │ │ │ └── 面经.md │ │ ├── 格林深瞳笔试 │ │ │ ├── README.md │ │ │ ├── img.png │ │ │ └── 查找数组最大元素.go │ │ ├── 欧科云链 │ │ │ └── slice.go │ │ ├── 武汉微派网络(贪吃蛇) │ │ │ ├── a.go │ │ │ └── 面经.md │ │ ├── 沐瞳科技 │ │ │ ├── a.go │ │ │ └── 面经.md │ │ ├── 泡泡玛特-2024-7-12 │ │ │ └── 面经.md │ │ ├── 深信服 │ │ │ ├── 校招 │ │ │ │ └── 校招golang一面11月7号.md │ │ │ └── 社招 │ │ │ │ └── 后台开发-深圳-24-08-26 │ │ │ │ ├── a.go │ │ │ │ └── 面经.md │ │ ├── 滴滴 │ │ │ ├── 两轮车事业部07-30 │ │ │ │ ├── a.go │ │ │ │ └── 面经.md │ │ │ ├── 滴滴国际化-24-7-22 │ │ │ │ ├── a.go │ │ │ │ └── 面经.md │ │ │ └── 聚合代驾2024-8-26 │ │ │ │ ├── a.go │ │ │ │ └── 面经.md │ │ ├── 爱诗科技 │ │ │ ├── a.go │ │ │ └── 面经.md │ │ ├── 王牌游戏-2024-7-14 │ │ │ ├── a.go │ │ │ ├── 【王牌游戏】后端工程师-测试题.docx │ │ │ ├── 【王牌游戏】高潜策划管培生-测试题2.0.docx │ │ │ ├── 测试题 │ │ │ │ ├── 1.go │ │ │ │ ├── 2.go │ │ │ │ ├── 3.go │ │ │ │ ├── 4.go │ │ │ │ ├── 5.go │ │ │ │ └── 6.go │ │ │ └── 面经.md │ │ ├── 百度 │ │ │ ├── 小度智能助手业务部-07-30 │ │ │ │ ├── a.go │ │ │ │ ├── b.go │ │ │ │ └── 面经.md │ │ │ ├── 推荐产品研发组_GOPHP研发工程师-8-29 │ │ │ │ ├── a.go │ │ │ │ ├── b.go │ │ │ │ └── c.go │ │ │ ├── 百度-服务体验发展中心_Java工程师实习-面试 │ │ │ │ ├── README.md │ │ │ │ └── baidu.go │ │ │ ├── 百度2022年春实习招聘研发A卷3.22 │ │ │ │ └── 像素.go │ │ │ ├── 百度国际化-2024-7-8 │ │ │ │ ├── 1-a.go │ │ │ │ ├── 1-b.go │ │ │ │ ├── 2-a.go │ │ │ │ └── 面经.md │ │ │ ├── 百度在线-2024-7-10 │ │ │ │ ├── a.go │ │ │ │ ├── b.go │ │ │ │ └── 面经.md │ │ │ └── 百度电商-24-9-29 │ │ │ │ └── a.go │ │ ├── 知乎-cgl │ │ │ └── a.go │ │ ├── 知乎 │ │ │ ├── a.go │ │ │ ├── img.png │ │ │ └── 题目.md │ │ ├── 科大讯飞 │ │ │ └── contex和channel配套使用 │ │ │ │ └── 并发.go │ │ ├── 腾娱互动 │ │ │ ├── 武汉-Z业务部-广告 │ │ │ │ ├── a.go │ │ │ │ └── 面经.md │ │ │ ├── 武汉 │ │ │ │ └── 面经-base武汉.md │ │ │ ├── 深圳-qq 飞车手游 │ │ │ │ ├── a.go │ │ │ │ └── 面经.md │ │ │ └── 深圳-欢乐斗地主 │ │ │ │ ├── a.go │ │ │ │ ├── b.go │ │ │ │ ├── c.go │ │ │ │ └── 面经.md │ │ ├── 腾讯云智 │ │ │ ├── 手图服务后台开发-24-8-28 │ │ │ │ └── a.go │ │ │ └── 腾讯云容器开发-24-07-23 │ │ │ │ └── a.go │ │ ├── 腾讯音乐 │ │ │ ├── a.go │ │ │ └── 面经.md │ │ ├── 蓝标传媒 │ │ │ ├── a.go │ │ │ └── 面经.md │ │ ├── 贝塔科技 │ │ │ ├── 数组.go │ │ │ ├── 管道.go │ │ │ └── 链表排序.md │ │ ├── 边无际 │ │ │ └── a.go │ │ ├── 迅雷 │ │ │ ├── a.go │ │ │ └── 面经.md │ │ ├── 金山云 2023届校招 Golang方向 │ │ │ ├── 小明的打车费.md │ │ │ └── 鸽子在转圈.md │ │ └── 金山云2023校招 │ │ │ └── 一面面经.md │ ├── 框架 │ │ └── Gin源码阅读.md │ └── 算法 │ │ ├── Leetcode │ │ ├── Hot100题 │ │ │ ├── 104.二叉树的最大深度.go │ │ │ └── 94. 二叉树的中序遍历.go │ │ ├── leetcode │ │ │ ├── 215. 数组中的第K个最大元素.go │ │ │ ├── 283. 移动零.go │ │ │ ├── 6031. 找出数组中的所有 K 近邻下标.go │ │ │ └── 912. 排序数组.go │ │ ├── 剑指 Offer(专项突击版) │ │ │ ├── 069. 山峰数组的顶部.exe │ │ │ ├── 069. 山峰数组的顶部之二分.exe │ │ │ ├── 069. 山峰数组的顶部之二分.go │ │ │ ├── 069山峰数组的顶部之枚举.exe │ │ │ ├── 069山峰数组的顶部之枚举.go │ │ │ ├── 072. 求平方根之二分.exe │ │ │ ├── 072. 求平方根之二分.go │ │ │ ├── 072. 求平方根之二分2.go │ │ │ ├── 072. 求平方根之暴力.go │ │ │ ├── 剑指 Offer II 068. 查找插入位置.exe │ │ │ ├── 剑指 Offer II 068. 查找插入位置2.exe │ │ │ ├── 剑指 Offer II 068. 查找插入位置2二分.go │ │ │ ├── 剑指 Offer II 068. 查找插入位置二分.go │ │ │ ├── 剑指 Offer II 070. 排序数组中只出现一次的数字之二分.exe │ │ │ └── 剑指 Offer II 070. 排序数组中只出现一次的数字之二分.go │ │ └── 剑指offer2 │ │ │ ├── 剑指 Offer 40. 最小的k个数之堆排序.exe │ │ │ ├── 剑指 Offer 40. 最小的k个数之堆排序.go │ │ │ ├── 剑指 Offer 45. 把数组排成最小的数.exe │ │ │ └── 剑指 Offer 45. 把数组排成最小的数.go │ │ ├── search │ │ └── binarySearch.go │ │ ├── sort │ │ ├── 交换排序-冒泡排序 │ │ │ └── BubbleSort.go │ │ ├── 交换排序-快速排序 │ │ │ ├── quicksort.go │ │ │ ├── 快排.go │ │ │ └── 快速排序.go │ │ ├── 归并排序 │ │ │ └── merge_sort.go │ │ ├── 插入排序-直接插入排序 │ │ │ └── insertsort.go │ │ ├── 选择排序-堆排序 │ │ │ └── go堆排序.go │ │ └── 选择排序-简单选择排序 │ │ │ └── selectsort.go │ │ ├── 大数计算 │ │ ├── big库函数版本.go │ │ ├── go-bigger.go │ │ └── 数组版本.go │ │ └── 尚硅谷 │ │ ├── Josephu │ │ └── main.go │ │ ├── binarytree │ │ └── main.go │ │ ├── circelqueue │ │ └── main.go │ │ ├── circlesinglelink │ │ └── main.go │ │ ├── doublelink │ │ └── main.go │ │ ├── expStack │ │ └── main.go │ │ ├── hashtable │ │ └── main.go │ │ ├── insertsort │ │ └── main.go │ │ ├── migong │ │ ├── demo01 │ │ │ └── main.go │ │ └── main │ │ │ └── main.go │ │ ├── quicksort │ │ └── main.go │ │ ├── selectsort │ │ └── main.go │ │ ├── singlelink │ │ └── main.go │ │ ├── singlequeue │ │ └── main.go │ │ ├── sparsearray │ │ └── main.go │ │ └── stack │ │ └── main.go └── go-study │ ├── GO文档 │ ├── GO专家编程 │ │ ├── 内存管理 │ │ │ └── 逃逸分析 │ │ │ │ ├── 3.1 指针逃逸.go │ │ │ │ ├── 3.2 栈空间不足逃逸.go │ │ │ │ ├── 3.3 动态类型逃逸.go │ │ │ │ └── 3.4 闭包引用对象逃逸.go │ │ ├── 协程 │ │ │ └── 协程调度 │ │ │ │ ├── 协程调度.exe │ │ │ │ └── 协程调度.go │ │ ├── 常见控制结构实现原理 │ │ │ ├── defer │ │ │ │ ├── 2.1 题目一.exe │ │ │ │ ├── 2.1 题目一.go │ │ │ │ ├── 2.2 题目二.exe │ │ │ │ ├── 2.2 题目二.go │ │ │ │ ├── 2.3 题目三.exe │ │ │ │ ├── 2.3 题目三.go │ │ │ │ ├── 3.3.3 主函数拥有匿名返回值,返回变量.exe │ │ │ │ └── 3.3.3 主函数拥有匿名返回值,返回变量.go │ │ │ ├── range │ │ │ │ ├── 2.1 题目一:切片遍历.exe │ │ │ │ ├── 2.1 题目一:切片遍历.go │ │ │ │ └── 2.3 题目三:动态遍历.go │ │ │ └── select │ │ │ │ ├── 2.1 题目1.exe │ │ │ │ ├── 2.1 题目1.go │ │ │ │ ├── 2.2 题目2.exe │ │ │ │ ├── 2.2 题目2.go │ │ │ │ ├── 2.3 题目3.exe │ │ │ │ ├── 2.3 题目3.go │ │ │ │ ├── 2.4 题目4.exe │ │ │ │ └── 2.4 题目4.go │ │ ├── 常见数据结构实现原理 │ │ │ ├── chan │ │ │ │ ├── main.exe │ │ │ │ ├── main.go │ │ │ │ ├── select.exe │ │ │ │ ├── select.go │ │ │ │ ├── 多返回值模式.exe │ │ │ │ └── 多返回值模式.go │ │ │ ├── iota │ │ │ │ ├── main.exe │ │ │ │ └── main.go │ │ │ ├── map │ │ │ │ ├── 值为切片类型的map.go │ │ │ │ ├── 元素为map类型的切片.exe │ │ │ │ └── 元素为map类型的切片.go │ │ │ ├── slice │ │ │ │ ├── 2.1 题目一.exe │ │ │ │ ├── 2.1 题目一.go │ │ │ │ ├── 2.2 题目二.go │ │ │ │ ├── 2.3 题目三.go │ │ │ │ ├── 3.3 使用数组创建Slice.exe │ │ │ │ └── 3.3 使用数组创建Slice.go │ │ │ ├── string │ │ │ │ ├── main.go │ │ │ │ ├── string和byte.exe │ │ │ │ └── string和byte.go │ │ │ └── struct │ │ │ │ ├── 获取Tag.exe │ │ │ │ └── 获取Tag.go │ │ └── 并发控制 │ │ │ ├── WaitGroup │ │ │ ├── Wait-Goroutine-Group.exe │ │ │ └── Wait-Goroutine-Group.go │ │ │ └── channel │ │ │ ├── 2. 场景示例.exe │ │ │ └── 2. 场景示例.go │ ├── GitBook │ │ └── Golang │ │ │ └── 在 Go 中恰到好处的内存对齐.go │ ├── Go入门指南 │ │ └── 第14章协程与通道 │ │ │ ├── demo │ │ │ ├── Go 通道实现信号量.go │ │ │ ├── 实现并行的 for 循环.go │ │ │ ├── 用协程实现在一个非常长的数组中查找一个元素.go │ │ │ └── 素数.go │ │ │ ├── examples │ │ │ └── chapter_14 │ │ │ │ ├── blocking.go │ │ │ │ ├── channel_block.go │ │ │ │ ├── channel_block2.go │ │ │ │ ├── channel_block3.go │ │ │ │ ├── channel_buffer.go │ │ │ │ ├── channel_idiom.go │ │ │ │ ├── channel_idiom2.go │ │ │ │ ├── general_lazy_evalution1.go │ │ │ │ ├── goroutine2.go │ │ │ │ ├── goroutine_select.go │ │ │ │ ├── gosum.go │ │ │ │ ├── lazy_evaluation.go │ │ │ │ ├── multiplex_server.go │ │ │ │ ├── producer_consumer.go │ │ │ │ ├── sieve1.go │ │ │ │ └── sieve2.go │ │ │ └── exercise │ │ │ ├── 练习14-11 │ │ │ ├── concurrent_pi2.go │ │ │ └── 练习14.11.md │ │ │ ├── 练习14-12 │ │ │ ├── general_lazy_evalution2.go │ │ │ └── 练习14.12.md │ │ │ ├── 练习14-7 │ │ │ ├── a.go │ │ │ ├── c.go │ │ │ └── 练习14.7.md │ │ │ ├── 练习14-8 │ │ │ ├── fibonacci.go │ │ │ ├── fibonacci2.go │ │ │ ├── gofibonacci.go │ │ │ ├── gofibonacci2.go │ │ │ ├── gofibonacci3.go │ │ │ ├── gofibonacci_select.go │ │ │ └── 练习14.8.md │ │ │ ├── 练习14-9 │ │ │ ├── random_bitgen.go │ │ │ └── 练习14.9.md │ │ │ └── 练习4-10 │ │ │ ├── polar_to_cartesian.go │ │ │ └── 练习4.10.md │ ├── 个人学习笔记.md │ ├── 幼麟实验室 │ │ ├── README.md │ │ ├── slice.go │ │ └── string.go │ └── 码农桃花源 │ │ └── array-and-slice │ │ ├── array-and-slice.go │ │ ├── 切片作为函数参数.go │ │ └── 切片作为函数参数2.go │ ├── README.md │ ├── exercise │ ├── Demo │ │ ├── go-game │ │ │ └── 贪吃蛇.go │ │ ├── go-zap │ │ │ └── go-log.go │ │ ├── http.get.go │ │ └── 兑换码 │ │ │ ├── 兑换码.go │ │ │ ├── 生成6位数的唯一id.go │ │ │ └── 生成指定位数的字符串(数字、大小写字母).go │ ├── Go │ │ ├── Gin │ │ │ ├── Bind Header.go │ │ │ ├── ip │ │ │ │ └── 获取ip地址.go │ │ │ └── stream │ │ │ │ └── 流式返回.go │ │ ├── Math │ │ │ ├── myMath.go │ │ │ └── myMath1.go │ │ ├── Time │ │ │ ├── Location.go │ │ │ ├── extractDates.go │ │ │ ├── getDayTimestamps.go │ │ │ ├── getMonthRange.go │ │ │ ├── test.go │ │ │ ├── test2.go │ │ │ ├── test3.go │ │ │ ├── time.go │ │ │ ├── time.now.go │ │ │ ├── utc.go │ │ │ ├── 倒计时.go │ │ │ └── 时间戳转换成UTC时间.go │ │ ├── byte和rune.go │ │ ├── chan │ │ │ └── 多生产者场景下 channel 关闭的问题.go │ │ ├── context │ │ │ └── Value.go │ │ ├── defer │ │ │ └── test1.go │ │ ├── for │ │ │ ├── for-chan.go │ │ │ ├── range-map.go │ │ │ └── range-slice.go │ │ ├── interface │ │ │ └── 类型断言.go │ │ ├── map │ │ │ ├── golang的map[string][]string的技巧.go │ │ │ └── test1.go │ │ ├── package │ │ │ └── strings.TrimSpace.go │ │ ├── strings │ │ │ ├── join.go │ │ │ ├── lenString.go │ │ │ ├── split.go │ │ │ ├── strconv-Atoi.go │ │ │ └── trimPrefix.go │ │ ├── struct.go │ │ ├── test.go │ │ ├── test │ │ │ ├── Println.go │ │ │ ├── expand.go │ │ │ └── signature.go │ │ ├── 函数 │ │ │ ├── go函数定义.go │ │ │ └── go闭包.go │ │ ├── 并发 │ │ │ ├── sync-map.go │ │ │ ├── 并发控制.go │ │ │ └── 并发控制优化.go │ │ └── 数组与切片 │ │ │ ├── Go 输出两个slice切片的差集.go │ │ │ ├── go数组变链表.go │ │ │ ├── 从数组中截取切片.go │ │ │ ├── 去重.go │ │ │ └── 数组.go │ ├── framework │ │ └── gin │ │ │ └── test.go │ └── 其他 │ │ ├── gomodule.go │ │ ├── json内嵌数组json.go │ │ ├── 康威的生命游戏.go │ │ └── 浮点数格式化输出.go │ ├── go语言基础 │ ├── 并发 │ │ ├── README.md │ │ ├── channel │ │ │ ├── CHANNEL_README.md │ │ │ ├── channel.go │ │ │ ├── exercise.go │ │ │ ├── 单向通道.go │ │ │ ├── 多返回值模式.go │ │ │ ├── 无缓冲channel.go │ │ │ ├── 有缓冲通道.go │ │ │ ├── 生产者消费者模型 │ │ │ │ ├── 无缓冲channel.go │ │ │ │ └── 有缓冲channel.go │ │ │ └── 通道误用示例.go │ │ ├── context │ │ │ └── CONTEXT_README.md │ │ ├── exercise │ │ │ ├── README.md │ │ │ └── 计算int64随机数各位数和.go │ │ ├── goroutine │ │ │ ├── GOROUTINE_README.md │ │ │ ├── exercise.go │ │ │ ├── 启动单个goroutine-test.go │ │ │ ├── 启动单个goroutine.go │ │ │ └── 启动多个goroutine.go │ │ ├── select │ │ │ ├── SELECT_README.md │ │ │ └── select.go │ │ ├── 原子操作 │ │ │ ├── README.md │ │ │ └── atomic.go │ │ └── 并发安全和锁 │ │ │ ├── Map │ │ │ ├── map.go │ │ │ └── syncMap.go │ │ │ ├── Once │ │ │ ├── once.go │ │ │ └── singleton.go │ │ │ ├── README.md │ │ │ ├── WaitGroup │ │ │ └── waitgroup.go │ │ │ ├── 互斥锁 │ │ │ └── Mutex.go │ │ │ ├── 数据竞争示例.go │ │ │ └── 读写互斥锁 │ │ │ └── rwMutex.go │ └── 接口 │ │ ├── README.md │ │ ├── huchao.txt │ │ ├── 值接收者实现接口.go │ │ ├── 指针接收者实现接口.go │ │ ├── 日志库.go │ │ ├── 类型与接口的关系.go │ │ └── 类型断言.go │ ├── 常用组件库 │ ├── ChatGPT │ │ └── go-openai.go │ ├── Elasticsearch │ │ └── README.md │ ├── go-mod-graph-chart │ │ └── PaulXu-cn go-mod-graph-chart.md │ ├── mime │ │ └── mime-multipart.md │ ├── validator │ │ └── README.md │ ├── viper │ │ └── README.md │ ├── zap │ │ ├── README.md │ │ ├── zap.go │ │ └── 在go语言中使用zap.md │ ├── 定时任务 │ │ ├── CRON_README.md │ │ ├── cron.go │ │ └── 原生实现.md │ ├── 常用限流策略——漏桶与令牌桶 │ │ ├── 令牌桶 │ │ │ └── juju-ratelimit.go │ │ └── 漏桶 │ │ │ └── uber-go-ratelimit.go │ ├── 数据结构与算法库 │ │ └── container │ │ │ ├── list.go │ │ │ └── ring.go │ └── 输入输出 │ │ └── fmt-格式化IO.md │ ├── 第五届字节跳动青训营 │ ├── h_promotion │ │ ├── .gitignore │ │ ├── .mvn │ │ │ └── wrapper │ │ │ │ ├── maven-wrapper.jar │ │ │ │ └── maven-wrapper.properties │ │ ├── logs │ │ │ ├── h_promotion-ERROR-2022-12-30_1.log.gz │ │ │ └── h_promotion-WARN-2022-12-30_1.log.gz │ │ ├── mvnw │ │ ├── mvnw.cmd │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── camp │ │ │ │ │ └── promotion │ │ │ │ │ ├── HPromotionApplication.java │ │ │ │ │ ├── common │ │ │ │ │ ├── BizException.java │ │ │ │ │ ├── Constant.java │ │ │ │ │ ├── ResponseData.java │ │ │ │ │ └── ResponseEnum.java │ │ │ │ │ ├── config │ │ │ │ │ ├── RedisConfig.java │ │ │ │ │ └── WebMvcConfig.java │ │ │ │ │ ├── controller │ │ │ │ │ ├── CategoryController.java │ │ │ │ │ ├── PromotionController.java │ │ │ │ │ └── request │ │ │ │ │ │ ├── CreateActivityRequest.java │ │ │ │ │ │ ├── CreateOrderRequest.java │ │ │ │ │ │ └── CreatePromoProductRequest.java │ │ │ │ │ ├── convertet │ │ │ │ │ ├── ConvertFunction.java │ │ │ │ │ ├── Converter.java │ │ │ │ │ ├── MultiConverter.java │ │ │ │ │ └── PromoConverter.java │ │ │ │ │ ├── dao │ │ │ │ │ ├── HCategoryAttributeDao.java │ │ │ │ │ ├── HCategoryDao.java │ │ │ │ │ ├── HOrderDao.java │ │ │ │ │ ├── HProductDao.java │ │ │ │ │ ├── HPromoDao.java │ │ │ │ │ ├── HPromoProductDao.java │ │ │ │ │ ├── HSkuDao.java │ │ │ │ │ ├── HSpecDao.java │ │ │ │ │ ├── HSpecDetailDao.java │ │ │ │ │ ├── HUserAddressDao.java │ │ │ │ │ └── HUserDao.java │ │ │ │ │ ├── entity │ │ │ │ │ ├── HCategory.java │ │ │ │ │ ├── HCategoryAttribute.java │ │ │ │ │ ├── HOrder.java │ │ │ │ │ ├── HProduct.java │ │ │ │ │ ├── HPromo.java │ │ │ │ │ ├── HPromoProduct.java │ │ │ │ │ ├── HSku.java │ │ │ │ │ ├── HSpec.java │ │ │ │ │ ├── HSpecDetail.java │ │ │ │ │ ├── HUser.java │ │ │ │ │ └── HUserAddress.java │ │ │ │ │ ├── enums │ │ │ │ │ ├── OrderStatusEnum.java │ │ │ │ │ ├── PaymentTypeEnum.java │ │ │ │ │ ├── ProductStatusEnum.java │ │ │ │ │ └── PromoStatusEnum.java │ │ │ │ │ ├── handler │ │ │ │ │ └── BizExceptionHandler.java │ │ │ │ │ ├── limit │ │ │ │ │ ├── RateEnum.java │ │ │ │ │ ├── RateLimit.java │ │ │ │ │ └── RateLimitAspect.java │ │ │ │ │ ├── lock │ │ │ │ │ ├── AbstractDistributedLock.java │ │ │ │ │ └── RedisDistributedLock.java │ │ │ │ │ ├── model │ │ │ │ │ ├── CreateActivityModel.java │ │ │ │ │ ├── CreateOrderModel.java │ │ │ │ │ ├── CreatePromoProductModel.java │ │ │ │ │ ├── HPromoProductModel.java │ │ │ │ │ ├── HPromoSkuModel.java │ │ │ │ │ ├── HPromoSpuModel.java │ │ │ │ │ └── OrderModel.java │ │ │ │ │ ├── mq │ │ │ │ │ ├── OrderProducer.java │ │ │ │ │ ├── OrderPullConsumer.java │ │ │ │ │ └── OrderPushConsumer.java │ │ │ │ │ ├── service │ │ │ │ │ ├── CacheService.java │ │ │ │ │ ├── HCategoryAttributeService.java │ │ │ │ │ ├── HCategoryService.java │ │ │ │ │ ├── HOrderService.java │ │ │ │ │ ├── HProductService.java │ │ │ │ │ ├── HPromoOrderService.java │ │ │ │ │ ├── HPromoProductService.java │ │ │ │ │ ├── HPromoService.java │ │ │ │ │ ├── HPromotionService.java │ │ │ │ │ ├── HSkuService.java │ │ │ │ │ ├── HSpecDetailService.java │ │ │ │ │ ├── HSpecService.java │ │ │ │ │ ├── HUserAddressService.java │ │ │ │ │ ├── HUserService.java │ │ │ │ │ ├── IdGenerateService.java │ │ │ │ │ ├── LocalCacheService.java │ │ │ │ │ ├── RedisService.java │ │ │ │ │ ├── RiskManagementService.java │ │ │ │ │ ├── TimeService.java │ │ │ │ │ └── impl │ │ │ │ │ │ ├── HCategoryAttributeServiceImpl.java │ │ │ │ │ │ ├── HCategoryServiceImpl.java │ │ │ │ │ │ ├── HOrderServiceImpl.java │ │ │ │ │ │ ├── HProductServiceImpl.java │ │ │ │ │ │ ├── HPromoOrderServiceImpl.java │ │ │ │ │ │ ├── HPromoProductServiceImpl.java │ │ │ │ │ │ ├── HPromoServiceImpl.java │ │ │ │ │ │ ├── HPromotionServiceImpl.java │ │ │ │ │ │ ├── HSkuServiceImpl.java │ │ │ │ │ │ ├── HSpecDetailServiceImpl.java │ │ │ │ │ │ ├── HSpecServiceImpl.java │ │ │ │ │ │ ├── HUserAddressServiceImpl.java │ │ │ │ │ │ └── HUserServiceImpl.java │ │ │ │ │ └── util │ │ │ │ │ └── ApplicationContextUtil.java │ │ │ └── resources │ │ │ │ ├── application.yml │ │ │ │ ├── decrease-stock.lua │ │ │ │ ├── log4j2.xml │ │ │ │ ├── mapper │ │ │ │ ├── HCategoryAttributeDao.xml │ │ │ │ ├── HCategoryDao.xml │ │ │ │ ├── HOrderDao.xml │ │ │ │ ├── HProductDao.xml │ │ │ │ ├── HPromoDao.xml │ │ │ │ ├── HPromoProductDao.xml │ │ │ │ ├── HSkuDao.xml │ │ │ │ ├── HSpecDao.xml │ │ │ │ ├── HSpecDetailDao.xml │ │ │ │ ├── HUserAddressDao.xml │ │ │ │ └── HUserDao.xml │ │ │ │ ├── promo.sql │ │ │ │ └── unlock.lua │ │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── camp │ │ │ └── promotion │ │ │ └── HPromotionApplicationTests.java │ ├── 【后端专场 学习资料一】第五届字节跳动青训营.md │ ├── 【后端专场 学习资料七】第五届字节跳动青训营.md │ ├── 【后端专场 学习资料三】第五届字节跳动青训营.md │ ├── 【后端专场 学习资料二】第五届字节跳动青训营.md │ ├── 【后端专场 学习资料五】第五届字节跳动青训营.md │ ├── 【后端专场 学习资料六】第五届字节跳动青训营.md │ └── 【后端专场 学习资料四】第五届字节跳动青训营.md │ ├── 规范 │ └── 高质量编程与性能调优实战.md │ ├── 资料库 │ ├── Go 学习推荐社区网站博主.md │ ├── Go语言学习之路_Liwenzhou.md │ ├── golang学习路线.md │ └── 超高质量网站.md │ └── 项目 │ ├── 7 个 yyds 的 Go 项目.md │ ├── golang项目.md │ └── 成为 Go 高手的 8 个 GitHub 开源项目.md ├── images ├── Blued │ └── Blued.jpeg ├── GOLANG ROADMAP.png ├── GO语言算法和数据结构(golang语言实现).png ├── Golang面试八股文-刷完面试成功率90%10.png ├── Golang面试八股文刷完面试成功率90%--毛神.jpg ├── Gophers 1️⃣群聊二维码.png ├── Gophers │ ├── 1faaf9020e0df18fdf0429e0db211f37.png │ ├── 21d7b19498ecea607e93b8a1ac0334fd.png │ ├── 3a80147ec037492954f53e254516f876.jpeg │ ├── 7e57e31c27a6f674d37f361acc99fe18.png │ ├── 98068ce517fb3cde20c01b4da3faee36.png │ ├── 9ea6c4d634d77fe67828e15114126c83.png │ ├── Excelize.png │ ├── Gin-Gonic.png │ ├── The Cloud-Native Application Proxy.png │ ├── a4569e34ee3c8189513108a2f7bedc42.jpeg │ ├── c4e30ec316973e501df2e99427f9f9d3.png │ ├── d5aa7fb03c892fc7aec2816864d30e61.png │ ├── e52e65e839b0d5e53e3d28bbcb07d790.png │ ├── excelize.svg │ ├── ff0f3f3c6016016f059fbfd8c15c5d94.png │ ├── go-git-logo.png │ ├── go-git.png │ ├── golang-logo.png │ └── json-to-go.png ├── Go学习开发地图.png ├── Go语言中文网.png ├── Mysql是怎样运行的.png ├── Mysql面试八股文-刷完面试成功率90%.png ├── R-C.jpeg ├── RBAC.jpg ├── advanced-oauth-security.png ├── deepseek.png ├── elasticsearch.jpg ├── golang.design.png ├── go语言标准库.png ├── kafka-logo-7.png ├── linux.png ├── mysql-2.png ├── redis.png ├── redis设计与实现.png ├── 微信交流群.jpg ├── 数据结构c语言版.png ├── 最新面试300问Golang面试八股文.png ├── 最新面试300问Golang面试八股文offer拿到手软.png ├── 消息队列.jpeg ├── 现代操作系统.png ├── 第五届字节跳动青训营 - 后端专场基础班.png ├── 计算机网络-第七版-谢希仁.jpg ├── 贝塔-北京.jpeg ├── 贝塔-成都.jpeg ├── 飞书.png └── 高并发设计的15个锦囊.png ├── k8s ├── README.md ├── k8s操作命令.md └── k8s面经.md ├── mongo └── 查询.md ├── mysql ├── MYSQL知识点整理.md ├── MySQL基础、锁、事务、分库分表、优化.md └── MySQL索引及优化全总结.md ├── project ├── README.md ├── data-sync │ ├── main.go │ ├── mongo-to-mysql │ │ ├── ad_conf_centre │ │ │ ├── ad_conf_audience.go │ │ │ ├── ad_conf_audience_include_relations.go │ │ │ ├── ad_conf_audience_isegmentation_relations.go │ │ │ ├── ad_conf_copywriting.go │ │ │ ├── ad_conf_country.go │ │ │ ├── ad_conf_position.go │ │ │ ├── ad_conf_scheme.go │ │ │ ├── bean │ │ │ │ ├── bean_mongo.go │ │ │ │ ├── bean_mysql.go │ │ │ │ └── flexible_spec_config.go │ │ │ └── node │ │ │ │ ├── AdTextModel.js │ │ │ │ ├── CfgAppModel.js │ │ │ │ ├── CfgAudienceModel.js │ │ │ │ ├── CfgCountryModel.js │ │ │ │ ├── CfgFrameModel.js │ │ │ │ └── CfgPositionModel.js │ │ ├── ad_material │ │ │ ├── ad_material.go │ │ │ ├── ad_material_language_relations.go │ │ │ ├── ad_material_person_relations.go │ │ │ ├── ad_material_sync_success.go │ │ │ ├── bean │ │ │ │ ├── bean_mongo.go │ │ │ │ └── bean_mysql.go │ │ │ ├── node │ │ │ │ └── AssetCenterModel.js │ │ │ └── url_replace.go │ │ ├── ad_preview │ │ │ ├── ad_fb_finish.go │ │ │ ├── adflow │ │ │ │ ├── AdFlowCfgModel.js │ │ │ │ ├── AdFlowModel.js │ │ │ │ ├── AdflowPreviewModel.js │ │ │ │ └── JenkinsBuildInfoModel.js │ │ │ ├── bean │ │ │ │ ├── bean_mongo_adflow.go │ │ │ │ ├── bean_mongo_fb.go │ │ │ │ └── bean_mysql.go │ │ │ └── fb │ │ │ │ ├── FBAdModel.js │ │ │ │ ├── FBAdPoolModel.js │ │ │ │ ├── FBAdsetModel.js │ │ │ │ ├── FBAudienceAccountModel.js │ │ │ │ ├── FBCampaignModel.js │ │ │ │ └── FBCustomAudiencetModel.js │ │ ├── art_asset │ │ │ ├── art_asset_1.go │ │ │ ├── art_asset_2.go │ │ │ ├── art_asset_tag_relations.go │ │ │ ├── art_asset_tags.go │ │ │ ├── art_need_asset_relations.go │ │ │ ├── bean │ │ │ │ ├── bean_mongo.go │ │ │ │ └── bean_mysql.go │ │ │ └── node │ │ │ │ ├── ActiveLibraryModel.js │ │ │ │ ├── ArtSourceModel.js │ │ │ │ ├── CategoryModel.js │ │ │ │ ├── CloudUrlModel.js │ │ │ │ ├── PlatUserModel.js │ │ │ │ └── TagModel.js │ │ ├── art_need │ │ │ ├── BI 数据权限2023-03-03.xlsx │ │ │ ├── art_attachments.go │ │ │ ├── art_attachments2.go │ │ │ ├── art_need_id.txt │ │ │ ├── art_need_language_relations.go │ │ │ ├── art_need_material_size_relations.go │ │ │ ├── art_need_person_relations.go │ │ │ ├── art_need_relations.go │ │ │ ├── art_need_tag_relations.go │ │ │ ├── art_needs.go │ │ │ ├── art_tasks.go │ │ │ ├── base_desc_template.go │ │ │ ├── bean_mongo.go │ │ │ ├── bean_mysql.go │ │ │ ├── gia导入ARK用户账号密码.xlsx │ │ │ ├── supply_desc.go │ │ │ └── url_replace.go │ │ ├── bi_data │ │ │ └── bi_data.go │ │ ├── game.go │ │ ├── remote-config │ │ │ └── remote_config.go │ │ ├── sdk_release │ │ │ ├── README.md │ │ │ ├── child_sdk.go │ │ │ ├── child_sdk_release_record.go │ │ │ ├── jenkins_job.go │ │ │ ├── sdk_project.go │ │ │ ├── sdk_release_record.go │ │ │ └── version_number_to_version_ordinal.go │ │ ├── user_console │ │ │ ├── bean │ │ │ │ ├── bean_mongo.go │ │ │ │ ├── bean_mysql.go │ │ │ │ ├── const.go │ │ │ │ └── 投放模块-用户数据权限.txt │ │ │ ├── node │ │ │ │ └── DimPermissionModel.js │ │ │ ├── user_perm_police_resource_ad_app_game.go │ │ │ ├── user_perm_police_resource_bi.go │ │ │ ├── user_perm_police_resource_bi_app.go │ │ │ └── user_perm_police_resource_bi_game.go │ │ └── version-console │ │ │ ├── bean.go │ │ │ ├── env_version.go │ │ │ ├── is_gray_to2.go │ │ │ ├── language.go │ │ │ ├── version.go │ │ │ └── whitelist.go │ ├── mysql-to-mysql │ │ ├── README.md │ │ ├── activities.go │ │ ├── ad_material │ │ │ ├── ad_material.go │ │ │ ├── ad_material_sync_success.go │ │ │ ├── update_success_id.sql │ │ │ └── update_success_id_recover.sql │ │ ├── command.go │ │ ├── gameConfigs_to_gmConfig.go │ │ ├── gm_config.go │ │ ├── mail_goods.go │ │ └── mails.go │ └── postgreSQL-to-mysql │ │ └── bi-console │ │ ├── cfg_event_params_value.go │ │ ├── cfg_event_params_value2.go │ │ ├── cfg_event_params_value3.go │ │ └── cfg_event_params_value4.go ├── 业务 │ ├── BAISHUN (语聊房模式)游戏对接 │ │ ├── README.md │ │ ├── img.png │ │ └── signature生成参考代码.go │ ├── golang递归实现类别树(CategoryTree).md │ ├── ip.go │ ├── tiktok广告 │ │ ├── 上传图片.go │ │ ├── 上传视频.go │ │ └── 搜索视频.go │ ├── 三方抓数 │ │ ├── Aarki │ │ │ └── reporting.go │ │ ├── Blind Ferret │ │ │ └── blind-ferret.go │ │ ├── Tapjoy │ │ │ └── getReport.go │ │ ├── Taurusx │ │ │ ├── token.go │ │ │ ├── 广告创意信息.go │ │ │ ├── 广告投放报表.go │ │ │ ├── 广告组.go │ │ │ └── 推广信息.go │ │ ├── appier │ │ │ └── appier.go │ │ ├── bigo │ │ │ ├── 3.2 广告系列查询接口.go │ │ │ ├── 3.3 广告组查询接口.go │ │ │ ├── 3.5 报表查询接口.go │ │ │ ├── Base64.encode.go │ │ │ └── 刷新access_token.go │ │ ├── chartboost │ │ │ ├── campaign.go │ │ │ ├── job-status.go │ │ │ ├── pull the data.go │ │ │ └── pull the data3.go │ │ ├── liftoff │ │ │ ├── 1、reports.go │ │ │ ├── 2、reports-status.go │ │ │ ├── 3、reports-data.go │ │ │ ├── 4、get-campaigns.go │ │ │ └── 6、get-creatives.go │ │ ├── mintegral │ │ │ ├── pull the data.go │ │ │ └── token.go │ │ └── 阳光短剧 │ │ │ ├── decode.go │ │ │ ├── txt.go │ │ │ ├── 渠道列表查询接口(新).go │ │ │ ├── 用户数据查询.go │ │ │ └── 订单数据查询.go │ ├── 加密excel │ │ ├── JPLAndroid端美国地区付费用户gaid信息-sha256加密.xlsx │ │ ├── JPLAndroid端美国地区付费用户gaid信息.xlsx │ │ └── sha256.go │ ├── 增量更新从Facebook获取的广告业务.md │ ├── 字节广告 │ │ ├── images │ │ │ ├── images.go │ │ │ └── images2.go │ │ ├── token │ │ │ └── 刷新Refresh Token.go │ │ └── vedio │ │ │ ├── vedio.go │ │ │ └── vedio2.go │ ├── 小游戏归因 │ │ └── 巨量 │ │ │ └── 微信 │ │ │ └── signature.go │ ├── 打点 │ │ └── 数数 │ │ │ └── 退款打点.go │ ├── 腾讯广告 │ │ ├── images │ │ │ ├── go-sdk-添加图片文件.go │ │ │ └── image.go │ │ ├── vedio │ │ │ ├── go-sdk-添加视频文件.go │ │ │ └── vedio.go │ │ └── 资产授权 │ │ │ └── 资产权限授予.go │ └── 飞书多维表格 │ │ ├── token │ │ └── tenant_access_token.go │ │ └── 新增记录.go ├── 推荐项目 │ └── golang项目.md ├── 规范 │ ├── CodeReview规则.md │ ├── Golang开发规约.md │ ├── Go风格指南.md │ ├── github flow 推荐流程.md │ ├── git规范 │ │ ├── ARNING REMOTE HOST IDENTIFICATION HAS CHANGED.md │ │ └── 新需求开发和分支管理.md │ ├── 数据库的设计规范.md │ ├── 阿里官方 Redis 开发规范.md │ └── 项目开发规范.md └── 设计方案及调研 │ ├── Golang根据指定的两个字段,批量删除数据库中的相关记录.md │ ├── Oauth2.0 │ ├── OAuth2.0原理及Marketing-API使用.md │ └── Oauth2.0授权及golang实现.md │ ├── PG VS Mysql.md │ ├── Tidb.md │ ├── content-type.md │ ├── golang使用信号量并发安全的迁移千万条数据.md │ ├── golang实现根据图片url转成File.md │ ├── golang迁移1亿条mysql数据.md │ ├── go实现判断当两个参数确定时,第三个参数必须是唯一的.md │ ├── redis分布式锁及双重校验.md │ ├── 分类标签tree.md │ ├── 国内支付前后端方案调研.md │ ├── 图片-文字-动图敏感过滤.md │ ├── 基于RBAC的用户权限管理系统.md │ ├── 对象存储 OSS.md │ ├── 登录方案调研.md │ ├── 第三方登录.md │ ├── 钉钉发送工作消息通知.md │ └── 高并发系统设计.md ├── test.log ├── web ├── README.md └── Web 开发技术 │ └── Web 性能 │ └── 渲染页面:浏览器的工作原理.md ├── zookpper └── README.md ├── 其他 ├── README.md ├── 后端通用面试题.md └── 天津落户.md ├── 分布式 ├── API 网关详解.md ├── README.md ├── ZooKeeper详解 │ ├── ZooKeeper 实战.md │ ├── ZooKeeper 相关概念总结(入门).md │ └── ZooKeeper 相关概念总结(进阶).md ├── 分布式 ID 详解.md ├── 分布式事务(更新中).md ├── 分布式配置中心(更新中).md ├── 分布式锁详解.md └── 理论&算法&协议 │ ├── CAP & BASE理论.md │ ├── Paxos 算法.md │ ├── RBFT算法.md │ └── Raft 算法.md ├── 区块链 └── 区块链面经 │ └── README.md ├── 如何makemoney └── how2makemoney.md ├── 安全 ├── README.md └── 敏感词过滤 │ └── 敏感词过滤方案总结.md ├── 开发工具 ├── Docker │ ├── README.md │ ├── docker从入门到上手干事.md │ ├── docker基本概念解读.md │ └── docker笔记.md ├── Git │ ├── Github小技巧.md │ ├── Git入门.md │ ├── Git详解.md │ └── README.md ├── linux │ ├── README.md │ ├── linux速查 │ │ ├── Linux 命令行速查表-Cheet Sheet.md │ │ ├── Linux速查备忘手册.pdf │ │ └── linux命令大全-菜鸟.md │ ├── study │ │ ├── Linux - Curl使用.md │ │ ├── Linux - Linux 常用.md │ │ ├── Linux - Linux创建自建服务.md │ │ ├── Linux - Linux基础知识.md │ │ ├── Linux - ab压力测试.md │ │ ├── Linux - 内存分析工具pmap.md │ │ └── Linux - 零拷贝技术.md │ └── 常见的linux面试问题.md └── 开发百宝箱.md ├── 微服务 ├── README.md ├── code │ ├── HTTP调用RESTful API │ │ ├── client.go │ │ └── server.go │ ├── gRPC │ │ ├── hello_gRPC_client │ │ │ ├── go.mod │ │ │ ├── go.sum │ │ │ ├── main.go │ │ │ └── proto │ │ │ │ ├── hello.pb.go │ │ │ │ ├── hello.proto │ │ │ │ └── hello_grpc.pb.go │ │ └── hello_gRPC_server │ │ │ ├── go.mod │ │ │ ├── go.sum │ │ │ ├── main.go │ │ │ └── proto │ │ │ ├── hello.pb.go │ │ │ ├── hello.proto │ │ │ └── hello_grpc.pb.go │ └── rpc demo │ │ ├── 使用JSON协议的RPC │ │ ├── client-json.go │ │ ├── server-json.go │ │ └── service.go │ │ ├── 基于TCP协议的RPC │ │ ├── client-tcp.go │ │ ├── server-tcp.go │ │ └── service.go │ │ └── 基于http协议(基础RPC)示例 │ │ ├── client-http.go │ │ ├── server-http.go │ │ └── service.go ├── document │ ├── Go语言protobuf使用指南.md │ ├── RPC原理与Go RPC.md │ ├── gRPC.md │ ├── protobuf v3语法中文指南.md │ └── protobuf中oneof、WrapValue和FieldMask的使用.md └── 面经 │ ├── RPC面经.md │ └── 微服务面经.md ├── 提问的智慧 └── 提问的智慧.md ├── 操作系统 ├── study │ ├── 王道考研-操作系统.md │ └── 现代操作系统 │ │ ├── img.png │ │ └── 现代操作系统原书第4版.md └── 面经 │ └── 操作系统.md ├── 数据结构与算法 ├── LeetCode │ ├── LeetCode算法提炼.md │ └── 怎么高效刷 Leetcode?.md ├── README.md ├── 排序算法全解析 │ ├── 时间复杂度 O(n) 级排序算法.md │ ├── 时间复杂度 O(n^2) 级排序算法.md │ ├── 时间复杂度 O(nlogn) 级排序算法.md │ └── 概述.md ├── 算法基础 │ ├── 算法基础-复杂度.md │ └── 算法基础-用空间复杂度换时间复杂度.md ├── 资料库 │ └── README.md ├── 进制和位运算 │ ├── 位运算符的概念和性质.md │ ├── 例题.md │ ├── 整数在计算机中的表示方式.md │ └── 进制.md └── 面经 │ ├── 十大排序算法.md │ └── 数据结构与算法Guide【Golang实现】.md ├── 新冠 └── 奥密克戎 — 我的新冠感染全记录.md ├── 求职宝典 ├── HR问我目前拿到哪几个offer了,该怎么回答?.md ├── 北京哪些知名的科技公司.md ├── 北京有哪些好公司推荐?这些神仙公司能落京户、955、高薪还不内卷!.md ├── 国内软件厂商公司名单.md ├── 如何巧妙推迟面试时间.md ├── 面试官问:为什么离开上家公司?.md └── 面试官:你有什么想问的吗.md ├── 消息队列 ├── Kafka知识体系.md ├── Kafka面经.md ├── MQ面经.md ├── README.md └── RabbitMq.md ├── 简历 ├── 总结.md ├── 我的简历 │ ├── 春招版本 │ │ ├── 胡超-18836288306-后端开发工程师.docx │ │ └── 胡超-18836288306-后端开发工程师.pdf │ └── 秋招版本 │ │ └── 胡超-18836288306-后端开发工程师(1).pdf ├── 求职技巧.pdf ├── 简历投递.pdf └── 简历模板.pdf ├── 计算机网络 ├── 一次搞定计算机网络,高效修炼程序员内功.md ├── 导读 程序员如何打好计算机领域的基础?.md └── 计网面经 │ ├── 计算机网络上.md │ ├── 计算机网络下.md │ └── 计算机网络经典面试题.md ├── 设计模式 ├── README.md ├── 常见设计模式.md └── 常见设计模式导图.md ├── 高可用 ├── README.md ├── 冗余设计详解.md ├── 性能测试入门.md ├── 服务限流详解.md ├── 超时&重试详解.md ├── 降级&熔断详解(更新中).md └── 高可用系统设计指南.md ├── 高并发 ├── README.md └── 高并发系统设计.md └── 高性能 ├── CDN(内容分发网络)详解.md ├── README.md ├── 常见 SQL 优化手段总结(更新中).md ├── 消息队列 ├── Kafka常见面试题总结.md ├── RabbitMQ基础知识总结.md ├── RabbitMQ常见面试题总结.md ├── RocketMQ基础知识总结.md ├── RocketMQ常见面试题总结(更新中).md └── 消息队列基础常见面试题总结.md ├── 读写分离和分库分表详解.md └── 负载均衡详解(更新中).md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | *.exe 4 | db.go 5 | *.log 6 | 7 | # .DS_Store 8 | .DS_Store 9 | **/.DS_Store 10 | .DS_Store? -------------------------------------------------------------------------------- /elasticsearch/images/es_interview/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/elasticsearch/images/es_interview/img.png -------------------------------------------------------------------------------- /elasticsearch/images/es_interview/img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/elasticsearch/images/es_interview/img_1.png -------------------------------------------------------------------------------- /elasticsearch/images/es_interview/img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/elasticsearch/images/es_interview/img_2.png -------------------------------------------------------------------------------- /elasticsearch/images/es_interview/img_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/elasticsearch/images/es_interview/img_3.png -------------------------------------------------------------------------------- /elasticsearch/images/es_interview/img_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/elasticsearch/images/es_interview/img_4.png -------------------------------------------------------------------------------- /elasticsearch/images/es_restful/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/elasticsearch/images/es_restful/img.png -------------------------------------------------------------------------------- /elasticsearch/images/es_restful/img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/elasticsearch/images/es_restful/img_1.png -------------------------------------------------------------------------------- /elasticsearch/images/es_restful/img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/elasticsearch/images/es_restful/img_2.png -------------------------------------------------------------------------------- /elasticsearch/study/exercise/go-elasticsearch.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: huChao 3 | @since: 2022/8/9 4 | @desc: //TODO The official go进阶14讲 client for Elasticsearch 5 | **/ 6 | package main 7 | 8 | import ( 9 | "log" 10 | "strings" 11 | ) 12 | 13 | func main() { 14 | es, err := elasticsearch.NewClient(elasticsearch.Config{ 15 | Addresses: []string{"http://localhost:9200"}, 16 | }) 17 | 18 | body := `{ 19 | "query": { 20 | "match": { "message": "myProduct" } 21 | }, 22 | "aggregations": { 23 | "top_10_states": { "terms": {"field": "state", "size": 24 | 10 } } 25 | } 26 | }` 27 | 28 | res, err := es.Search( 29 | es.Search.WithIndex("social-*"), 30 | es.Search.WithBody(strings.NewReader(body)), 31 | es.Search.WithPretty(), 32 | ) 33 | if err != nil { 34 | log.Fatalf("Error getting response: %s", err) 35 | } 36 | 37 | defer res.Body.Close() 38 | } 39 | -------------------------------------------------------------------------------- /elasticsearch/study/各种查询的golang实现/es实现mysql or查询.md: -------------------------------------------------------------------------------- 1 | # es实现mysql or查询 2 | 3 | 4 | 5 | ```go 6 | termQuery3 := elastic.NewMatchQuery("from_user_bid", req.OwnerBid) 7 | termQuery4 := elastic.NewMatchQuery("to_user_bid", req.OwnerBid) 8 | 9 | boolQuery := elastic.NewBoolQuery() 10 | 11 | boolQuery.Should(termQuery3) 12 | boolQuery.Should(termQuery4) 13 | 14 | searchResult, err := l.svcCtx.OEsClient.OClient.Search().Index("records").Query(boolQuery).From((req.PageNum-1)*req.PageSize).Size(req.PageSize).Sort("create_time", false).Do(l.ctx) 15 | if err != nil { 16 | return nil, err 17 | } 18 | ``` -------------------------------------------------------------------------------- /golang/go-Interview/实战/meatApp/A.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: huchao 3 | @since: 2022/8/3 4 | @desc: //TODO 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | a := decha(5) 12 | fmt.Println(a) 13 | 14 | } 15 | 16 | func anser(x []int) []int { 17 | //a := decha(5) 18 | c := sort(x) 19 | return c 20 | } 21 | 22 | func decha(input int) []int { 23 | a := make([]int, 10) 24 | a[9] = 65 25 | 26 | for i := 8; i >= 0; i-- { 27 | a[i] = a[i+1] + input 28 | } 29 | 30 | return a 31 | } 32 | 33 | func sort(x []int) []int { 34 | for i := 0; i < len(x); i++ { 35 | for j := i + 1; j < len(x); j++ { 36 | if x[i] > x[j] { 37 | temp := x[i] 38 | x[i] = x[j] 39 | x[j] = temp 40 | } 41 | } 42 | } 43 | return x 44 | } 45 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/meatApp/B.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: huchao 3 | @since: 2022/8/3 4 | @desc: //TODO 5 | **/ 6 | package main 7 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/三七互娱/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type TreeNode struct { 6 | // Val int 7 | // Left *TreeNode 8 | // Right *TreeNode 9 | //} 10 | 11 | //type ListNode struct { 12 | // Val int 13 | // Next *ListNode 14 | //} 15 | 16 | func main() { 17 | fmt.Printf("hello world") 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/上海弘连网络8月23/10.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // 请您写一段简单的示例代码来表示Go协程+Channel的用法 9 | 10 | func Process(ch chan int) { 11 | //Do some work... 12 | time.Sleep(time.Second) 13 | 14 | ch <- 1 //管道中写入一个元素表示当前协程已结束 15 | } 16 | 17 | func main() { 18 | channels := make([]chan int, 10) //创建一个10个元素的切片,元素类型为channel 19 | 20 | for i := 0; i < 10; i++ { 21 | channels[i] = make(chan int) //切片中放入一个channel 22 | go Process(channels[i]) //启动协程,传一个管道用于通信 23 | } 24 | 25 | for i, ch := range channels { //遍历切片,等待子协程结束 26 | <-ch 27 | fmt.Println("Routine ", i, " quit!") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/上海弘连网络8月23/2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func TestSlice(arr []int) { 6 | arr = append(arr, 3) 7 | arr = append(arr, 4) 8 | } 9 | 10 | func main() { 11 | arr := make([]int, 1, 10) 12 | arr = append(arr, 1) 13 | arr = append(arr, 2) 14 | TestSlice(arr) 15 | fmt.Printf("%d,%d,%d", arr[0], arr[1], len(arr)) // 0,1,3 16 | } 17 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/上海弘连网络8月23/3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var item = "hello" 8 | 9 | func main() { 10 | v := item 11 | v[0] = 'a' 12 | fmt.Printf("%s", item) 13 | } 14 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/上海弘连网络8月23/4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type People struct { 8 | age *int 9 | name string 10 | } 11 | 12 | func NewPeople(name string, age int) (p *People) { 13 | p = new(People) 14 | p.age = new(int) 15 | p.SetName(name) 16 | p.SetAge(age) 17 | return 18 | } 19 | 20 | func (p People) SetAge(age int) { 21 | p.age = &age 22 | } 23 | 24 | func (p People) GetAge() int { 25 | return *p.age 26 | } 27 | 28 | func (p People) SetName(name string) { 29 | p.name = name 30 | } 31 | 32 | func (p People) GetName() string { 33 | return p.name 34 | } 35 | 36 | func main() { 37 | var people *People = NewPeople("John", 22) 38 | people.SetName("Grace") 39 | people.SetAge(45) 40 | fmt.Printf("%s,%d", people.GetName(), people.GetAge()) // ,0 41 | } 42 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/上海弘连网络8月23/5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | Defer("John") 7 | } 8 | 9 | func Defer(name string) { 10 | defer func(param string) { 11 | fmt.Printf("%s", param) 12 | }(name) 13 | 14 | defer func() { 15 | err := recover() 16 | if err != nil { 17 | fmt.Printf("%s", err) 18 | } 19 | }() 20 | name = "Lee" 21 | panic("error") 22 | defer func() { 23 | fmt.Printf("end") // errorJohn 24 | }() 25 | } 26 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/上海弘连网络8月23/6.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | var object interface{} 9 | object = 1 10 | switch object { 11 | case 1: 12 | fmt.Printf("1") // 1 13 | case 2: 14 | fmt.Printf("2") 15 | case 3: 16 | fmt.Printf("3") 17 | break 18 | case 4: 19 | fmt.Printf("4") 20 | break 21 | default: 22 | fmt.Printf("5 ") 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/上海弘连网络8月23/7.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | name := "张三" 9 | fmt.Printf("%d", len(name)) // 6 10 | } 11 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/上海弘连网络8月23/8.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var peoples map[string]string = make(map[string]string) 7 | peoples["001"] = "Jack" 8 | peoples["004"] = "John" 9 | peoples["003"] = "Georgia" 10 | peoples["002"] = "Lucy" 11 | for k, v := range peoples { 12 | fmt.Println(k, v) 13 | } 14 | //001 Jack 15 | //004 John 16 | //003 Georgia 17 | //002 Lucy 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/上海弘连网络8月23/9.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/8/23 4 | @note: 5 | **/ 6 | package main 7 | 8 | //请您简短介绍下反射具体可以实现哪些功能,如果您在工作中曾经使用过反射,请说说具体的应用场景? 9 | 10 | //1. golang中反射最常见的使用场景是做对象的序列化,go语言标准库的encoding/json、xml、gob、binary等包就大量依赖于反射功能来实现 11 | //2. 反射能够在运行时检查类型,它还允许在运行时检查,修改和创建变量,函数和结构体。 12 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/乐城堡校招/一.go: -------------------------------------------------------------------------------- 1 | package main 2 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/乐城堡校招/三.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | // 假设序列中的每一个元素表示[start, end)的时间段 7 | timeSeq := [][]int{{1, 9}, {2, 4}, {5, 6}, {3, 7}, {1, 8}} 8 | 9 | // 根据时间段中的起始时间和结束时间,创建一个新的时间序列,表示每个时间点上连接和断开的设备数量 10 | timePoints := make(map[int]int) 11 | for _, t := range timeSeq { 12 | timePoints[t[0]]++ 13 | timePoints[t[1]]-- 14 | } 15 | 16 | // 记录同一时间最多连接的设备数量 17 | maxConnectedDevices := 0 18 | // 记录当前时间连接的设备数量 19 | currentConnectedDevices := 0 20 | // 遍历每个时间点,计算同一时间最多连接的设备数量 21 | for _, v := range timePoints { 22 | currentConnectedDevices += v 23 | if currentConnectedDevices > maxConnectedDevices { 24 | maxConnectedDevices = currentConnectedDevices 25 | } 26 | } 27 | 28 | // 输出同一时间最多连接的设备数量 29 | fmt.Println("最多同时连接的设备数量:", maxConnectedDevices) 30 | } 31 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/乐城堡校招/校招笔试题V2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-Interview/实战/乐城堡校招/校招笔试题V2.pdf -------------------------------------------------------------------------------- /golang/go-Interview/实战/乐城堡校招/笔试题目.md: -------------------------------------------------------------------------------- 1 | * 1、假设你的学院组织了⼀场考试,现在有⼀个成绩单[60,98,59,88,98,60...],该成绩单是按照学⽣ 2 | 学号来排序的。请实现⼀个算法:计算该成绩单最⾼的k个分数。 3 | * 2、假设你寝室的路由器记录了每台设备连接和断开的时间点,经过整理后,你得到了类似这样⼀个序 4 | 列 5 | [[1,9),[2,4),[5,6),[3,7),[1,8)]。请实现⼀个算法:计算同⼀时间最多有⼏台设备连接了路由器。 6 | * 3、 [可选题] 假设你们学校是这样的组织架构(树状结构,且有指向⽗节点的指针),当学⽣合作时,需 7 | 要最近⼀级的上级批准。例如,同班同学(A1和A2)合作,需要班主任A批准;不同班级的学⽣(A1和 8 | B1)合作,需要院⻓1批准;同理,不同院的学⽣,需要校⻓批准。请实现⼀个算法:当两个学⽣想 9 | 要合作时,找到对应的批准⼈。 10 | 11 | ![img](file:///C:\Users\Hasee\AppData\Roaming\Tencent\Users\2557523039\QQ\WinTemp\RichOle\X{5~JHK~FNNB`{(JQD6)[U8.png) 12 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/依对-2024-7-9/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type TreeNode struct { 6 | // Val int 7 | // Left *TreeNode 8 | // Right *TreeNode 9 | //} 10 | 11 | //type ListNode struct { 12 | // Val int 13 | // Next *ListNode 14 | //} 15 | 16 | func main() { 17 | fmt.Println("hello") 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/决策数后端测试题/字符串中连续重复出现次数最多的字符和次数.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:huchao 3 | @data:2022/3/11 4 | @note: 输出字符串中连续重复出现次数最多的字符和次数 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "math" 11 | ) 12 | 13 | func main() { 14 | s := "2334" 15 | fmt.Println(longestRun(s)) 16 | } 17 | 18 | //输出字符串中连续重复出现次数最多的字符和次数 19 | func longestRun(s string) (string, int) { 20 | var maxVal string 21 | max := math.MinInt64 22 | maxVal = string(s[0]) 23 | 24 | // 使用KMP算法进行匹配 25 | for i := 0; i < len(s); i++ { 26 | a := string(s[i]) 27 | j := i + 1 28 | for j < len(s) { 29 | b := string(s[j]) 30 | //进行匹配 31 | if a != b { 32 | //跳出当前循环 33 | break 34 | } 35 | j++ 36 | } 37 | 38 | if j-i >= max { 39 | maxVal = string(s[j-1]) 40 | } 41 | max = maxFunc(max, j-i) 42 | } 43 | return string(maxVal),max 44 | 45 | } 46 | 47 | // 判断较大的函数 48 | func maxFunc(a, b int) int { 49 | if a > b { 50 | return a 51 | } else { 52 | return b 53 | } 54 | } -------------------------------------------------------------------------------- /golang/go-Interview/实战/北京竞业达数码科技股份有限公司/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type ListNode struct { 6 | // Val int 7 | // Next *ListNode 8 | //} 9 | 10 | //type TreeNode struct { 11 | // Val int 12 | // Left *TreeNode 13 | // Right *TreeNode 14 | //} 15 | // 构建一个示例二叉树 16 | // 1 17 | // / \ 18 | // 2 3 19 | // /| |\ 20 | // 4 5 6 7 21 | //root := &TreeNode{Val: 1} 22 | //root.Left = &TreeNode{Val: 2} 23 | //root.Right = &TreeNode{Val: 3} 24 | //root.Left.Left = &TreeNode{Val: 4} 25 | //root.Left.Right = &TreeNode{Val: 5} 26 | //root.Right.Left = &TreeNode{Val: 6} 27 | //root.Right.Right = &TreeNode{Val: 7} 28 | 29 | func main() { 30 | fmt.Println("Hello World!") 31 | } 32 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/北京蓝城兄弟-24-8-27/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type ListNode struct { 6 | // Val int 7 | // Next *ListNode 8 | //} 9 | 10 | //type TreeNode struct { 11 | // Val int 12 | // Left *TreeNode 13 | // Right *TreeNode 14 | //} 15 | // 构建一个示例二叉树 16 | // 1 17 | // / \ 18 | // 2 3 19 | // /| |\ 20 | // 4 5 6 7 21 | //root := &TreeNode{Val: 1} 22 | //root.Left = &TreeNode{Val: 2} 23 | //root.Right = &TreeNode{Val: 3} 24 | //root.Left.Left = &TreeNode{Val: 4} 25 | //root.Left.Right = &TreeNode{Val: 5} 26 | //root.Right.Left = &TreeNode{Val: 6} 27 | //root.Right.Right = &TreeNode{Val: 7} 28 | 29 | func main() { 30 | fmt.Println("Hello, World!") 31 | } 32 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/哈乐沃德/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type TreeNode struct { 6 | // Val int 7 | // Left *TreeNode 8 | // Right *TreeNode 9 | //} 10 | 11 | //type ListNode struct { 12 | // Val int 13 | // Next *ListNode 14 | //} 15 | 16 | func main() { 17 | fmt.Printf("hello world") 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/哔哩哔哩/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type TreeNode struct { 6 | // Val int 7 | // Left *TreeNode 8 | // Right *TreeNode 9 | //} 10 | 11 | //type ListNode struct { 12 | // Val int 13 | // Next *ListNode 14 | //} 15 | 16 | func main() { 17 | fmt.Println("hello world") 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/哔哩哔哩/面经.md: -------------------------------------------------------------------------------- 1 | # 一面 2 | 3 | 1. 自我介绍 4 | 2. 项目 5 | 1. 游戏项目:详细介绍一下在我被美女包围这个项目中,担任的角色和做过的工作、 6 | 2. 中台:介绍一下广告投放平台 7 | 3. go 8 | 1. 什么是goroutine。及补充 9 | 2. 介绍一下 golang 的 gmp 模型。及补充 10 | 4. mysql 11 | 1. mysql 有哪些场景的优化方式?能想到什么都可以说? 12 | 2. 什么是索引 13 | 3. 什么是事务 14 | 4. 事务有哪些隔离级别及这些隔离基本的区别 15 | 5. redis 16 | 1. 使用 redis 常见的注意事项,也是你能想到什么都可以说 17 | 2. redis 删除一个 大key,该怎么操作 18 | 6. 网络 19 | 1. 浏览器中输入一段网址最终网页展现在我们面前,中间发生哪些事情,介绍一下 20 | 2. 网页上的图片和视频相关的资源从哪里获取 21 | 3. 什么是 CDN 22 | 4. 知道哪些常见的网络攻击方式,讲了一下**DDoS和 XSS** 23 | 7. 你也是哔站的用户是么?一般都在哔站上传什么内容的视频,技术相关 24 | 8. 反问 25 | 1. 介绍了一下他们的大组(内容平台-供给生态技术组)。服务于 up 主,从上传视频到视频开放的全流程的整条链路。中间会有很多流程,比如视频上传,视频转码,审核等相关的一下逻辑在。视频上传之后会给到 up 一些相关的工具,比如说创作中心,数据看板等相关的一些工具给到用户。这些都是我们这个大组负责的。 26 | 2. 后端开发,整个组 30 多人,golang,微服务框架,b 站自研的微服务框架Kratos,现已开源。 27 | 3. 数据库主要用到 mysql 和一些分布式的数据库 Tidb。 28 | 4. 中间件 redis,**Memcached**哔站自研的一些相关中间件 29 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/天龙互娱/面经.md: -------------------------------------------------------------------------------- 1 | # 一面-线下 2 | 3 | 1. 先手写三道算法 4 | 1. [55. 跳跃游戏](https://leetcode.cn/problems/jump-game/) 5 | 2. [LCR 182. 动态口令](https://leetcode.cn/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/) 6 | 3. [2798. 满足目标工作时长的员工数目](https://leetcode.cn/problems/number-of-employees-who-met-the-target/) 7 | 2. 项目 8 | 1. 我被美女包围了-卡池设计 9 | 1. 游戏服务器部署了两个实例,那redis订阅的时候是这两个实例都能收到还是只有一个能收到 10 | 2. ark-三方抓数 11 | 3. 技术 12 | 1. go并发 13 | 4. 开源项目 14 | 5. 反问 15 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/好未来/技术体系-数字效能部-知音楼-golang开发工程师-24-08-12/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | // Counter 一个线程安全的计数器结构体 9 | type Counter struct { 10 | mu sync.Mutex 11 | count int 12 | } 13 | 14 | // Increment 增加计数 15 | func (c *Counter) Increment() { 16 | c.mu.Lock() // 加锁,确保线程安全 17 | c.count++ 18 | c.mu.Unlock() // 解锁 19 | } 20 | 21 | // Value 获取当前计数值 22 | func (c *Counter) Value() int { 23 | c.mu.Lock() // 加锁,确保读取时的线程安全 24 | defer c.mu.Unlock() // defer确保方法结束时解锁 25 | return c.count 26 | } 27 | 28 | func main() { 29 | counter := &Counter{} 30 | 31 | var wg sync.WaitGroup 32 | 33 | // 启动多个 goroutine 并发地增加计数器 34 | for i := 0; i < 1000; i++ { 35 | wg.Add(1) 36 | go func() { 37 | defer wg.Done() 38 | counter.Increment() 39 | }() 40 | } 41 | 42 | wg.Wait() 43 | fmt.Println("Value:", counter.Value()) 44 | } 45 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/好未来/技术体系-数字效能部-知音楼-golang开发工程师-24-08-12/b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | //求子数组的最大和 8 | //题目:输入一个整形数组,数组里有正数也有负数。 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。 求所有子数组的和的最大值。要求时间复杂度为 O(n)。 9 | //例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2, 因此输出为该子数组的和18。 10 | 11 | func maxSubArray(nums []int) int { 12 | if len(nums) == 0 { 13 | return 0 14 | } 15 | localMax := nums[0] 16 | globalMax := nums[0] 17 | 18 | for i := 1; i < len(nums); i++ { 19 | // 判断是开始一个新的子数组还是从上一个子数组中继续 20 | localMax = max(nums[i], localMax+nums[i]) 21 | // 更新全局最大和 22 | globalMax = max(globalMax, localMax) 23 | } 24 | return globalMax 25 | } 26 | 27 | func max(a, b int) int { 28 | if a > b { 29 | return a 30 | } 31 | return b 32 | } 33 | 34 | func main() { 35 | nums := []int{1, -2, 3, 10, -4, 7, 2, -5} 36 | fmt.Println("最大子数组和为:", maxSubArray(nums)) 37 | } 38 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/好未来/数字效能部-用户中台-07-31/面经.md: -------------------------------------------------------------------------------- 1 | # 一面 2 | 3 | 1. [leetcode102. 二叉树的层序遍历](https://leetcode.cn/problems/binary-tree-level-order-traversal/description/) 共享屏幕算法:把一个二叉树做一个层序遍历。(假如说有一个两层的平衡二叉树,要做的事就是把这个二叉树按照广度优先遍历给它遍历出来,对于每一层的数据,第一层按照从左到右遍历,第二层按照从右到左的顺序) 4 | ``` 5 | type TreeNode struct { 6 | Val int 7 | Left *TreeNode 8 | Right *TreeNode 9 | } 10 | ``` 11 | 12 | 2. go 13 | 1. 数组和切片 14 | 2. 切片扩容 15 | 3. 切片的新版本扩容 16 | 4. 内存管理 17 | 5. 垃圾回收 18 | 6. 三色标记流程 19 | 7. stw 20 | 8. 什么时候会触发stw 21 | 9. 有没有遇到过cpu不高但是内存搞的场景怎么排查的 22 | 10. 怎么实时查看k8s内存占用的 23 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/广州伽马/岗位要求作业—计数器.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-Interview/实战/广州伽马/岗位要求作业—计数器.zip -------------------------------------------------------------------------------- /golang/go-Interview/实战/度小满/后端开发工程师—技术体系-24-9-3/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type ListNode struct { 6 | // Val int 7 | // Next *ListNode 8 | //} 9 | 10 | //type TreeNode struct { 11 | // Val int 12 | // Left *TreeNode 13 | // Right *TreeNode 14 | //} 15 | // 构建一个示例二叉树 16 | // 1 17 | // / \ 18 | // 2 3 19 | // /| |\ 20 | // 4 5 6 7 21 | //root := &TreeNode{Val: 1} 22 | //root.Left = &TreeNode{Val: 2} 23 | //root.Right = &TreeNode{Val: 3} 24 | //root.Left.Left = &TreeNode{Val: 4} 25 | //root.Left.Right = &TreeNode{Val: 5} 26 | //root.Right.Left = &TreeNode{Val: 6} 27 | //root.Right.Right = &TreeNode{Val: 7} 28 | 29 | func main() { 30 | fmt.Println("Hello, World!") 31 | } 32 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/度小满/实习/Golang使用协程和channel顺序打印1-10.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | //整体思路 9 | //简单讲解下,由于goroutine的执行顺序是没有保证的,所以当需要顺序打印时,需要借助其他的一些全局变量控制打印顺序,我此处是通过一个tag,通过tag这个变量控制数据进入chan的顺序,进而使得输出可以按序输出 10 | //需要注意的一个小点 11 | //通过协程进行写入时,不能直接用变量i,需要通过参数把i传递进去,因为i对于这个协程来说是全局的,而i这个全局变量又是在自增的,所以不能直接用i 12 | 13 | //使用channel按顺序输出1-10 14 | func orderchan() { 15 | wg := sync.WaitGroup{} 16 | wg.Add(10) 17 | chs := make(chan int) 18 | //通过一个全局变量控制进channel的顺序 19 | tag := 1 20 | for i := 1; i <= 10; i++ { 21 | go func(value int) { 22 | //死循环,保证按顺序进chan 23 | for { 24 | if tag == value { 25 | chs <- value 26 | break 27 | } 28 | } 29 | }(i) 30 | } 31 | for i := 0; i < 10; i++ { 32 | fmt.Print(<-chs) 33 | wg.Done() 34 | tag++ 35 | } 36 | wg.Wait() 37 | } 38 | 39 | func main() { 40 | orderchan() 41 | } 42 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/度小满/实习/协程调度2.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: edy 3 | @since: 2022/9/20 4 | @desc: //TODO 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "time" 11 | ) 12 | 13 | func g1(p chan int) { 14 | for i := 1; i <= 10; i++ { 15 | p <- i 16 | if i%2 == 1 { 17 | fmt.Println("g1", i) 18 | } 19 | } 20 | } 21 | 22 | func g2(p chan int) { 23 | for i := 1; i <= 10; i++ { 24 | <-p 25 | if i%2 == 0 { 26 | fmt.Println("g2", i) 27 | } 28 | } 29 | } 30 | 31 | func main() { 32 | msg := make(chan int) 33 | go g1(msg) 34 | go g2(msg) 35 | 36 | time.Sleep(time.Second * 1) 37 | } 38 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/度小满/实习/线程调度-waitgroup.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | // 两个goroutine交替打印1-100之间的奇数和偶数 9 | 10 | func main() { 11 | ch := make(chan int) 12 | var wg sync.WaitGroup 13 | wg.Add(2) 14 | go func() { 15 | defer wg.Done() 16 | for i := 1; i < 101; i++ { 17 | ch <- 1 // 塞入 18 | //奇数 19 | if i%2 == 1 { 20 | fmt.Println("线程1打印:", i) 21 | } 22 | } 23 | }() 24 | go func() { 25 | defer wg.Done() 26 | for i := 1; i < 101; i++ { 27 | <-ch // 取出 28 | //偶数 29 | if i%2 == 0 { 30 | fmt.Println("线程2打印:", i) 31 | } 32 | } 33 | }() 34 | wg.Wait() 35 | } 36 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/度小满/实习/线程调度.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // 用两个携程实现一个从1到10到交替顺序打印 9 | 10 | var flagChan = make(chan int) 11 | 12 | func work1() { 13 | for i := 1; i <= 10; i++ { 14 | flagChan <- 1 // 塞入 15 | if i%2 == 1 { 16 | fmt.Println(i) 17 | } 18 | } 19 | } 20 | 21 | func work2() { 22 | for i := 1; i <= 10; i++ { 23 | _ = <-flagChan // 取出 24 | if i%2 == 0 { 25 | fmt.Println(i) 26 | } 27 | } 28 | } 29 | 30 | func main() { 31 | go work1(); 32 | go work2(); 33 | 34 | time.Sleep(3 * time.Second) 35 | } -------------------------------------------------------------------------------- /golang/go-Interview/实战/得物-2024-7-10/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type TreeNode struct { 6 | // Val int 7 | // Left *TreeNode 8 | // Right *TreeNode 9 | //} 10 | 11 | //type ListNode struct { 12 | // Val int 13 | // Next *ListNode 14 | //} 15 | 16 | func f() { 17 | defer fmt.Println("D") 18 | fmt.Println("F") 19 | } 20 | 21 | func main() { 22 | defer fmt.Println("N") 23 | f() 24 | fmt.Println("M") 25 | } 26 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/得物-2024-7-10/b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | panic("xxx") 5 | recover() 6 | } 7 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/得物-2024-7-10/c.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //select * from tableA where a = 1; 有一个表 ,里面有一个字段 a,建一个单字段索引,假如这个 sql没有走索引,分析一下原因 4 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/懂球帝/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type TreeNode struct { 6 | // Val int 7 | // Left *TreeNode 8 | // Right *TreeNode 9 | //} 10 | 11 | //type ListNode struct { 12 | // Val int 13 | // Next *ListNode 14 | //} 15 | 16 | func main() { 17 | fmt.Println("Hello, World!") 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/搜狐畅游/0802/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type TreeNode struct { 6 | // Val int 7 | // Left *TreeNode 8 | // Right *TreeNode 9 | //} 10 | 11 | //type ListNode struct { 12 | // Val int 13 | // Next *ListNode 14 | //} 15 | 16 | func main() { 17 | fmt.Printf("hello world") 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/格林深瞳/area.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/7/7 4 | @note: 5 | **/ 6 | package main 7 | 8 | // 国 9 | type Nation struct { 10 | IdAndName 11 | Province []Province // 省 12 | ZhiCity []ZhiCity // 直辖市 13 | AutonomousRegion []AutonomousRegion // 自治区 14 | } 15 | 16 | // 省 17 | type Province struct { 18 | IdAndName 19 | ZiArea []Area // 子级行政区 20 | } 21 | 22 | // 直辖市 23 | type ZhiCity struct { 24 | IdAndName 25 | ZiArea []Area // 子级行政区 26 | } 27 | 28 | // 自治区 29 | type AutonomousRegion struct { 30 | IdAndName 31 | ZiArea []Area // 子级行政区 32 | } 33 | 34 | // 行政区 35 | type Area struct { 36 | IdAndName 37 | ZiArea []Area // 子级行政区 38 | } 39 | 40 | type IdAndName struct { 41 | Id int64 // id 42 | Name string // 名称 43 | } 44 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/格林深瞳9月21面/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // 一个西瓜7快,苹果3块,荔枝1块3个,50块钱 买 50个水果 多少中买法 6 | // 一个西瓜7快,苹果3块,荔枝1块3个,50块钱 多少中买法 7 | 8 | //7x + 3y + z/3 = 50 9 | //x + y + z = 50 10 | 11 | func main() { 12 | //int x=0, y = 0, z = 0; 13 | var count = 0 14 | 15 | for x := 1; x <= 50/7; x++ { 16 | for y := 1; y <= 50/3; y++ { 17 | for z := 1; z <= 150; z++ { 18 | if (7*x+3*y+1/3*z == 50) && z%3 == 0 { 19 | count++ 20 | fmt.Printf("%d,%d,%d", x, y, z) 21 | fmt.Println() 22 | } 23 | } 24 | } 25 | } 26 | fmt.Println(count) 27 | 28 | } 29 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/格林深瞳9月21面/面经.md: -------------------------------------------------------------------------------- 1 | ![img](https://cdn.nlark.com/yuque/0/2022/png/22219483/1663771841059-fcc55a5c-59a0-4788-8703-c475301efebb.png) 2 | 3 | 4 | ------ 5 | 6 | 1. 上来共享屏幕 7 | 2. 自我介绍 8 | 3. 你们有go语言这门课程吗? 9 | 4. 为什么选择go语言? 10 | 5. 简单谈一下java与go,优缺点 11 | 12 | 1. 1. go协程和java线程的不同 13 | 14 | 1. go的垃圾回收 15 | 16 | 1. 1. 混合写屏障 17 | 2. java的垃圾回收机制 18 | 19 | 1. sync包 20 | 21 | 1. 1. sync.once的实现机制 22 | 23 | 1. 互斥锁和读写锁 24 | 2. 代码题: 25 | 26 | 1. 1. 一个西瓜7快,苹果3块,荔枝1块3个,50块钱 买 50个水果 多少种买法 27 | 2. 一个西瓜7快,苹果3块,荔枝1块3个,50块钱 多少种买法 28 | 29 | 1. 数据库 30 | 2. mysql 31 | 32 | 1. 1. 两种存储引擎的区别 33 | 2. 聚簇索引和非聚簇索引 34 | 3. 缓存的机制 35 | 4. 事务的几种机制是怎么实现的,借助mvcc机制 36 | 5. 幻读是怎么解决的 37 | 6. 慢sql的排查与优化以及解决思路,具体 38 | 7. 一个表超大数据,分页查询怎么才能尽可能的快,如何优化大分页查询? -------------------------------------------------------------------------------- /golang/go-Interview/实战/格林深瞳笔试/README.md: -------------------------------------------------------------------------------- 1 | ![img.png](img.png) -------------------------------------------------------------------------------- /golang/go-Interview/实战/格林深瞳笔试/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-Interview/实战/格林深瞳笔试/img.png -------------------------------------------------------------------------------- /golang/go-Interview/实战/格林深瞳笔试/查找数组最大元素.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "math" 4 | 5 | func main() { 6 | 7 | } 8 | 9 | func findMax(nums []int) int { 10 | a := len(nums) 11 | 12 | get := func(i int) int { 13 | if i == -1 || i == a { 14 | return math.MinInt64 15 | } 16 | return nums[i] 17 | } 18 | 19 | left, right := 0, a-1 20 | for { 21 | mid := (left + right) / 2 22 | if get(mid-1) < get(mid) && get(mid) > get(mid+1) { 23 | return nums[mid] 24 | } 25 | if get(mid) < get(mid+1) { 26 | left = mid + 1 27 | } else { 28 | right = mid - 1 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/欧科云链/slice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | list := []string{"a", "b", "c", "d", "e"} 7 | slice := list[2:4:6] 8 | fmt.Println(slice) 9 | } 10 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/武汉微派网络(贪吃蛇)/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // 从字符串中提取数字 6 | func main() { 7 | str := "a123a" 8 | ss := FindNum(str) 9 | fmt.Println(ss) 10 | } 11 | 12 | func FindNum(char string) int { 13 | // i记录循环次数 14 | // k记录提取的单个数的值 15 | // flag记录当前是否为数字 16 | // sum记录a[]的下标,存放数字到a数组中 17 | //var a []int 18 | var flag int 19 | var m int 20 | var sum int 21 | var k int 22 | flag = 0 23 | sum = 0 24 | m = 0 25 | 26 | for i := 0; i < len(char); i++ { 27 | // 当前位为数字,则放入k中 28 | if char[i] >= '0' && char[i] <= '9' { 29 | flag = 1 30 | k = int(char[i] - '0') 31 | } else { 32 | // flag = 1 ,说明前一位是数字,而现在已经不是数字 33 | // 把计算的sum放入数组中,一组连在一起的数字判断完成 34 | if flag == 1 { 35 | m = m + 1 36 | //a[m] = sum 37 | } 38 | // 复位 39 | flag = 0 40 | sum = 0 41 | } 42 | // 若为数字,则计算连在一起的数字的值 43 | if flag == 1 { 44 | sum = sum * 10 45 | sum += k 46 | } 47 | } 48 | return sum 49 | } 50 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/泡泡玛特-2024-7-12/面经.md: -------------------------------------------------------------------------------- 1 | # 一面 2 | 1. 聊公司 3 | 1. 公司主要是做哪方面业务的? 4 | 2. 端游还是手游? 5 | 3. 业务中台还是技术中台? 6 | 4. 团队多少人 7 | 2. 项目 8 | 1. 介绍一个有代表性的项目 9 | 2. 又讲了游戏服务器的项目 10 | 3. 觉得项目有哪设计的不好 11 | 3. redis、mysql 12 | 1. redis 除了内存原因快,还有没有其他原因? 13 | 2. 为什么 mysql 不用单线程 14 | 3. Redis 没有事务吗 15 | 4. redis 跳表,为了解决什么问题,时间复杂度多少 16 | 5. 还有哪些查找数据结构复杂度为log n 17 | 6. 为什么不用二叉树而用跳表 18 | 4. 网络 19 | 1. tcp的状态,timewaite 发生在第几个阶段 20 | 2. 服务器有大量的 timewaite,会影响什么? 21 | 3. linux 理论上来说可以处理的链接数量多少 22 | 5. GitHub 23 | 1. 有没有自己维护过的开源项目 24 | 2. 项目的Contributors有没有其他人 25 | 3. 使用Air实现Go程序实时热重载。这个是什么原理? 26 | 4. 假设现在想实现一个热加载怎么实现? 27 | 5. [Go pprof性能调优](https://www.liwenzhou.com/posts/Go/performance_optimisation/) 28 | 6. 职业规划和下一份工作是想做什么? 29 | 7. 二面需要现场再来一轮技术面 30 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/深信服/校招/校招golang一面11月7号.md: -------------------------------------------------------------------------------- 1 | 胡超一面 2 | 3 | 1. 自我介绍 4 | 2. 什么时候接触编程 5 | 3. 通信工程专业与计算机相关的课程 6 | 4. 自己有什么特点适合编程 7 | 5. 自学能力有什么经历? 8 | 6. 学习过程中,有什么印象深刻的问题,怎么解决的? 9 | 7. 算法 10 | 11 | 1. 1. 了解哪些排序算法? 12 | 2. 了解归并排序不? 13 | 3. 堆排序过程 14 | 15 | 1. 手撕 16 | 17 | 1. 1. 插入排序 18 | 2. 插入的空间复杂度多少 19 | 20 | 1. 什么时候开始用的go? 21 | 2. 计算机网络是否自学的? 22 | 3. 学习过程中有遇到什么tcp相关的问题? 23 | 4. 什么情况下会发生快速重传? 24 | 5. 项目 25 | 26 | 1. 1. 浏览器是方案怎么设计的? 27 | 2. es 28 | 3. 技术方案是怎么定的,和导师一起的吗? 29 | 4. es查询为什么快? 30 | 31 | 1. 反问 32 | 2. 结束 -------------------------------------------------------------------------------- /golang/go-Interview/实战/深信服/社招/后台开发-深圳-24-08-26/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type ListNode struct { 6 | // Val int 7 | // Next *ListNode 8 | //} 9 | 10 | //type TreeNode struct { 11 | // Val int 12 | // Left *TreeNode 13 | // Right *TreeNode 14 | //} 15 | // 构建一个示例二叉树 16 | // 1 17 | // / \ 18 | // 2 3 19 | // /| |\ 20 | // 4 5 6 7 21 | //root := &TreeNode{Val: 1} 22 | //root.Left = &TreeNode{Val: 2} 23 | //root.Right = &TreeNode{Val: 3} 24 | //root.Left.Left = &TreeNode{Val: 4} 25 | //root.Left.Right = &TreeNode{Val: 5} 26 | //root.Right.Left = &TreeNode{Val: 6} 27 | //root.Right.Right = &TreeNode{Val: 7} 28 | 29 | func main() { 30 | fmt.Println("Hello World!") 31 | } 32 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/王牌游戏-2024-7-14/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type TreeNode struct { 6 | // Val int 7 | // Left *TreeNode 8 | // Right *TreeNode 9 | //} 10 | 11 | //type ListNode struct { 12 | // Val int 13 | // Next *ListNode 14 | //} 15 | 16 | func main() { 17 | fmt.Println("Hello, world!") 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/王牌游戏-2024-7-14/【王牌游戏】后端工程师-测试题.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-Interview/实战/王牌游戏-2024-7-14/【王牌游戏】后端工程师-测试题.docx -------------------------------------------------------------------------------- /golang/go-Interview/实战/王牌游戏-2024-7-14/【王牌游戏】高潜策划管培生-测试题2.0.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-Interview/实战/王牌游戏-2024-7-14/【王牌游戏】高潜策划管培生-测试题2.0.docx -------------------------------------------------------------------------------- /golang/go-Interview/实战/王牌游戏-2024-7-14/测试题/3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "hash/fnv" 6 | ) 7 | 8 | //设计一个名为”abTestHash"的哈希函数,用于AB测试的分组。该函数接受玩家的UUID(int64)和AB测试的ID(int32)作为参数,并返回分组概率(int32)。要求分组均匀且无耦合。 9 | 10 | // abTestHash 接收玩家的UUID和AB测试的ID,并返回一个表示分组的int32值(0为A组,1为B组) 11 | func abTestHash(uuid int64, testID int32) int32 { 12 | //使用哈希函数对UUID和AB测试ID的组合进行哈希 13 | // 创建一个FNV哈希器 14 | hasher := fnv.New32a() 15 | 16 | // 将UUID和测试ID写入哈希器(先写入UUID,再写入测试ID,以确保每个玩家在不同的测试中具有不同的哈希值 17 | combined := fmt.Sprintf("%d%d", uuid, testID) 18 | hasher.Write([]byte(combined)) 19 | 20 | // 使用哈希值的最低位来决定分组(0或1) 21 | hashValue := hasher.Sum32() 22 | return int32(hashValue & 1) // 如果最低位是0,返回0(A组);如果是1,返回1(B组) 23 | } 24 | 25 | func main() { 26 | // 示例用法 27 | uuid := int64(123456789012345678) 28 | testID := int32(4) 29 | 30 | group := abTestHash(uuid, testID) 31 | fmt.Printf("UUID %d; Test ID %d; group %d\n", uuid, testID, group) 32 | } 33 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/百度/小度智能助手业务部-07-30/b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。 4 | // 5 | //注意:答案中不可以包含重复的三元组。 6 | // 7 | // 8 | // 9 | // 10 | // 11 | //示例 1: 12 | // 13 | //输入:nums = [-1,0,1,2,-1,-4] 14 | //输出:[[-1,-1,2],[-1,0,1]] 15 | //解释: 16 | //nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。 17 | //nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。 18 | //nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。 19 | //不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。 20 | //注意,输出的顺序和三元组的顺序并不重要。 21 | //示例 2: 22 | // 23 | //输入:nums = [0,1,1] 24 | //输出:[] 25 | //解释:唯一可能的三元组和不为 0 。 26 | //示例 3: 27 | // 28 | //输入:nums = [0,0,0] 29 | //输出:[[0,0,0]] 30 | //解释:唯一可能的三元组和为 0 。 31 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/百度/推荐产品研发组_GOPHP研发工程师-8-29/b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type ListNode struct { 6 | Val int 7 | Next *ListNode 8 | } 9 | 10 | func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode { 11 | dummy := &ListNode{} 12 | 13 | current := dummy 14 | 15 | for l1 != nil && l2 != nil { 16 | if l1.Val <= l2.Val { 17 | current.Next = l1 18 | l1 = l1.Next 19 | } else { 20 | current.Next = l2 21 | l2 = l2.Next 22 | } 23 | current = current.Next 24 | } 25 | 26 | if l1 != nil { 27 | current.Next = l1 28 | } else if l2 != nil { 29 | current.Next = l2 30 | } 31 | return dummy.Next 32 | } 33 | 34 | func main() { 35 | fmt.Println("Hello World!") 36 | } 37 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/百度/百度2022年春实习招聘研发A卷3.22/像素.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/22 4 | @note: 5 | **/ 6 | package main 7 | import ( 8 | "fmt" 9 | "strconv" 10 | ) 11 | 12 | func main() { 13 | n, k := 0, 0 14 | fmt.Scan(&n, &k) 15 | var a = make([][]uint8, n) 16 | for i := range a { 17 | a[i] = make([]uint8, n) 18 | } 19 | for i := 0; i < n; i++ { 20 | for j := 0; j < n; j++ { 21 | fmt.Scan(&a[i][j]) 22 | } 23 | } 24 | 25 | var b = make([][]uint8, n*k) 26 | for i := range b { 27 | b[i] = make([]uint8, n*k) 28 | } 29 | 30 | for i := 0; i < n; i++ { 31 | for j := 0; j < n; j++ { 32 | for c := 0; c < k; c++ { 33 | for d := 0; d < k; d++ { 34 | b[i*k+c][j*k+d] = a[i][j] 35 | } 36 | } 37 | } 38 | } 39 | tmp := "" 40 | for i := 0; i < n*k; i++ { 41 | for j := 0; j < n*k; j++ { 42 | tmp += strconv.Itoa(int(b[i][j])) + " " 43 | } 44 | tmp += "\n" 45 | } 46 | fmt.Print(tmp) 47 | } 48 | 49 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/百度/百度国际化-2024-7-8/1-a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type TreeNode struct { 6 | // Val int 7 | // Left *TreeNode 8 | // Right *TreeNode 9 | //} 10 | 11 | //type ListNode struct { 12 | // Val int 13 | // Next *ListNode 14 | //} 15 | 16 | func main() { 17 | a := twoSum([]int{2, 7, 11, 15}, 9) 18 | fmt.Printf("%v", a) 19 | } 20 | 21 | // 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 22 | func twoSum(nums []int, target int) []int { 23 | hashTable := map[int]int{} 24 | for i, num := range nums { 25 | if preIndex, ok := hashTable[target-num]; ok { 26 | return []int{preIndex, i} 27 | } 28 | hashTable[num] = i 29 | } 30 | return nil 31 | } 32 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/百度/百度在线-2024-7-10/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type TreeNode struct { 6 | // Val int 7 | // Left *TreeNode 8 | // Right *TreeNode 9 | //} 10 | 11 | //type ListNode struct { 12 | // Val int 13 | // Next *ListNode 14 | //} 15 | 16 | func main() { 17 | fmt.Println("hello world") 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/百度/百度在线-2024-7-10/b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | println("hello world") 5 | } 6 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/知乎-cgl/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | s := make([]int, 5) 7 | s = append(s, 1, 2, 3) 8 | fmt.Println(s) // [0 0 0 0 0 1 2 3] 9 | 10 | s2 := make([]int, 0) 11 | s2 = append(s2, 1, 2, 3, 4) 12 | fmt.Println(s2) // [1 2 3 4] 13 | 14 | a := [3]int{7, 8, 9} 15 | //a := make([]int, 1) 16 | //fmt.Printf("%+v\n", a) // [7 8 9] 17 | //b := ap(a) 18 | //ap(a) 19 | //fmt.Printf("%+v\n", a) // [7 8 9] 20 | app(a) 21 | fmt.Printf("%+v\n", a) // [1 8 9] 22 | } 23 | 24 | func ap(a []int) { 25 | a = append(a, 10) 26 | } 27 | 28 | func ap1(a []int) []int { 29 | a = append(a, 10) 30 | return a 31 | } 32 | 33 | func app(a [3]int) { 34 | a[0] = 1 35 | } 36 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/知乎/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-Interview/实战/知乎/img.png -------------------------------------------------------------------------------- /golang/go-Interview/实战/知乎/题目.md: -------------------------------------------------------------------------------- 1 | ![img.png](img.png) -------------------------------------------------------------------------------- /golang/go-Interview/实战/科大讯飞/contex和channel配套使用/并发.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: HuChao 3 | @since: 2022/8/4 4 | @desc: //TODO 5 | **/ 6 | package main 7 | 8 | import ( 9 | "context" 10 | "fmt" 11 | "time" 12 | ) 13 | 14 | func main() { 15 | ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) 16 | defer cancel() 17 | 18 | result := make(chan int, 0) 19 | asyncDoStuffWithTimeout(ctx, result) 20 | fmt.Printf("restult get: %v", <-result) 21 | } 22 | 23 | func asyncDoStuffWithTimeout(ctx context.Context, result chan int) { 24 | go func() { 25 | select { 26 | case <-ctx.Done(): 27 | fmt.Printf("ctx is done, %v", ctx.Err()) 28 | result <- 0 29 | return 30 | case <-time.After(2 * time.Second): 31 | fmt.Println("set result") 32 | result <- 10 33 | } 34 | }() 35 | } 36 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/腾娱互动/武汉-Z业务部-广告/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type TreeNode struct { 6 | // Val int 7 | // Left *TreeNode 8 | // Right *TreeNode 9 | //} 10 | 11 | //type ListNode struct { 12 | // Val int 13 | // Next *ListNode 14 | //} 15 | 16 | func main() { 17 | fmt.Println("Hello, World!") 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/腾娱互动/武汉/面经-base武汉.md: -------------------------------------------------------------------------------- 1 | # 一面-base武汉-挂-7.9 2 | 3 | 1. 为什么想离职 4 | 2. 对我们的招聘岗位有了解吗 5 | 3. 有去过武汉吗 6 | 4. 自我介绍 7 | 5. 什么时候接触golang的,自学的是么,为什么想到去学go 8 | 6. 分享一下go语言的学习经验 9 | 7. 学习go的时候有没有遇到过什么问题? 10 | 8. 讲一下goroutine与线程有什么不同呢? 11 | 9. 什么情况下会引起panic 12 | 10. 怎么捕获panic 13 | 11. error 和 panic的区别 14 | 12. golang的gc怎么做的 15 | 1. 触发时机是什么? 16 | 2. go的gc为什么要引入短暂的全局停顿 17 | 3. 标记回收的时候怎么解决循环引用的问题 18 | 4. 什么是弱引用,举个例子,比如定义了一个组合类型,一个循环嵌套的关系,什么是弱引用,什么是循环引用 19 | 13. 项目 20 | 1. 在中台系统具体负责哪些 21 | 2. 数据抓取遇到过哪些难点? 22 | 14. 有关注过哪些最新的技术发展 23 | 15. 反问 24 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/腾娱互动/深圳-qq 飞车手游/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //type TreeNode struct { 4 | // Val int 5 | // Left *TreeNode 6 | // Right *TreeNode 7 | //} 8 | 9 | //type ListNode struct { 10 | // Val int 11 | // Next *ListNode 12 | //} 13 | 14 | func main() { 15 | 16 | } -------------------------------------------------------------------------------- /golang/go-Interview/实战/腾娱互动/深圳-欢乐斗地主/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func modifySlice(s []int) { 6 | s[0] = 99 7 | s = append(s, 4) 8 | fmt.Println("Inside modifySlice:", s) // 99 2 3 4 9 | } 10 | 11 | func main() { 12 | slice := make([]int, 0, 6) 13 | slice = append(slice, 1) 14 | slice = append(slice, 2) 15 | slice = append(slice, 3) 16 | modifySlice(slice) 17 | fmt.Println("After modifySlice:", slice) // 99 2 3 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/腾娱互动/深圳-欢乐斗地主/b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | func main() { 9 | wg := sync.WaitGroup{} 10 | for i := 0; i < 10; i++ { 11 | wg.Add(1) 12 | go func(wg *sync.WaitGroup) { 13 | fmt.Println(i) 14 | wg.Done() 15 | }(&wg) 16 | } 17 | wg.Wait() 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/腾讯音乐/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //type TreeNode struct { 4 | // Val int 5 | // Left *TreeNode 6 | // Right *TreeNode 7 | //} 8 | 9 | //type ListNode struct { 10 | // Val int 11 | // Next *ListNode 12 | //} 13 | 14 | func main() { 15 | 16 | } -------------------------------------------------------------------------------- /golang/go-Interview/实战/蓝标传媒/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type TreeNode struct { 6 | // Val int 7 | // Left *TreeNode 8 | // Right *TreeNode 9 | //} 10 | 11 | //type ListNode struct { 12 | // Val int 13 | // Next *ListNode 14 | //} 15 | 16 | func main() { 17 | fmt.Printf("hello world") 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/贝塔科技/数组.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | args := [5]int{0, 1, 2, 3, 4} 7 | slice1 := args[0:2] 8 | fmt.Println("len(slice1):", len(slice1)) // 2 9 | fmt.Println("cap(slice1):", cap(slice1)) // 5 10 | fmt.Printf("%p\n", slice1) // 0xc0000aa060 11 | slice1 = append(slice1, 5) 12 | fmt.Printf("%p\n", slice1) // 0xc0000aa060 13 | fmt.Println(args) // [0 1 5 3 4] 14 | fmt.Println("len(slice1):", len(slice1)) // 3 15 | fmt.Println("cap(slice1):", cap(slice1)) // 5 16 | fmt.Println(slice1) // [0 1 5] 17 | slice1 = append(slice1, 10, 11, 12) 18 | fmt.Printf("%p\n", slice1) // 0xc0000b6000 19 | fmt.Println(args) // [0 1 5 3 4] 20 | fmt.Println(slice1) // [0 1 5 10 11 12] 21 | fmt.Println("len(slice1):", len(slice1)) // 6 22 | fmt.Println("cap(slice1):", cap(slice1)) // 10 23 | } 24 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/贝塔科技/管道.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | var c = make(chan int) 4 | var a string 5 | 6 | func f() { 7 | a = "hello" 8 | c <- 0 9 | } 10 | 11 | func main() { 12 | go f() 13 | <-c 14 | print(a) // hello 15 | } 16 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/迅雷/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //type TreeNode struct { 6 | // Val int 7 | // Left *TreeNode 8 | // Right *TreeNode 9 | //} 10 | 11 | //type ListNode struct { 12 | // Val int 13 | // Next *ListNode 14 | //} 15 | 16 | func main() { 17 | fmt.Println("Hello, World!") 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/迅雷/面经.md: -------------------------------------------------------------------------------- 1 | # 一面 2 | 3 | 1. 自我介绍 4 | 2. 游戏开发参与了哪些 5 | 3. 大体介绍一下抽卡 6 | 4. go 7 | 1. map的读写时间复杂度是多少 8 | 2. 为什么是O1 9 | 3. 冲突了怎么办,怎么解决冲突 10 | 4. map是线程安全的吗 11 | 5. 对map不加锁的话会有什么问题 12 | 6. 举个详细的例子说明一下什么情况下会出现什么问题 13 | 7. 读到一个正在写入的数据是什么意思 14 | 8. 为什么一个在写一个在读会有问题 15 | 9. 为什么会不完整呢,底层的技术细节是什么原因? 16 | 10. 不纠结这个问题,往下走好了 17 | 5. 设计模式 18 | 1. 单例模式有什么好处啊 19 | 2. 和定义一个全局变量有什么区别 20 | 6. 你们公司现在没什么人了吗?只是你们项目被裁了是吧? 21 | 7. 未来的职业规划大概是什么样子的 22 | 23 | -------------------------------------------------------------------------------- /golang/go-Interview/实战/金山云 2023届校招 Golang方向/小明的打车费.md: -------------------------------------------------------------------------------- 1 | 小明的打车费 2 | 3 | **时间限制:** 3000MS 4 | **内存限制:** 589824KB 5 | 6 | **题目描述:** 7 | 8 | 小明经常需要打车,某一天他在打车途中研究起了某打车软件的计费系统,他发现这个软件的计费方式是这样的,打车并没有出租车所谓的起步费,乘客从上车开始计算时长,每分钟收费0.3元,每行驶一公里收取1.8元,如果里程超过20公里,则超过20公里的部分,每公里加收0.7元的远途费。当然虽然打车没有起步费,但是有一个最低消费限制,如果订单金额小于9元则按9元收取。现在给出小明乘车的时间和行驶的里程,请你求出小明需要支付多少钱。 9 | 10 | 输入描述 11 | 12 | ``` 13 | 输入第一行是一个正整数T,表示测试数据的组数。(1<=T<=100) 14 | 15 | 接下来有T行,每行两个正整数t和s,分别表示乘车分钟数和里程。(1<=t,s<=100); 16 | ``` 17 | 18 | 输出描述 19 | 20 | ``` 21 | 对于每组测试数据,输出一个两位小数,表示需要支付的金额。 22 | ``` 23 | 24 | 样例输入 25 | 26 | ``` 27 | 4 28 | 5 2 29 | 3 10 30 | 15 20 31 | 50 70 32 | ``` 33 | 34 | 样例输出 35 | 36 | ``` 37 | 9.00 38 | 18.90 39 | 40.50 40 | 176.00 41 | ``` -------------------------------------------------------------------------------- /golang/go-Interview/实战/金山云 2023届校招 Golang方向/鸽子在转圈.md: -------------------------------------------------------------------------------- 1 | 鸽子在转圈 2 | 3 | **时间限制:** 3000MS 4 | **内存限制:** 589824KB 5 | 6 | **题目描述:** 7 | 8 | 鸽子今天又碰到转转转任务了。转转转任务需要依次点击三个绕着圈旋转的按钮。若在按钮转到指定位置时进行点击则视为成功并继续点击下一个圈,否则视为失败并回到第一个圈继续。每个圈无论成功或失败均耗时1秒。今天她在第一个圈失败了a次,在第二个圈失败了b次,在第三个圈失败了c次,最后成功了一次。已知鸽子今天总共耗时为t和a,b,c其中一个的值,求今天鸽子最多失败了多少次和最少失败了多少次。 9 | 10 | 11 | 12 | 13 | 14 | 输入描述 15 | 16 | 一行,形如x v t,中间用空格隔开。 17 | 18 | 其中x是字母a/b/c中的一个,代表知道的是哪一个值。 19 | 20 | v(1≤v≤106)是上述x具体的值,表示在a/b/c其中一个环节失败的次数。 21 | 22 | t(1≤t≤6*106)是总耗时。 23 | 24 | 25 | 26 | 输出描述 27 | 28 | 在一行中输出用空格分隔的两个数,分别代表鸽子最多/最少失败了多少次。 29 | 30 | 31 | 32 | 33 | 34 | 样例输入 35 | 36 | ``` 37 | a 3 12 38 | ``` 39 | 40 | 样例输出 41 | 42 | ``` 43 | 6 5 44 | ``` 45 | 46 | 47 | 48 | 提示 49 | 50 | ``` 51 | 对于样例,有以下两种可能:在第一个圈失败了三次,第二个圈失败了三次,第三个圈失败了零次,最后成功了一次,总耗时为1+1+1+2+2+2+3=12,共失败六次。在第一个圈失败了三次,第二个圈失败了零次,第三个圈失败了两次,最后成功了一次,总耗时为1+1+1+3+3+3=12,共失败五次。 52 | ``` -------------------------------------------------------------------------------- /golang/go-Interview/实战/金山云2023校招/一面面经.md: -------------------------------------------------------------------------------- 1 | 1. 自我介绍 2 | 2. 有缓冲和无缓冲channel 3 | 3. 面向对象 4 | 4. go如何实现面向对象 5 | 5. 反转链表 6 | 7 | ------ 8 | 9 | 1. java线程池与go携程池的区别 10 | 2. map与sync.map底层 11 | 3. sync.map高并发怎样 12 | 4. 有没有改进它的思路 13 | 5. interface相关知识 14 | 6. 代码:根据输入的文件名称,打印出文件树状结构。 15 | 16 | ------ 17 | 18 | 1. 实习的项目 19 | 2. 这个项目学到了什么。 20 | 3. make new的区别 21 | 4. 设计模式 22 | 23 | 1. 1. 单例 24 | 2. 工厂 25 | 26 | 1. 如何设计一个高并发的系统 27 | 2. sql题 查询年龄第二大的人 -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/Hot100题/104.二叉树的最大深度.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * type TreeNode struct { 4 | * Val int 5 | * Left *TreeNode 6 | * Right *TreeNode 7 | * } 8 | */ 9 | func maxDepth(root *TreeNode) int { 10 | if root == nil { 11 | return 0 12 | } 13 | 14 | leftDepth := maxDepth(root.Left) 15 | rightDepth := maxDepth(root.Right) 16 | if leftDepth > rightDepth { 17 | return leftDepth + 1 18 | }else { 19 | return rightDepth + 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/leetcode/283. 移动零.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:huchao 3 | @data:2022/3/6 4 | @note: 283. 移动零 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func moveZeroes(nums []int) []int { 11 | var left int = 0 12 | var right int = 0 13 | for right < len(nums) { 14 | if nums[right] !=0 { 15 | nums[left],nums[right] = nums[right],nums[left] 16 | left++ 17 | } 18 | right++ 19 | } 20 | return nums 21 | } 22 | 23 | func main() { 24 | arr := []int{0,1,0,3,12} 25 | fmt.Println(moveZeroes(arr)) 26 | } -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/leetcode/6031. 找出数组中的所有 K 近邻下标.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/13 4 | @note: 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | arr := []int{3,4,9,1,3,9,5} 12 | fmt.Println(findKDistantIndices(arr,9,1)) 13 | } 14 | 15 | func findKDistantIndices(nums []int, key int, k int) []int { 16 | var res []int 17 | n := len(nums) 18 | for i := 0; i < n; i++ { 19 | for j := max(0, i-k); j < min(n, i+k+1); j++ { 20 | if nums[j] == key { 21 | res = append(res, i) 22 | break 23 | } 24 | } 25 | } 26 | return res 27 | } 28 | 29 | func max(a, b int) int { 30 | if a > b { 31 | return a 32 | } 33 | return b 34 | } 35 | 36 | func min(a, b int) int { 37 | if a < b { 38 | return a 39 | } 40 | return b 41 | } -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/069. 山峰数组的顶部.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/069. 山峰数组的顶部.exe -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/069. 山峰数组的顶部之二分.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/069. 山峰数组的顶部之二分.exe -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/069. 山峰数组的顶部之二分.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:huchao 3 | @data:2022/3/9 4 | @note:剑指 Offer II 069. 山峰数组的顶部 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | arr := []int{0,10,5,2} 12 | fmt.Println(peakIndexInMountainArray(arr)) 13 | } 14 | 15 | func peakIndexInMountainArray(arr []int) int { 16 | return binarySearch3(arr,1,len(arr)-1) 17 | } 18 | 19 | func binarySearch3(arr []int,left int,right int) int { 20 | 21 | ans := 0 22 | // 当 left > right 时,说明递归整个数组,但是没有找到 23 | for left <=right { 24 | 25 | mid := (right + left) / 2 26 | 27 | if arr[mid] > arr[mid+1] { // 向左移动 28 | ans = mid 29 | right = mid - 1 30 | } else if arr[mid] < arr[mid+1] { // 右移动 31 | left = mid+1 32 | } else { 33 | return mid 34 | } 35 | 36 | } 37 | return ans 38 | } 39 | -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/069山峰数组的顶部之枚举.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/069山峰数组的顶部之枚举.exe -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/069山峰数组的顶部之枚举.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:huchao 3 | @data:2022/3/9 4 | @note:剑指 Offer II 069. 山峰数组的顶部 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | func main() { 13 | arr := []int{1,3,5,4,2} 14 | fmt.Println(peakIndexInMountainArray2(arr)) 15 | } 16 | 17 | func peakIndexInMountainArray2(arr []int) int { 18 | ans := 1 19 | for i := 2; i < len(arr)-1; i++ { 20 | if arr[ans] > arr[i] { 21 | return ans 22 | } 23 | ans = i 24 | } 25 | return ans 26 | } -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/072. 求平方根之二分.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/072. 求平方根之二分.exe -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/072. 求平方根之二分.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:huchao 3 | @data:2022/3/10 4 | @note:剑指 Offer II 072. 求平方根 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | fmt.Println(mySqrt2(8)) 12 | } 13 | 14 | func mySqrt2(x int) int { 15 | left, right := 1, x 16 | for left < right { 17 | mid := left + (right - left) / 2 18 | if x/mid > mid { 19 | left = mid + 1 20 | } else if x/mid < mid { 21 | right = mid 22 | } else { 23 | return mid 24 | } 25 | } 26 | if left * left > x { 27 | return left - 1 28 | } else { 29 | return left 30 | } 31 | return left 32 | } 33 | 34 | -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/072. 求平方根之二分2.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:huchao 3 | @data:2022/3/10 4 | @note:剑指 Offer II 072. 求平方根之二分2 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | func main() { 13 | fmt.Println(mySqrt3(8)) 14 | } 15 | 16 | func mySqrt3(x int) int { 17 | var left,right = 0 ,x 18 | for left < right { 19 | mid := left + (right-left)/2 20 | if x / mid > mid { 21 | left = mid + 1 22 | }else if x/mid < mid { 23 | right = mid 24 | }else { 25 | return mid 26 | } 27 | } 28 | if left * left > x { 29 | return left - 1 30 | }else { 31 | return left 32 | } 33 | } -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/072. 求平方根之暴力.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:huchao 3 | @data:2022/3/10 4 | @note:剑指 Offer II 072. 求平方根 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | var x = 2 12 | fmt.Println(mySqrt(x)) 13 | } 14 | 15 | func mySqrt(x int) int { 16 | var i = 1 17 | if x == 0 { 18 | return 0 19 | } 20 | for i <= x { 21 | if x / i > i { 22 | i = i + 1 23 | }else if x / i < i { 24 | return i -1 25 | }else { 26 | return i 27 | } 28 | } 29 | return i 30 | } -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/剑指 Offer II 068. 查找插入位置.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/剑指 Offer II 068. 查找插入位置.exe -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/剑指 Offer II 068. 查找插入位置2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/剑指 Offer II 068. 查找插入位置2.exe -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/剑指 Offer II 068. 查找插入位置2二分.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:huchao 3 | @data:2022/3/9 4 | @note:剑指 Offer II 068. 查找插入位置 二分2 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | arr := []int{1,3,5,6} 12 | fmt.Println(searchInsert2(arr,7)) 13 | } 14 | 15 | func searchInsert2(nums []int, target int) int { 16 | return binarySearch2(nums,0,len(nums)-1,target) 17 | } 18 | 19 | func binarySearch2(arr []int,left int,right int,findVal int) int { 20 | 21 | // 当 left > right 时,说明递归整个数组,但是没有找到 22 | for left <=right { 23 | 24 | mid := (right + left) / 2 25 | midVal := arr[mid] 26 | 27 | if findVal > midVal { // 向右移动 28 | left = mid+1 29 | } else if findVal < midVal { // 向左移动 30 | right = mid-1 31 | } else { 32 | return mid 33 | } 34 | } 35 | return left 36 | 37 | } 38 | -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/剑指 Offer II 070. 排序数组中只出现一次的数字之二分.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-Interview/算法/Leetcode/剑指 Offer(专项突击版)/剑指 Offer II 070. 排序数组中只出现一次的数字之二分.exe -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指offer2/剑指 Offer 40. 最小的k个数之堆排序.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-Interview/算法/Leetcode/剑指offer2/剑指 Offer 40. 最小的k个数之堆排序.exe -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指offer2/剑指 Offer 45. 把数组排成最小的数.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-Interview/算法/Leetcode/剑指offer2/剑指 Offer 45. 把数组排成最小的数.exe -------------------------------------------------------------------------------- /golang/go-Interview/算法/Leetcode/剑指offer2/剑指 Offer 45. 把数组排成最小的数.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Huchao 3 | @data:2022/3/6 4 | @note: 剑指 Offer 45. 把数组排成最小的数 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "strings" 11 | ) 12 | 13 | func main() { 14 | //[3,30,34,5,9] 15 | arr := []int{3, 30, 34, 5, 9} 16 | //minNumber(arr) 17 | fmt.Println(minNumber(arr)) 18 | } 19 | 20 | func minNumber(nums []int) string { 21 | BubbleSort(nums) 22 | temp := make([]string, len(nums)) 23 | for i, num := range nums { 24 | temp[i] = fmt.Sprintf("%d", num) 25 | } 26 | result := strings.Join(temp, "") 27 | return strings.ReplaceAll(result, "\\[|]|,|\\s", "") 28 | } 29 | 30 | //交换排序-冒泡排序 31 | func BubbleSort(arr []int) []int { 32 | for i := 0; i < len(arr); i++ { 33 | for j := i + 1; j < len(arr); j++ { 34 | if strings.Compare(string(arr[i]+arr[j]), string(arr[j]+arr[i])) > 0 { 35 | arr[i], arr[j] = arr[j], arr[i] 36 | } 37 | } 38 | } 39 | return arr 40 | } 41 | -------------------------------------------------------------------------------- /golang/go-Interview/算法/sort/交换排序-冒泡排序/BubbleSort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func BubbleSort(list []int) { 6 | n := len(list) 7 | // 在一轮中有没有交换过 8 | didSwap := false 9 | 10 | // 进行 N-1 轮迭代 11 | for i := n - 1; i > 0; i-- { 12 | // 每次从第一位开始比较,比较到第 i 位就不比较了,因为前一轮该位已经有序了 13 | for j := 0; j < i; j++ { 14 | // 如果前面的数比后面的大,那么交换 15 | if list[j] > list[j+1] { 16 | list[j], list[j+1] = list[j+1], list[j] 17 | didSwap = true 18 | } 19 | } 20 | 21 | // 如果在一轮中没有交换过,那么已经排好序了,直接返回 22 | if !didSwap { 23 | return 24 | } 25 | } 26 | } 27 | 28 | func main() { 29 | list := []int{5, 9, 1, 6, 8, 14, 6, 49, 25, 4, 6, 3} 30 | BubbleSort(list) 31 | fmt.Println(list) 32 | } 33 | -------------------------------------------------------------------------------- /golang/go-Interview/算法/sort/交换排序-快速排序/快排.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:胡超 3 | @data:2022/3/5 4 | @note: golang实现十大经典算法:交换排序-快速排序 5 | **/ 6 | package main 7 | 8 | func main() { 9 | l := []int{0, 0, 0, 14124, 124124, 1} 10 | quicksort2(l, 0, len(l)-1) 11 | } 12 | 13 | func partion(a []int, start int, end int) int { 14 | pivot, i, j := a[start], start, end 15 | //将第一个元素作为pivot 16 | for i < j { 17 | for i < j && pivot < a[j] { //从右边开始找出小于pivot的 18 | j-- 19 | } 20 | if i < j { 21 | a[i] = a[j] 22 | i++ 23 | } 24 | for i < j && a[i] < pivot { //找出大于pivot 25 | i++ 26 | } 27 | if i < j { 28 | a[j] = a[i] 29 | j-- 30 | } 31 | } 32 | a[i] = pivot //这时i是pivot最终位置 33 | return i 34 | } 35 | func quicksort2(a []int, start int, end int) { 36 | if start < end { 37 | d := partion(a, start, end) 38 | quicksort2(a, start, d-1) 39 | quicksort2(a, d+1, end) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /golang/go-Interview/算法/sort/交换排序-快速排序/快速排序.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:huchao 3 | @data:2022/3/5 4 | @note:交换排序-快速排序 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func QuickSort1(arr []int) []int { 11 | if len(arr) <= 1 { 12 | return arr 13 | } 14 | splitdata := arr[0] //第一个数据 15 | low := make([]int, 0, 0) //比我小的数据 16 | hight := make([]int, 0, 0) //比我大的数据 17 | mid := make([]int, 0, 0) //与我一样大的数据 18 | mid = append(mid, splitdata) //加入一个 19 | for i := 1; i < len(arr); i++ { 20 | if arr[i] < splitdata { 21 | low = append(low, arr[i]) 22 | } else if arr[i] > splitdata { 23 | hight = append(hight, arr[i]) 24 | } else { 25 | mid = append(mid, arr[i]) 26 | } 27 | } 28 | low, hight = QuickSort1(low), QuickSort1(hight) 29 | myarr := append(append(low, mid...), hight...) 30 | return myarr 31 | } 32 | 33 | //快速排序算法 34 | func main() { 35 | arr := []int{1, 9, 10, 30, 2, 5, 45, 8, 63, 234, 12} 36 | fmt.Println(QuickSort1(arr)) 37 | } 38 | -------------------------------------------------------------------------------- /golang/go-Interview/算法/sort/选择排序-简单选择排序/selectsort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | //SelectSort 选择排序-简单选择排序 8 | // 最好、最坏、平均时间复杂度均为:O(n^2), 9 | // 空间复杂度:O(1) 10 | // 稳定性:不稳定 如:5 5 2 11 | func SelectSort(arr []int) []int { 12 | //1. 先完成将第一个最大值和 arr[0] => 先易后难 13 | //1 假设 arr[0] 最大值 14 | for j := 0; j < len(arr)-1; j++ { 15 | 16 | max := arr[j] 17 | maxIndex := j 18 | //2. 遍历后面 j + 1---[len(arr) -1] 比较 19 | for i := j + 1; i < len(arr); i++ { 20 | if max < arr[i] { //找到真正的最大值 21 | max = arr[i] 22 | maxIndex = i 23 | } 24 | } 25 | //交换 26 | if maxIndex != j { 27 | arr[j], arr[maxIndex] = arr[maxIndex], arr[j] 28 | } 29 | fmt.Printf("第%d次 %v\n ", j+1, arr) 30 | } 31 | return arr 32 | } 33 | 34 | func main() { 35 | //定义一个数组 36 | arr := []int{10, 34, 19, 100, 80, 789} 37 | selectSort := SelectSort(arr) 38 | fmt.Println(selectSort) 39 | } 40 | -------------------------------------------------------------------------------- /golang/go-Interview/算法/大数计算/big库函数版本.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:HuChao 3 | @data:2022/9/24 4 | @note: 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "math/big" 11 | ) 12 | 13 | func main() { 14 | var a, b string 15 | fmt.Scan(&a) 16 | fmt.Scan(&b) 17 | t1, _ := new(big.Int).SetString(a, 16) 18 | t2, _ := new(big.Int).SetString(b, 16) 19 | dummy := t1.Add(t1, t2) 20 | fmt.Print(dummy) 21 | } 22 | -------------------------------------------------------------------------------- /golang/go-Interview/算法/大数计算/go-bigger.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/9/24 4 | @note: 5 | **/ 6 | 7 | //https://blog.csdn.net/a568283992/article/details/119698329 8 | 9 | package main 10 | 11 | import ( 12 | "fmt" 13 | ) 14 | 15 | func main() { 16 | a := big_integer.ValueOf(6782613786431) 17 | b := big_integer.ValueOf(-678261378231) 18 | res := a.Add(b) 19 | fmt.Println(res.String()) 20 | } 21 | -------------------------------------------------------------------------------- /golang/go-Interview/算法/尚硅谷/migong/demo01/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | import ( 3 | "fmt" 4 | ) 5 | 6 | func test(n int) { 7 | if n > 2 { 8 | n-- // 死龟 9 | test(n) 10 | } else { 11 | fmt.Println("n=", n) 12 | } 13 | 14 | } 15 | 16 | func main() { 17 | 18 | n := 4 19 | test(n) 20 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/内存管理/逃逸分析/3.1 指针逃逸.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/19 4 | @note: 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | type Student struct { 11 | Name string 12 | Age int 13 | } 14 | 15 | func StudentRegister(name string, age int) *Student { 16 | s := new(Student) //局部变量s逃逸到堆 17 | 18 | s.Name = name 19 | s.Age = age 20 | 21 | return s 22 | } 23 | 24 | func main() { 25 | fmt.Println(StudentRegister("Jim", 18)) 26 | } 27 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/内存管理/逃逸分析/3.2 栈空间不足逃逸.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/19 4 | @note: 5 | **/ 6 | package main 7 | 8 | //我们发现当切片长度扩大到10000时就会逃逸。 9 | // 10 | //实际上当栈空间不足以存放当前对象时或无法判断当前切片长度时会将对象分配到堆中。 11 | 12 | func Slice() { 13 | s := make([]int, 1000, 1000) 14 | 15 | for index, _ := range s { 16 | s[index] = index 17 | } 18 | } 19 | 20 | func main() { 21 | Slice() 22 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/内存管理/逃逸分析/3.3 动态类型逃逸.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/19 4 | @note: 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | s := "Escape" 12 | fmt.Println(s) // 很多函数参数为interface类型,比如fmt.Println(a …interface{}),编译期间很难确定其参数的具体类型,也会产生逃逸。 13 | 14 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/内存管理/逃逸分析/3.4 闭包引用对象逃逸.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/19 4 | @note: 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func Fibonacci() func() int { 11 | a, b := 0, 1 12 | return func() int { 13 | a, b = b, a+b 14 | return a 15 | } 16 | } 17 | 18 | func main() { 19 | f := Fibonacci() 20 | 21 | for i := 0; i < 10; i++ { 22 | fmt.Printf("Fibonacci: %d\n", f()) 23 | } 24 | } 25 | 26 | //Fibonacci()函数中原本属于局部变量的a和b由于闭包的引用,不得不将二者放到堆上,以致产生逃逸 -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/协程/协程调度/协程调度.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/协程/协程调度/协程调度.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/协程/协程调度/协程调度.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/19 4 | @note: 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "runtime" 11 | ) 12 | 13 | func main() { 14 | a := runtime.GOMAXPROCS(10) 15 | fmt.Println(a) 16 | } 17 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/defer/2.1 题目一.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/defer/2.1 题目一.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/defer/2.1 题目一.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/13 4 | @note: 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | deferFuncParameter() // 延迟函数fmt.Println(aInt)的参数在defer语句出现时就已经确定了,所以无论后面如何修改aInt变量都不会影响延迟函数。 12 | } 13 | 14 | func deferFuncParameter() { 15 | var aInt = 1 16 | 17 | defer fmt.Println(aInt) 18 | 19 | aInt = 2 20 | return 21 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/defer/2.2 题目二.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/defer/2.2 题目二.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/defer/2.2 题目二.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/13 4 | @note: 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func printArray(array *[3]int) { 11 | for i := range array { 12 | fmt.Println(array[i]) 13 | } 14 | } 15 | 16 | func deferFuncParameter2() { 17 | var aArray = [3]int{1, 2, 3} 18 | 19 | defer printArray(&aArray) 20 | 21 | aArray[0] = 10 // 修改数组第一个元素 22 | return 23 | } 24 | // 延迟函数printArray()的参数在defer语句出现时就已经确定了, 25 | // 即数组的地址, 26 | // 由于延迟函数执行时机是在return语句之前, 27 | // 所以对数组的最终修改值会被打印出来。 28 | 29 | func main() { 30 | deferFuncParameter2() 31 | } 32 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/defer/2.3 题目三.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/defer/2.3 题目三.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/defer/2.3 题目三.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/13 4 | @note: 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | fmt.Println(deferFuncReturn3()) 12 | } 13 | 14 | func deferFuncReturn3() (result int) { 15 | i := 1 16 | 17 | defer func() { 18 | result++ 19 | }() 20 | 21 | return i 22 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/defer/3.3.3 主函数拥有匿名返回值,返回变量.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/defer/3.3.3 主函数拥有匿名返回值,返回变量.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/defer/3.3.3 主函数拥有匿名返回值,返回变量.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/13 4 | @note: 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | fmt.Println(foo()) 12 | } 13 | 14 | func foo() int { 15 | var i int 16 | 17 | defer func() { 18 | i++ 19 | }() 20 | 21 | return i 22 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/range/2.1 题目一:切片遍历.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/range/2.1 题目一:切片遍历.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/range/2.1 题目一:切片遍历.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/18 4 | @note: 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | slice := []int{1,2,3,4,5,6} 12 | RangeSlice(slice) 13 | fmt.Println(slice) 14 | } 15 | 16 | func RangeSlice(slice []int) { 17 | for index, value := range slice { 18 | _, _ = index, value 19 | } 20 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/range/2.3 题目三:动态遍历.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/18 4 | @note: 5 | **/ 6 | package main 7 | 8 | func main() { 9 | v := []int{1, 2, 3} 10 | for i := range v { 11 | v = append(v, i) 12 | } 13 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/select/2.1 题目1.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/select/2.1 题目1.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/select/2.2 题目2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/select/2.2 题目2.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/select/2.2 题目2.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/18 4 | @note: 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "time" 11 | ) 12 | 13 | func main() { 14 | chan1 := make(chan int) 15 | chan2 := make(chan int) 16 | 17 | writeFlag := false 18 | go func() { 19 | for { 20 | if writeFlag { 21 | chan1 <- 1 22 | } 23 | time.Sleep(time.Second) 24 | close(chan1) 25 | } 26 | }() 27 | 28 | go func() { 29 | for { 30 | if writeFlag { 31 | chan2 <- 1 32 | } 33 | time.Sleep(time.Second) 34 | close(chan2) 35 | } 36 | }() 37 | 38 | select { 39 | case <-chan1: 40 | fmt.Println("chan1 ready.") 41 | case <-chan2: 42 | fmt.Println("chan2 ready.") 43 | } 44 | 45 | fmt.Println("main exit.") 46 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/select/2.3 题目3.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/select/2.3 题目3.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/select/2.3 题目3.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/18 4 | @note: 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | func main() { 13 | chan1 := make(chan int) 14 | chan2 := make(chan int) 15 | 16 | go func() { 17 | close(chan1) 18 | }() 19 | 20 | go func() { 21 | close(chan2) 22 | }() 23 | 24 | select { 25 | case <-chan1: 26 | fmt.Println("chan1 ready.") 27 | case <-chan2: 28 | fmt.Println("chan2 ready.") 29 | } 30 | 31 | fmt.Println("main exit.") 32 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/select/2.4 题目4.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/select/2.4 题目4.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见控制结构实现原理/select/2.4 题目4.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/18 4 | @note: 5 | **/ 6 | package main 7 | 8 | func main() { 9 | select { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/chan/main.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/chan/main.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/chan/main.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/13 4 | @note: 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "time" 11 | ) 12 | 13 | func main() { 14 | for i := 0; i < 5; i++ { 15 | go func(i int) { 16 | fmt.Println(i) 17 | }(i) 18 | time.Sleep(time.Millisecond) 19 | } 20 | time.Sleep(1*time.Second) 21 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/chan/select.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/chan/select.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/chan/select.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/13 4 | @note: 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "time" 11 | ) 12 | 13 | func addNumberToChan(chanName chan int) { 14 | for { 15 | chanName <- 1 16 | time.Sleep(1 * time.Second) 17 | } 18 | } 19 | 20 | func main() { 21 | var chan1 = make(chan int, 10) 22 | var chan2 = make(chan int, 10) 23 | 24 | go addNumberToChan(chan1) 25 | go addNumberToChan(chan2) 26 | 27 | for { 28 | select { 29 | case e := <- chan1 : 30 | fmt.Printf("Get element from chan1: %d\n", e) 31 | case e := <- chan2 : 32 | fmt.Printf("Get element from chan2: %d\n", e) 33 | default: 34 | fmt.Printf("No element in chan1 and chan2.\n") 35 | time.Sleep(1 * time.Second) 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/chan/多返回值模式.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/chan/多返回值模式.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/chan/多返回值模式.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/13 4 | @note: 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func f2(ch chan int) { 11 | for { 12 | v, ok := <-ch 13 | if !ok { 14 | fmt.Println("通道已关闭") 15 | break 16 | } 17 | fmt.Printf("v:%#v ok:%#v\n", v, ok) 18 | } 19 | } 20 | 21 | func main() { 22 | ch := make(chan int, 1) 23 | ch <- 1 24 | //ch <- 2 25 | close(ch) 26 | f2(ch) 27 | } 28 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/iota/main.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/iota/main.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/iota/main.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/12 4 | @note: iota 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | //iota常用于const表达式中,我们还知道其值是从零开始,const声明块中每增加一行iota值自增1 11 | 12 | // iota初始值为0,也即LOG_EMERG值为0,下面每个常量递增1。 13 | type Priority int 14 | const ( 15 | LOG_EMERG Priority = iota 16 | LOG_ALERT 17 | LOG_CRIT 18 | LOG_ERR 19 | LOG_WARNING 20 | LOG_NOTICE 21 | LOG_INFO 22 | LOG_DEBUG 23 | ) 24 | 25 | func main() { 26 | fmt.Println(1 << 3) 27 | fmt.Println(1<<2) 28 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/map/值为切片类型的map.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/12 4 | @note: 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | var sliceMap = make(map[string][]string, 3) 12 | fmt.Println(sliceMap) 13 | fmt.Println("after init") 14 | key := "中国" 15 | value, ok := sliceMap[key] 16 | if !ok { 17 | value = make([]string, 0, 2) 18 | } 19 | value = append(value, "北京", "上海") 20 | sliceMap[key] = value 21 | fmt.Println(sliceMap) 22 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/map/元素为map类型的切片.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/map/元素为map类型的切片.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/map/元素为map类型的切片.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/12 4 | @note: 元素为map类型的切片 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | func main() { 13 | var mapSlice = make([]map[string]string, 3) 14 | for index, value := range mapSlice { 15 | fmt.Printf("index:%d value:%v\n", index, value) 16 | } 17 | fmt.Println("after init") 18 | // 对切片中的map元素进行初始化 19 | mapSlice[0] = make(map[string]string, 10) 20 | mapSlice[0]["name"] = "王五" 21 | mapSlice[0]["password"] = "123456" 22 | mapSlice[0]["address"] = "红旗大街" 23 | for index, value := range mapSlice { 24 | fmt.Printf("index:%d value:%v\n", index, value) 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/slice/2.1 题目一.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/slice/2.1 题目一.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/slice/2.1 题目一.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:huchao 3 | @data:2022/3/10 4 | @note: 2.1 题目一 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | var array [10]int // 定义了一个10个长度的整型数组array 12 | 13 | var slice = array[5:6] // 定义了一个切片slice,切取数组的第6个元素 14 | 15 | fmt.Println(array) // [0 0 0 0 0 0 0 0 0 0] 16 | fmt.Println(slice) // [0] 17 | fmt.Println("lenth of 数组与切片: ", len(slice)) // 1 18 | fmt.Println("capacity of 数组与切片: ", cap(slice)) // 5 19 | fmt.Println(&slice[0] == &array[5]) // true 20 | // slice根据数组array创建,与数组共享存储空间, 21 | // slice起始位置是array[5],长度为1,容量为5,数组与切片[0]和array[5]地址相同。 22 | } 23 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/slice/2.2 题目二.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:huchao 3 | @data:2022/3/10 4 | @note:2.2 题目二 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | //函数AddElement()接受一个切片和一个元素,把元素append进切片中,并返回切片 13 | func AddElement(slice []int, e int) []int { 14 | return append(slice, e) 15 | } 16 | 17 | func main() { 18 | var slice []int 19 | fmt.Println(cap(slice)) 20 | slice = append(slice, 1,2,3) 21 | fmt.Println(cap(slice)) 22 | 23 | newSlice := AddElement(slice, 4) // 向切片append进第4个元素同时定义一个新的切片newSlice 24 | //newSlice = AddElement(newSlice,5) 25 | 26 | //fmt.Println(cap(newSlice)) 27 | fmt.Printf("%p,%p",slice,newSlice) 28 | fmt.Println(&slice[0] == &newSlice[0]) // 新切片newSlice与旧切片slice是否共用一块存储空间 29 | 30 | //append函数执行时会判断切片容量是否能够存放新增元素, 31 | //如果不能,则会重新申请存储空间,新存储空间将是原来的2倍或1.25倍(取决于扩展原空间大小), 32 | //本例中实际执行了两次append操作,第一次空间增长到4, 33 | //所以第二次append不会再扩容,所以新旧两个切片将共用一块存储空间。程序会输出”true”。 34 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/slice/2.3 题目三.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:huchao 3 | @data:2022/3/10 4 | @note: 2.3 题目三 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | func main() { 13 | 14 | orderLen := 5 15 | order := make([]uint16, 2 * orderLen) // 定义一个长度为10的切片order 16 | 17 | // pollorder和lockorder分别是对order切片做了order[low:high:max]操作生成的切片 18 | pollorder := order[:orderLen:orderLen] // 指的是order的前半部分切片 19 | lockorder := order[orderLen:][:orderLen:orderLen] // 指的是order的后半部分切片,即原order分成了两段 20 | 21 | a := order[:5:5] 22 | b := order[5:][:5:5] 23 | 24 | // 分别打印pollorder和lockorder的容量和长度 25 | fmt.Println("len(pollorder) = ", len(pollorder)) // 5 26 | fmt.Println("cap(pollorder) = ", cap(pollorder)) // 5 27 | fmt.Println("len(lockorder) = ", len(lockorder)) // 5 28 | fmt.Println("cap(lockorder) = ", cap(lockorder)) // 5 29 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/slice/3.3 使用数组创建Slice.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/slice/3.3 使用数组创建Slice.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/slice/3.3 使用数组创建Slice.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:huchao 3 | @data:2022/3/12 4 | @note: 3.3 使用数组创建Slice 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | 12 | //使用数组来创建Slice时,Slice将与原数组共用一部分内存。 13 | var array [10]int 14 | slice := array[5:7] 15 | fmt.Println(len(slice)) // 2 切片从数组array[5]开始,到数组array[7]结束(不含array[7]),即切片长度为2 16 | fmt.Println(cap(slice)) // 5 数组后面的内容都作为切片的预留内存,即capacity为5。 17 | fmt.Println(&array[5] == &slice[0]) // true 18 | 19 | fmt.Printf("%p,%p",slice,array) 20 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/string/main.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/12 4 | @note: string 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | var a []string 12 | a = append(a, "sdf","sdff","sd") 13 | fmt.Println(concatstrings(a)) 14 | //str := "Str1" + "Str2" + "Str3" 15 | fmt.Println(concatstrings(a)) 16 | } 17 | 18 | func concatstrings(a []string) string { // 字符串拼接 19 | length := 0 // 拼接后总的字符串长度 20 | 21 | for _, str := range a { 22 | length += len(str) 23 | } 24 | 25 | s, b := rawstring(length) // 生成指定大小的字符串,返回一个string和切片,二者共享内存空间 26 | 27 | for _, str := range a { 28 | copy(b, str) // string无法修改,只能通过切片修改 29 | b = b[len(str):] 30 | } 31 | 32 | return s 33 | } 34 | // 因为string是无法直接修改的, 35 | // 所以这里使用rawstring()方法初始化一个指定大小的string, 36 | // 同时返回一个切片,二者共享同一块内存空间, 37 | // 后面向切片中拷贝数据,也就间接修改了string。 38 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/string/string和byte.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/string/string和byte.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/string/string和byte.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:huchao 3 | @data:2022/3/12 4 | @note: string 和 byte[] 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | var s []byte 12 | s = append(s,'1','2','s','a') 13 | str := GetStringBySlice(s) 14 | fmt.Println(len(s)) 15 | fmt.Println(len(str)) 16 | fmt.Println("%p\n,%p\n",s,str) 17 | } 18 | 19 | //[]byte转string 20 | func GetStringBySlice(s []byte) string { 21 | return string(s) 22 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/struct/获取Tag.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/struct/获取Tag.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/常见数据结构实现原理/struct/获取Tag.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/12 4 | @note: 2.3 获取Tag 5 | **/ 6 | package main 7 | 8 | import ( 9 | "reflect" 10 | "fmt" 11 | ) 12 | 13 | type Server struct { 14 | ServerName string `key1:"value1" key11:"value11"` 15 | ServerIP string `key2:"value2"` 16 | } 17 | 18 | func main() { 19 | s := Server{} 20 | st := reflect.TypeOf(s) 21 | 22 | field1 := st.Field(0) 23 | fmt.Printf("key1:%v\n", field1.Tag.Get("key1")) 24 | fmt.Printf("key11:%v\n", field1.Tag.Get("key11")) 25 | 26 | filed2 := st.Field(1) 27 | fmt.Printf("key2:%v\n", filed2.Tag.Get("key2")) 28 | 29 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/并发控制/WaitGroup/Wait-Goroutine-Group.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/并发控制/WaitGroup/Wait-Goroutine-Group.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/并发控制/WaitGroup/Wait-Goroutine-Group.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/20 4 | @note: 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "time" 11 | "sync" 12 | ) 13 | 14 | func main() { 15 | var wg sync.WaitGroup 16 | 17 | wg.Add(2) //设置计数器,数值即为goroutine的个数 18 | go func() { 19 | //Do some work 20 | time.Sleep(1*time.Second) 21 | 22 | fmt.Println("Goroutine 1 finished!") 23 | wg.Done() //goroutine执行结束后将计数器减1 24 | }() 25 | 26 | go func() { 27 | //Do some work 28 | time.Sleep(2*time.Second) 29 | 30 | fmt.Println("Goroutine 2 finished!") 31 | wg.Done() //goroutine执行结束后将计数器减1 32 | }() 33 | 34 | wg.Wait() //主goroutine阻塞等待计数器变为0 35 | fmt.Printf("All Goroutine finished!") 36 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/并发控制/channel/2. 场景示例.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/GO文档/GO专家编程/并发控制/channel/2. 场景示例.exe -------------------------------------------------------------------------------- /golang/go-study/GO文档/GO专家编程/并发控制/channel/2. 场景示例.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/20 4 | @note: 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "time" 11 | ) 12 | 13 | func Process(ch chan int) { 14 | //Do some work... 15 | time.Sleep(time.Second) 16 | 17 | ch <- 1 //管道中写入一个元素表示当前协程已结束 18 | } 19 | 20 | func main() { 21 | channels := make([]chan int, 10) //创建一个10个元素的切片,元素类型为channel 22 | 23 | for i:= 0; i < 10; i++ { 24 | channels[i] = make(chan int) //切片中放入一个channel 25 | go Process(channels[i]) //启动协程,传一个管道用于通信 26 | } 27 | 28 | for i, ch := range channels { //遍历切片,等待子协程结束 29 | a := <-ch 30 | fmt.Println("Routine ", i, " quit!") 31 | fmt.Println(a) 32 | } 33 | } -------------------------------------------------------------------------------- /golang/go-study/GO文档/GitBook/Golang/在 Go 中恰到好处的内存对齐.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/13 4 | @note: 在 go进阶14讲 中恰到好处的内存对齐 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "unsafe" 11 | ) 12 | 13 | type Part1 struct { 14 | a bool 15 | b int32 16 | c int8 17 | d int64 18 | e byte 19 | } 20 | 21 | func main() { 22 | fmt.Printf("bool size: %d\n", unsafe.Sizeof(bool(true))) 23 | fmt.Printf("int32 size: %d\n", unsafe.Sizeof(int32(0))) 24 | fmt.Printf("int8 size: %d\n", unsafe.Sizeof(int8(0))) 25 | fmt.Printf("int64 size: %d\n", unsafe.Sizeof(int64(0))) 26 | fmt.Printf("byte size: %d\n", unsafe.Sizeof(byte(0))) 27 | fmt.Printf("string size: %d\n", unsafe.Sizeof("EDDYCJY")) 28 | } 29 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/demo/实现并行的 for 循环.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | func process(item int) { 9 | // 这里可以放你的处理代码 10 | fmt.Println(item) 11 | } 12 | 13 | func main() { 14 | data := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 15 | 16 | var wg sync.WaitGroup // 使用sync.WaitGroup来等待所有goroutines完成 17 | wg.Add(len(data)) 18 | 19 | for _, item := range data { 20 | go func(item int) { 21 | defer wg.Done() // 当goroutine完成时,调用Done 22 | process(item) 23 | }(item) 24 | } 25 | 26 | wg.Wait() // 等待所有goroutines完成 27 | } 28 | 29 | //在这个示例中: 30 | // 31 | //1、我们使用了sync.WaitGroup来确保主函数等待所有goroutines完成。 32 | //2、对于数据切片中的每个元素,我们都启动了一个新的goroutine来处理该元素。 33 | //3、在goroutine内部,我们调用process()函数来处理该元素。 34 | //4、当goroutine完成其工作后,我们调用wg.Done()来告诉WaitGroup一个goroutine已完成。 35 | //5、在所有goroutines都启动后,我们调用wg.Wait()来等待它们都完成。 36 | //6、这样,我们就实现了一个并行的for循环,其中每个元素都在其自己的goroutine中并行处理。 37 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/examples/chapter_14/blocking.go: -------------------------------------------------------------------------------- 1 | // blocking.go 2 | // throw: all goroutines are asleep - deadlock! 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "sync" 8 | ) 9 | 10 | func f1(in chan int, wg *sync.WaitGroup) { 11 | defer wg.Done() 12 | fmt.Println("in:===", <-in) 13 | } 14 | 15 | func main() { 16 | wg := sync.WaitGroup{} 17 | wg.Add(1) 18 | out := make(chan int) 19 | //out := make(chan int, 1) // solution 2 20 | //go f1(out, &wg) // solution 1 21 | out <- 2 22 | go f1(out, &wg) // solution 2 23 | wg.Wait() 24 | } 25 | 26 | // 这段代码会造成死锁。问题的根源是在 out <- 2 处。在此处,主 goroutine 尝试向 out 通道发送一个整数值,但是没有其他的 goroutine 在接收这个值,导致主 goroutine 被阻塞。 27 | //这是一个常见的 Go 并发模型中的问题。当一个 goroutine 尝试向一个无缓冲的通道发送数据时,它会阻塞,直到另一个 goroutine 从该通道读取数据。但在这段代码中,在发送数据之前没有启动任何接收数据的 goroutine,所以会出现死锁。 28 | // 有两种解决方案: 29 | // 向通道发送数据之前,启动一个 goroutine 来接收数据。 30 | // 将通道的容量设置为 1,这样就可以发送一个数据,然后再阻塞。 31 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/examples/chapter_14/channel_block.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | var cnt = 0 9 | 10 | func main() { 11 | ch1 := make(chan int) 12 | go pump(ch1) // pump hangs 13 | fmt.Println(<-ch1) // prints only 0 14 | 15 | time.Sleep(time.Second) 16 | fmt.Println(cnt) // prints 1 17 | 18 | } 19 | 20 | func pump(ch chan int) { 21 | for i := 0; ; i++ { 22 | ch <- i // the channel will be block due to lack of consumer 23 | cnt++ // this code will only execute once 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/examples/chapter_14/channel_block2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | ch1 := make(chan int) 10 | go pump2(ch1) 11 | go suck(ch1) // tons of numbers appear 12 | time.Sleep(1e9) 13 | } 14 | 15 | func pump2(ch chan int) { 16 | for i := 0; ; i++ { 17 | ch <- i 18 | } 19 | } 20 | 21 | func suck(ch chan int) { 22 | for { 23 | fmt.Println(<-ch) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/examples/chapter_14/channel_block3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | import "time" 5 | 6 | func main() { 7 | c := make(chan int, 1) 8 | go func() { 9 | time.Sleep(15 * 1e9) 10 | x := <-c 11 | fmt.Println("received", x) 12 | }() 13 | fmt.Println("sending", 10) 14 | c <- 10 15 | fmt.Println("sent", 10) 16 | } 17 | 18 | /* Output: 19 | sending 10 20 | (15 s later): 21 | received 10 22 | sent 10 23 | */ 24 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/examples/chapter_14/channel_buffer.go: -------------------------------------------------------------------------------- 1 | // 给 channel_block3.go 的通道增加缓冲并观察输出有何不同 2 | package main 3 | 4 | import "fmt" 5 | import "time" 6 | 7 | func main() { 8 | c := make(chan int, 50) 9 | go func() { 10 | time.Sleep(15 * 1e9) 11 | x := <-c 12 | fmt.Println("received", x) 13 | }() 14 | fmt.Println("sending", 10) 15 | c <- 10 16 | fmt.Println("sent", 10) 17 | } 18 | 19 | /* Output: 20 | sending 10 21 | sent 10 // prints immediately 22 | no further output, because main() then stops 23 | */ 24 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/examples/chapter_14/channel_idiom.go: -------------------------------------------------------------------------------- 1 | // 通道工厂模式 不将通道作为参数传递给协程,而用函数来生成一个通道并返回(工厂角色);函数内有个匿名函数被协程调用。 2 | // 通道工厂模式是指当我们需要创建大量的通道时,可以使用通道工厂模式来简化代码。 3 | // 通道工厂模式的实现原理是:将通道的创建和通道的使用分离,将通道的创建封装到一个函数中,通过调用该函数来创建通道,然后再将通道传递给需要使用通道的函数。 4 | // 通道工厂模式的代码如下所示。 5 | package main 6 | 7 | import ( 8 | "fmt" 9 | "time" 10 | ) 11 | 12 | func main() { 13 | stream := pump3() 14 | go suck3(stream) 15 | time.Sleep(1e9) 16 | } 17 | 18 | func pump3() chan int { 19 | ch := make(chan int) 20 | go func() { 21 | for i := 0; i < 10; i++ { 22 | ch <- i 23 | } 24 | }() 25 | return ch 26 | } 27 | 28 | func suck3(ch chan int) { 29 | for { 30 | fmt.Println(<-ch) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/examples/chapter_14/channel_idiom2.go: -------------------------------------------------------------------------------- 1 | // 给通道使用 for 循环 2 | package main 3 | 4 | import ( 5 | "fmt" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | suck4(pump4()) 11 | time.Sleep(1e9) 12 | } 13 | 14 | func pump4() chan int { 15 | ch := make(chan int) 16 | go func() { 17 | for i := 0; ; i++ { 18 | ch <- i 19 | } 20 | }() 21 | return ch 22 | } 23 | 24 | func suck4(ch chan int) { 25 | go func() { 26 | for v := range ch { 27 | fmt.Println(v) 28 | } 29 | }() 30 | } 31 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/examples/chapter_14/goroutine2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | ch := make(chan string) 10 | 11 | go sendData(ch) 12 | go getData(ch) 13 | 14 | time.Sleep(1e9) 15 | } 16 | 17 | func sendData(ch chan string) { 18 | ch <- "Washington" 19 | ch <- "Tripoli" 20 | ch <- "London" 21 | ch <- "Beijing" 22 | ch <- "Tokyo" 23 | } 24 | 25 | func getData(ch chan string) { 26 | var input string 27 | // time.Sleep(2e9) 28 | for { 29 | input = <-ch 30 | fmt.Printf("%s ", input) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/examples/chapter_14/goroutine_select.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | ch1 := make(chan int) 10 | ch2 := make(chan int) 11 | 12 | go pump1(ch1) 13 | go pump5(ch2) 14 | go suck5(ch1, ch2) 15 | 16 | time.Sleep(1e9) 17 | } 18 | 19 | func pump1(ch chan int) { 20 | for i := 0; ; i++ { 21 | ch <- i * 2 22 | } 23 | } 24 | 25 | func pump5(ch chan int) { 26 | for i := 0; ; i++ { 27 | ch <- i + 5 28 | } 29 | } 30 | 31 | func suck5(ch1, ch2 chan int) { 32 | for { 33 | select { 34 | case v := <-ch1: 35 | fmt.Printf("Received on channel 1: %d\n", v) 36 | case v := <-ch2: 37 | fmt.Printf("Received on channel 2: %d\n", v) 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/examples/chapter_14/gosum.go: -------------------------------------------------------------------------------- 1 | // gosum.go 2 | package main 3 | 4 | import ( 5 | "fmt" 6 | ) 7 | 8 | func sum(x, y int, c chan int) { 9 | c <- x + y 10 | } 11 | 12 | func main() { 13 | c := make(chan int) 14 | go sum(12, 13, c) 15 | fmt.Println(<-c) // 25 16 | } 17 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/examples/chapter_14/lazy_evaluation.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var resume chan int 8 | 9 | func integers() chan int { 10 | yield := make(chan int) 11 | count := 0 12 | go func() { 13 | for { 14 | yield <- count 15 | count++ 16 | } 17 | }() 18 | return yield 19 | } 20 | 21 | func generateInteger() int { 22 | return <-resume 23 | } 24 | 25 | func main() { 26 | resume = integers() 27 | fmt.Println(generateInteger()) //=> 0 28 | fmt.Println(generateInteger()) //=> 1 29 | fmt.Println(generateInteger()) //=> 2 30 | } 31 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/examples/chapter_14/producer_consumer.go: -------------------------------------------------------------------------------- 1 | // goroutines2.go 2 | package main 3 | 4 | import "fmt" 5 | 6 | // integer producer: 7 | func numGen(start, count int, out chan<- int) { 8 | for i := 0; i < count; i++ { 9 | out <- start 10 | start = start + count 11 | } 12 | close(out) 13 | } 14 | 15 | // integer consumer: 16 | func numEchoRange(in <-chan int, done chan<- bool) { 17 | for num := range in { 18 | fmt.Printf("%d\n", num) 19 | } 20 | done <- true 21 | } 22 | 23 | func main() { 24 | numChan := make(chan int) 25 | done := make(chan bool) 26 | go numGen(0, 10, numChan) 27 | go numEchoRange(numChan, done) 28 | 29 | <-done 30 | } 31 | 32 | /* Output: 33 | 0 34 | 10 35 | 20 36 | 30 37 | 40 38 | 50 39 | 60 40 | 70 41 | 80 42 | 90 43 | */ 44 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/exercise/练习14-11/练习14.11.md: -------------------------------------------------------------------------------- 1 | 练习 14.11: [concurrent_pi.go](exercises/chapter_14/concurrent_pi.go) / [concurrent_pi2.go](exercises/chapter_14/concurrent_pi2.go) 2 | 3 | 使用以下序列在协程中计算 pi:开启一个协程来计算公式中的每一项并将结果放入通道,`main()` 函数收集并累加结果,打印出 pi 的近似值。 4 | 5 | ![](images/14.4_piseries.png?raw=true) 6 | 7 | 计算执行时间(参见第 [6.11](6.11.md) 节) 8 | 9 | 再次声明这只是为了一边练习协程的概念一边找点乐子。 10 | 11 | 如果你需要的话可使用 `math.pi` 中的 `Pi`;而且不使用协程会运算的更快。一个急速版本:使用 `GOMAXPROCS`,开启和 `GOMAXPROCS` 同样多个协程。 -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/exercise/练习14-12/练习14.12.md: -------------------------------------------------------------------------------- 1 | 练习14.12:[general_lazy_evaluation2.go](exercises/chapter_14/general_lazy_evalution2.go) 2 | 通过使用 14.12 中工厂函数生成前 10 个斐波那契数 3 | 4 | 提示:因为斐波那契数增长很迅速,使用 `uint64` 类型。 5 | 注:这种计算通常被定义为递归函数,但是在没有尾递归的语言中,例如 go 语言,这可能会导致栈溢出,但随着 go 语言中堆栈可扩展的优化,这个问题就不那么严重。这里的诀窍是使用了惰性求值。gccgo 编译器在某些情况下会实现尾递归。 6 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/exercise/练习14-7/a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func tel(ch chan int) { 6 | for i := 0; i < 15; i++ { 7 | ch <- i // 发送数字到通道 8 | } 9 | close(ch) // 关闭通道,这很重要,否则 main 函数中的 for 循环会永远阻塞等待 10 | } 11 | 12 | func main() { 13 | // 使用 Go 协程和通道 14 | ch := make(chan int) // 创建一个整数通道 15 | done := make(chan bool) 16 | 17 | go tel(ch) // 在一个新的 Go 协程中启动 tel 函数 18 | 19 | // 从通道中获取并打印数字 20 | //for i := range ch { 21 | // fmt.Printf("The counter is at %d\n", i) 22 | //} // solution 1 23 | go cus(ch, done) // solution 2 24 | <-done 25 | } 26 | 27 | func cus(ch chan int, done chan bool) { 28 | // 匿名函数 29 | go func() { 30 | for i := range ch { 31 | fmt.Printf("The counter is at %d\n", i) 32 | } 33 | done <- true 34 | }() 35 | } 36 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/exercise/练习14-7/c.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func tel2(ch chan int, done chan struct{}) { 6 | for i := 0; i < 15; i++ { 7 | ch <- i // 发送数字到通道 8 | } 9 | close(ch) // 关闭数据通道 10 | done <- struct{}{} // 发送完成信号 11 | } 12 | 13 | func main() { 14 | ch := make(chan int) // 创建一个整数通道 15 | done := make(chan struct{}) // 创建一个结束信号通道 16 | 17 | go tel2(ch, done) // 在一个新的 Go 协程中启动 tel 函数 18 | 19 | // 使用 select 语句来从 ch 和 done 中接收数据 20 | for { 21 | select { 22 | case i, ok := <-ch: 23 | if ok { 24 | fmt.Printf("The counter is at %d\n", i) 25 | } 26 | case <-done: 27 | fmt.Println("Finished receiving!") 28 | return 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/exercise/练习14-8/fibonacci2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | pos := 4 7 | result, pos := fibonacci2(pos) 8 | fmt.Printf("the %d-th fibonacci number is: %d\n", pos, result) 9 | pos = 10 10 | result, pos = fibonacci2(pos) 11 | fmt.Printf("the %d-th fibonacci number is: %d\n", pos, result) 12 | } 13 | 14 | func fibonacci2(n int) (val, pos int) { 15 | if n <= 1 { 16 | val = 1 17 | } else { 18 | v1, _ := fibonacci2(n - 1) 19 | v2, _ := fibonacci2(n - 2) 20 | val = v1 + v2 21 | } 22 | pos = n 23 | return 24 | } 25 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/exercise/练习14-8/gofibonacci.go: -------------------------------------------------------------------------------- 1 | // Q26_fibonacci_go.go 2 | package main 3 | 4 | import ( 5 | "fmt" 6 | "os" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | term := 25 12 | i := 0 13 | c := make(chan int) 14 | start := time.Now() 15 | 16 | go fibnterms(term, c) 17 | for { 18 | if result, ok := <-c; ok { 19 | fmt.Printf("fibonacci(%d) is: %d\n", i, result) 20 | i++ 21 | } else { 22 | end := time.Now() 23 | delta := end.Sub(start) 24 | fmt.Printf("longCalculation took this amount of time: %s\n", delta) 25 | os.Exit(0) // os.Exit(0) 用于确保主函数(main)在所有斐波那契数列的项都计算和打印出来后立即结束 0 通常表示程序正常退出,而非零的值表示有错误或异常情况。 26 | } 27 | } 28 | } 29 | 30 | func fibnterms(term int, c chan int) { 31 | for i := 0; i <= term; i++ { 32 | c <- fibonacci(i) 33 | } 34 | close(c) 35 | } 36 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/exercise/练习14-8/gofibonacci2.go: -------------------------------------------------------------------------------- 1 | // gofibonacci2.go 2 | package main 3 | 4 | import ( 5 | "fmt" 6 | ) 7 | 8 | func fibonacci3(n int, c chan int) { 9 | x, y := 1, 1 10 | for i := 0; i < n; i++ { 11 | c <- x 12 | x, y = y, x+y 13 | } 14 | close(c) 15 | } 16 | 17 | func main() { 18 | c := make(chan int, 10) 19 | go fibonacci3(cap(c), c) 20 | for i := range c { 21 | fmt.Println(i) 22 | } 23 | } 24 | 25 | /* Output: 26 | 1 27 | 1 28 | 2 29 | 3 30 | 5 31 | 8 32 | 13 33 | 21 34 | 34 35 | 55 36 | */ 37 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/exercise/练习14-8/gofibonacci3.go: -------------------------------------------------------------------------------- 1 | // courtesy of: http://sdh33b.blogspot.com/2009/12/fibonacci-in-go.html 2 | package main 3 | 4 | import ( 5 | "fmt" 6 | "time" 7 | ) 8 | 9 | func dup3(in <-chan int) (<-chan int, <-chan int, <-chan int) { 10 | a, b, c := make(chan int, 2), make(chan int, 2), make(chan int, 2) 11 | go func() { 12 | for { 13 | x := <-in 14 | a <- x 15 | b <- x 16 | c <- x 17 | } 18 | }() 19 | return a, b, c 20 | } 21 | 22 | func fib() <-chan int { 23 | x := make(chan int, 2) 24 | a, b, out := dup3(x) 25 | go func() { 26 | x <- 0 27 | x <- 1 28 | <-a 29 | for { 30 | x <- <-a + <-b 31 | } 32 | }() 33 | <-out 34 | return out 35 | } 36 | 37 | func main() { 38 | start := time.Now() 39 | x := fib() 40 | for i := 0; i < 10; i++ { 41 | fmt.Println(<-x) 42 | } 43 | end := time.Now() 44 | delta := end.Sub(start) 45 | fmt.Printf("longCalculation took this amount of time: %s\n", delta) 46 | } 47 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/exercise/练习14-8/gofibonacci_select.go: -------------------------------------------------------------------------------- 1 | // gofibonacci_select.go 2 | package main 3 | 4 | import "fmt" 5 | 6 | func goFibonacciSelect(c, quit chan int) { 7 | x, y := 1, 1 8 | for { 9 | select { 10 | case c <- x: 11 | x, y = y, x+y 12 | case <-quit: 13 | fmt.Println("quit") 14 | return 15 | } 16 | } 17 | } 18 | 19 | func main() { 20 | c := make(chan int) 21 | quit := make(chan int) 22 | go func() { 23 | for i := 0; i < 10; i++ { 24 | fmt.Println(<-c) 25 | } 26 | quit <- 0 27 | }() 28 | goFibonacciSelect(c, quit) 29 | } 30 | 31 | /* Output: 32 | 1 33 | 1 34 | 2 35 | 3 36 | 5 37 | 8 38 | 13 39 | 21 40 | 34 41 | 55 42 | quit 43 | */ 44 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/exercise/练习14-8/练习14.8.md: -------------------------------------------------------------------------------- 1 | 练习 14.8: 2 | 3 | 从示例 [6.13 fibonacci.go](examples/chapter_6/fibonacci.go) 的斐波那契程序开始,制定解决方案,使斐波那契周期计算独立到协程中,并可以把结果发送给通道。 4 | 5 | 结束的时候关闭通道。`main()` 函数读取通道并打印结果:[goFibonacci.go](exercises/chapter_14/gofibonacci.go) 6 | 7 | 使用练习 [6.9 fibonacci2.go](exercises/chapter_6/fibonacci2.go) 中的算法写一个更短的 [gofibonacci2.go](exercises/chapter_14/gofibonacci2.go) 8 | 9 | 使用 `select` 语句来写,并让通道退出 ([gofibonacci_select.go](exercises/chapter_14/gofibonacci_select.go)) 10 | 11 | 注意:当给结果计时并和 6.13 对比时,我们发现使用通道通信的性能开销有轻微削减;这个例子中的算法使用协程并非性能最好的选择;但是 [gofibonacci3](exercises/chapter_14/gofibonacci3.go) 方案使用了 2 个协程带来了 3 倍的提速。 12 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/exercise/练习14-9/random_bitgen.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | c := make(chan int) 9 | // consumer: 10 | go func() { 11 | for { 12 | fmt.Print(<-c, " ") 13 | } 14 | }() 15 | // producer: 16 | for { 17 | select { 18 | case c <- 0: 19 | case c <- 1: 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/exercise/练习14-9/练习14.9.md: -------------------------------------------------------------------------------- 1 | 练习 14.9: 2 | 3 | 做一个随机位生成器,程序可以提供无限的随机 0 或者 1 的序列:[random_bitgen.go](exercises/chapter_14/random_bitgen.go) 4 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/Go入门指南/第14章协程与通道/exercise/练习4-10/练习4.10.md: -------------------------------------------------------------------------------- 1 | 练习 14.10:[polar_to_cartesian.go](exercises/chapter_14/polar_to_cartesian.go) 2 | 3 | (这是一种综合练习,使用到第 4、9、11 章和本章的内容。)写一个可交互的控制台程序,要求用户输入二位平面极坐标上的点(半径和角度(度))。计算对应的笛卡尔坐标系的点的 `x` 和 `y` 并输出。使用极坐标和笛卡尔坐标的结构体。 4 | 5 | 使用通道和协程: 6 | 7 | - `channel1` 用来接收极坐标 8 | - `channel2` 用来接收笛卡尔坐标 9 | 10 | 转换过程需要在协程中进行,从 `channel1` 中读取然后发送到 `channel2`。实际上做这种计算不提倡使用协程和通道,但是如果运算量很大很耗时,这种方案设计就非常合适了。 -------------------------------------------------------------------------------- /golang/go-study/GO文档/幼麟实验室/README.md: -------------------------------------------------------------------------------- 1 | # 幼麟实验室 2 | 3 | **哔站:** [幼麟实验室的个人空间-幼麟实验室个人主页-哔哩哔哩视频](https://space.bilibili.com/567195437) 4 | 5 | **知乎:** [幼麟实验室 - 知乎](https://www.zhihu.com/people/kylin-lab) 6 | 7 | **微信:** [【幼麟实验室】图文目录](https://mp.weixin.qq.com/s/-hMMtur1AmkkLpsZYi6e3g) 8 | 9 | ------ 10 | 11 | 1. [【Golang】字符咋存?utf8咋编码?string啥结构?_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV1ff4y1m72A/?spm_id_from=333.999.0.0&vd_source=8321160752e4f07c473e11ebc0dd0a28) 12 | 2. -------------------------------------------------------------------------------- /golang/go-study/GO文档/码农桃花源/array-and-slice/array-and-slice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | slice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 7 | s1 := slice[2:5] 8 | s2 := s1[2:6:7] 9 | 10 | s2 = append(s2, 100) 11 | s2 = append(s2, 200) 12 | 13 | s1[2] = 20 14 | 15 | fmt.Println(s1) 16 | fmt.Println(s2) 17 | fmt.Println(slice) 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/码农桃花源/array-and-slice/切片作为函数参数.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | s := []int{1, 1, 1} 7 | f(s) 8 | fmt.Println(s) 9 | } 10 | 11 | func f(s []int) { 12 | // i只是一个副本,不能改变s中元素的值 13 | /*for _, i := range s { 14 | i++ 15 | } 16 | */ 17 | 18 | for i := range s { 19 | s[i] += 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /golang/go-study/GO文档/码农桃花源/array-and-slice/切片作为函数参数2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func myAppend(s []int) []int { 6 | // 这里 s 虽然改变了,但并不会影响外层函数的 s 7 | s = append(s, 100) 8 | return s 9 | } 10 | 11 | func myAppendPtr(s *[]int) { 12 | // 会改变外层 s 本身 13 | *s = append(*s, 100) 14 | return 15 | } 16 | 17 | func main() { 18 | s := []int{1, 1, 1} 19 | newS := myAppend(s) 20 | 21 | fmt.Println(s) 22 | fmt.Println(newS) 23 | 24 | s = newS 25 | 26 | myAppendPtr(&s) 27 | fmt.Println(s) 28 | } 29 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/Gin/Bind Header.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | type testHeader struct { 11 | Rate int `header:"Rate"` 12 | Domain string `header:"Domain"` 13 | } 14 | 15 | func main() { 16 | r := gin.Default() 17 | r.GET("/", func(c *gin.Context) { 18 | h := testHeader{} 19 | 20 | if err := c.ShouldBindHeader(&h); err != nil { 21 | c.JSON(http.StatusOK, err) 22 | } 23 | 24 | fmt.Printf("%#v\n", h) 25 | c.JSON(http.StatusOK, gin.H{"Rate": h.Rate, "Domain": h.Domain}) 26 | }) 27 | 28 | r.Run() 29 | 30 | // client 31 | // curl -H "rate:300" -H "domain:music" 127.0.0.1:8080/ 32 | // output 33 | // {"Domain":"music","Rate":300} 34 | } 35 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/Gin/ip/获取ip地址.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "net/http" 6 | ) 7 | 8 | func main() { 9 | r := gin.Default() 10 | 11 | r.GET("/getip", func(c *gin.Context) { 12 | ip := c.ClientIP() 13 | c.JSON(http.StatusOK, gin.H{"ip": ip}) 14 | }) 15 | 16 | r.Run(":8080") 17 | } 18 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/Gin/stream/流式返回.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/gin-gonic/gin" 6 | "io" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | r := gin.Default() 12 | 13 | r.GET("/stream", func(c *gin.Context) { 14 | // 设置响应头,指定内容类型为text/plain 15 | c.Header("Content-Type", "text/plain") 16 | c.Header("Transfer-Encoding", "chunked") 17 | 18 | // 创建一个通道用于模拟流式数据 19 | dataStream := make(chan string) 20 | 21 | // 启动goroutine,模拟生成流式数据 22 | go func() { 23 | defer close(dataStream) 24 | for i := 0; i < 10; i++ { 25 | time.Sleep(1 * time.Second) 26 | dataStream <- fmt.Sprintf("Data %d\n", i) 27 | } 28 | }() 29 | 30 | // 将流式数据写入响应主体 31 | for data := range dataStream { 32 | _, _ = io.WriteString(c.Writer, data) 33 | c.Writer.Flush() 34 | } 35 | }) 36 | 37 | r.Run(":8080") 38 | } 39 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/Math/myMath.go: -------------------------------------------------------------------------------- 1 | package mathClass 2 | func Add(x,y int)int{ 3 | return x+y 4 | } 5 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/Math/myMath1.go: -------------------------------------------------------------------------------- 1 | package mathClass 2 | func Sub(x,y int)int{ 3 | return x-y 4 | } 5 | 6 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/Time/getDayTimestamps.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func GetDayTimestamps(dateStr string) (int64, int64, error) { 9 | layout := "2006-01-02" 10 | t, err := time.Parse(layout, dateStr) 11 | if err != nil { 12 | return 0, 0, err 13 | } 14 | 15 | startTimestamp := t.UnixNano() / 1e6 16 | endTimestamp := startTimestamp + 24*60*60*1000 - 1 17 | 18 | return startTimestamp, endTimestamp, nil 19 | } 20 | 21 | func main() { 22 | date := "2024-05-01" 23 | startTimestamp, endTimestamp, err := GetDayTimestamps(date) 24 | if err != nil { 25 | fmt.Println("Error:", err) 26 | return 27 | } 28 | 29 | fmt.Println("Start Timestamp:", startTimestamp) 30 | fmt.Println("End Timestamp:", endTimestamp) 31 | } 32 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/Time/getMonthRange.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func getMonthRange(dateStr string) (string, string) { 9 | // 解析日期字符串 10 | date, err := time.Parse("2006-01-02", dateStr) 11 | if err != nil { 12 | fmt.Println("Error parsing date:", err) 13 | return "", "" 14 | } 15 | 16 | // 获取当月第一天 17 | firstDay := time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, date.Location()) 18 | 19 | // 获取当月最后一天 20 | lastDay := firstDay.AddDate(0, 1, -1) 21 | 22 | return firstDay.Format("2006-01-02"), lastDay.Format("2006-01-02") 23 | } 24 | 25 | func main() { 26 | dateStr := "2023-02-11" 27 | firstDay, lastDay := getMonthRange(dateStr) 28 | fmt.Println("当月第一天:", firstDay) 29 | fmt.Println("当月最后一天:", lastDay) 30 | } 31 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/Time/test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | //loa := time.FixedZone("Asia/Shanghai", 8*60*60) 10 | //startDate, err := time.ParseInLocation("2006-01-02 15:04:05", "2023-10-31 01:02:36", loa) 11 | 12 | a := time.Duration(int64(1698684471)+7776000-time.Now().Unix()) * time.Second 13 | fmt.Println(a) 14 | if a < 0 { 15 | fmt.Println("小于0") 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/Time/test2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/mao888/mao-gutils/constants" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | isHour := true 11 | data := "2023-11-06 18:00:00" 12 | //data := "2023-11-06" 13 | loa := time.FixedZone("Asia/Shanghai", 8*60*60) 14 | var sdate, edate int64 15 | if isHour { 16 | date, err := time.ParseInLocation(constants.TimeYMDH, data, loa) 17 | if err != nil { 18 | fmt.Println("err:", err) 19 | return 20 | } 21 | sdate = date.Unix() 22 | edate = date.Add(time.Minute * 60).Unix() // sdate: 1699264800 edate: 1699268400 23 | } else { 24 | date, err := time.ParseInLocation(constants.TimeYMD, data, loa) 25 | if err != nil { 26 | fmt.Println("err:", err) 27 | return 28 | } 29 | sdate = date.Unix() 30 | edate = date.Add(time.Hour * 24).Unix() // sdate: 1699200000 edate: 1699286400 31 | } 32 | fmt.Println("sdate:", sdate, "edate:", edate) 33 | } 34 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/Time/test3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func main() { 9 | dateString := "2023-11-09" 10 | 11 | // 使用空格分割字符串 12 | parts := strings.Split(dateString, " ") 13 | 14 | // 提取日期部分 15 | if len(parts) >= 1 { 16 | day := parts[0] 17 | fmt.Println("截取到天:", day) 18 | } else { 19 | fmt.Println("日期字符串格式不正确") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/Time/time.now.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | var now time.Time 10 | now = time.Now() 11 | fmt.Println(now) 12 | 13 | // var secs time.Time 14 | secs := now.Unix() 15 | fmt.Println(secs) 16 | } 17 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/Time/utc.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | fmt.Println(time.Now().UTC().Format("2006-01-02 15:04:05")) 10 | sub := time.Now().UTC().Sub(time.Now()) 11 | 12 | fmt.Println(sub) 13 | } 14 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/Time/时间戳转换成UTC时间.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | chuo := int64(1688589582) 10 | //bendi := time.Unix(int64(chuo), 0).Format("2006-01-02 15:04:05") 11 | //lastLoginAt, err := time.Parse("2006-01-02 15:04:05", bendi) 12 | //if err != nil { 13 | // fmt.Println(err) 14 | // return 15 | //} 16 | //fmt.Println(lastLoginAt.String()) 17 | 18 | // 将时间戳转换为北京时间 19 | beijng := time.Unix(chuo, 0).In(time.FixedZone("CST", 8*3600)).Format("2006-01-02 15:04:05") 20 | 21 | // 将时间戳转换为UTC时间 22 | utc := time.Unix(chuo, 0).UTC().Format("2006-01-02 15:04:05") 23 | 24 | fmt.Println("beijng", beijng) 25 | fmt.Println("utc", utc) 26 | } 27 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/byte和rune.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: edy 3 | @since: 2022/8/11 4 | @desc: //TODO 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | //https://blog.csdn.net/qq_42410605/article/details/114818366 11 | 12 | func main() { 13 | s := "asc" 14 | fmt.Printf("%T ", s[0]) 15 | fmt.Println() 16 | for i := range s { 17 | fmt.Printf("%T ", s[i]) 18 | } 19 | fmt.Println() 20 | for _, i2 := range s { 21 | fmt.Printf("%T ", i2) 22 | } 23 | fmt.Println() 24 | for i := 0; i < len(s); i++ { 25 | fmt.Printf("%T ", s[i]) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/chan/多生产者场景下 channel 关闭的问题.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | // 多生产者场景下 channel 关闭的问题 9 | func main() { 10 | ch := make(chan int) 11 | workN := 5 // 生产者数 12 | var wg sync.WaitGroup 13 | wg.Add(workN) 14 | 15 | // 1、启动多个 Goroutine,通过闭包将 wg 传入,并且在完成任务后调用 wg.Done()。 16 | for i := 0; i < workN; i++ { 17 | go func(i int) { 18 | n := i * i 19 | ch <- n 20 | wg.Done() 21 | }(i) 22 | } 23 | 24 | // close channel 启动另一个 Goroutine 用来关闭 channel,这个 Goroutine 会阻塞,直到所有的任务完成,最后关闭 channel 25 | go func() { 26 | wg.Wait() 27 | close(ch) 28 | }() 29 | 30 | // 3、不停地从 channel 中读取数据,直到 channel 关闭,然后结束程序 31 | for i := range ch { 32 | fmt.Println(i) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/context/Value.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | ) 7 | 8 | type keyType string 9 | 10 | // Value(key interface{}) interface{} 是 context.Context 接口中的一个方法,用于在 context.Context 中存储和检索键值对信息。 11 | // 这个方法允许你在 context.Context 中关联任意键(key)和值(value),以便将一些请求特定的数据传递给相关的函数和 goroutine。 12 | 13 | func main() { 14 | // 创建一个父 Context 15 | parent := context.Background() 16 | 17 | // 在父 Context 中使用 context.WithValue 存储键值对信息 18 | key := keyType("user") 19 | value := "john_doe" 20 | ctx := context.WithValue(parent, key, value) 21 | 22 | // 在子函数中检索存储的值 23 | retrieveValue(ctx, key) 24 | } 25 | 26 | func retrieveValue(ctx context.Context, key keyType) { 27 | // 使用 context.Value 方法来检索存储的值 28 | if value, ok := ctx.Value(key).(string); ok { 29 | fmt.Printf("Value for key %s: %s\n", key, value) 30 | } else { 31 | fmt.Printf("Key %s not found in the context\n", key) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/defer/test1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func f1() int { 6 | x := 5 7 | defer func() { 8 | x++ 9 | }() 10 | return x 11 | } 12 | 13 | func f2() (x int) { 14 | defer func() { 15 | x++ 16 | }() 17 | return 5 18 | } 19 | 20 | func f3() (y int) { 21 | x := 5 22 | defer func() { 23 | x++ 24 | }() 25 | return x 26 | } 27 | func f4() (x int) { 28 | defer func(x int) { 29 | x++ 30 | }(x) 31 | return 5 32 | } 33 | func main() { 34 | fmt.Println(f1()) // 5 35 | fmt.Println(f2()) // 6 36 | fmt.Println(f3()) // 5 37 | fmt.Println(f4()) // 5 38 | } 39 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/for/for-chan.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | c := make(chan string, 3) 7 | c <- "1023" 8 | c <- "1024" 9 | c <- "1025" 10 | close(c) // 关闭通道 11 | 12 | for i := 0; i < len(c); i++ { 13 | v, ok := <-c 14 | if !ok { 15 | fmt.Println("通道已关闭") 16 | } else { 17 | //for循环value: 1023 18 | //for循环value: 1024 19 | fmt.Println("for循环value: ", v) 20 | } 21 | } 22 | 23 | //for msg := range c { 24 | // //range循环value: 1023 25 | // //range循环value: 1024 26 | // //range循环value: 1025 27 | // fmt.Println("range循环value: ", msg) 28 | //} 29 | 30 | //for { 31 | // v, ok := <-c 32 | // if !ok { 33 | // fmt.Println("通道已关闭") 34 | // break 35 | // } 36 | // //for-select循环value: 1023 37 | // //for-select循环value: 1024 38 | // //for-select循环value: 1025 39 | // fmt.Println("for-select循环value: ", v) 40 | //} 41 | } 42 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/for/range-slice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | words := []string{"Go", "语言", "高性能", "编程"} 7 | 8 | for i, s := range words { 9 | words = append(words, "test") 10 | fmt.Println(i, s) 11 | } 12 | //0 Go 13 | //1 语言 14 | //2 高性能 15 | //3 编程 16 | 17 | //for i := 0; i < len(words); i++ { 18 | // words = append(words, "test") 19 | // fmt.Println(i, words[i]) 20 | // if len(words) >= 10 { 21 | // break 22 | // } 23 | //} 24 | //0 Go 25 | //1 语言 26 | //2 高性能 27 | //3 编程 28 | //4 test 29 | //5 test 30 | 31 | } 32 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/interface/类型断言.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | gutil "github.com/mao888/mao-gutils/interfaces" 6 | ) 7 | 8 | func main() { 9 | var name interface{} = "aaa" 10 | fmt.Println(gutil.JudgeType(name)) 11 | fmt.Println(gutil.JudgeTypeByReflect(name)) 12 | } 13 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/map/test1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | type Map map[string][]int 7 | m := make(Map) 8 | s := []int{1, 2} 9 | s = append(s, 3) 10 | fmt.Printf("%v\n", s) // [1 2 3] 11 | m["q1mi"] = s 12 | fmt.Println(m) // map[q1mi:[1 2 3]] 13 | 14 | //m["q1mi"] = make([]int, len(s)) 15 | //copy(m["q1mi"], s) 16 | 17 | s = append(s[:1], s[2:]...) 18 | fmt.Printf("%v\n", s) // [1 3] 19 | fmt.Printf("%v\n", m["q1mi"]) // [1 3 3] 20 | 21 | s = append(s, 4, 5, 6) 22 | fmt.Printf("%v\n", s) // [1 3 4 5 6] 23 | fmt.Printf("%v\n", m["q1mi"]) // [1 3 3] 24 | } 25 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/package/strings.TrimSpace.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | /** 9 | []byte中每一个byte的默认值是0,而空格的值是32;按照实验的结果,TrimSpace可以剪掉byte为32的(空格),但不能剪掉byte为0的 10 | 返回将s前后端所有空白(unicode.IsSpace指定)都去掉的字符串。 11 | */ 12 | 13 | func testa() { 14 | buf := make([]byte, 10) 15 | buf[0] = ' ' 16 | buf[1] = ' ' 17 | buf[2] = 'b' 18 | buf[3] = 'b' 19 | buf[4] = ' ' 20 | //buf[5] = ' ' 21 | //buf[6] = 'b' 22 | // buf[7] = ' ' 23 | // buf[8] = ' ' 24 | buf[9] = ' ' 25 | fmt.Println(buf) 26 | fmt.Printf("%s\n", strings.TrimSpace(string(buf))) 27 | fmt.Printf("%d\n", len(strings.TrimSpace(string(buf)))) 28 | } 29 | 30 | func main() { 31 | testa() 32 | 33 | //testb() 34 | } 35 | 36 | func testb() { 37 | s := "Hello world hello world" 38 | ret := strings.TrimSpace(s) 39 | fmt.Println(ret) 40 | fmt.Println(len(ret)) 41 | } 42 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/strings/join.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func main() { 9 | status := []string{"3", "2", "1"} 10 | 11 | var statusStr []string 12 | for _, statu := range status { 13 | statusStr = append(statusStr, fmt.Sprintf("'%s'", statu)) 14 | } 15 | 16 | fmt.Println(strings.Join(status, ",")) 17 | 18 | fmt.Println(strings.Join(statusStr, ",")) 19 | } 20 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/strings/lenString.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "unicode/utf8" 7 | ) 8 | 9 | func main() { 10 | str := " 测试第一条ad s " 11 | charCount := utf8.RuneCountInString(str) // 用于获取字符串的字符数,而不是字节数 12 | fmt.Println("len str", len(str)) // 21 = 1 + 15 + 2 + 1 + 1 + 1 13 | fmt.Printf("字符串 \"%s\" 的字符数为 %d\n", str, charCount) // 11 14 | trimSpaceStr := strings.TrimSpace(str) // 去除字符串首尾的空白字符 15 | 16 | fmt.Println("len trimSpaceStr", len(trimSpaceStr)) // 15 + 4 = 19 17 | fmt.Printf("字符串 \"%s\" 的字符数为 %d\n", trimSpaceStr, utf8.RuneCountInString(trimSpaceStr)) // 9 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/strings/strconv-Atoi.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "strconv" 4 | 5 | func main() { 6 | eventParam, err := strconv.Atoi("2.1") 7 | if err != nil { 8 | panic(err) 9 | } 10 | println(eventParam) 11 | } 12 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/strings/trimPrefix.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func main() { 9 | var str string = "10110:[100186,100187]:[a,w,s,d]" 10 | str = strings.TrimPrefix(str, "[") 11 | str = strings.TrimSuffix(str, "]") 12 | fmt.Println(str) 13 | } 14 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/struct.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/6/16 4 | @note: 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | type name struct { 11 | name int 12 | kk func(int2 int) int 13 | } 14 | 15 | func (a *name) ff() { 16 | a.name = 1 17 | a.kk = func(int2 int) int { 18 | return 1 19 | } 20 | 21 | fmt.Printf("%d", a.kk(1)) 22 | 23 | } 24 | 25 | func main() { 26 | a := name{} 27 | a.ff() 28 | } 29 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | type Person struct { 10 | Name string 11 | } 12 | 13 | func (p *Person) SetName() { 14 | p.Name = "1" 15 | } 16 | 17 | func main() { 18 | //fmt.Println(mathClass.Add(2, 3)) 19 | //fmt.Println(mathClass.Sub(3, 2)) 20 | //p := Person{Name: "33"} 21 | //p.SetName() 22 | //fmt.Println(p.Name) 23 | //for i := 0; i < 10; i++ { 24 | // wg.Add(1) 25 | // go func(i int) { 26 | // defer wg.Done() 27 | // fmt.Println(i) 28 | // time.Sleep(time.Second) 29 | // }(i) 30 | //} 31 | ch := make(chan int) 32 | var w sync.WaitGroup 33 | w.Add(1) 34 | go func() { 35 | fmt.Println("11111") 36 | <-ch 37 | fmt.Println("3333333") 38 | w.Done() 39 | }() 40 | time.Sleep(time.Second * 2) 41 | ch <- 1 42 | w.Wait() 43 | } 44 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/test/Println.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | //n, e := fmt.Println() 5 | 6 | } 7 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/test/expand.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | gutil "github.com/mao888/mao-gutils/os" 6 | ) 7 | 8 | func main() { 9 | // 测试案例: 将template中 $ 后的字符串自定义替换 10 | template := "chartid=$user_id & prop=$prop" 11 | 12 | // 声明map 13 | var mapStr map[string]string 14 | //使用make函数创建一个非nil的map,nil map不能赋值 15 | mapStr = make(map[string]string) 16 | //给已声明的map赋值 17 | mapStr["user_id"] = "1,2,3" 18 | mapStr["prop"] = "huchao" 19 | 20 | //res := os.Expand(template, func(s string) string { 21 | // return mapStr[s] 22 | //}) 23 | 24 | res := gutil.ExpandByMap(template, mapStr) 25 | res2 := gutil.GetComposedTemplateListExpandByMap(template, true, mapStr) 26 | fmt.Println(res) 27 | fmt.Println(res2) 28 | } 29 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/函数/go函数定义.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/3/14 4 | @note: 5 | **/ 6 | package main 7 | 8 | func main() { 9 | add([]int{1,2}...) 10 | } 11 | 12 | func add(args ...int) int { 13 | sum := 0 14 | for _,arg := range args{ 15 | sum += arg 16 | } 17 | return sum 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/函数/go闭包.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:huchao 3 | @data:2022/2/11 4 | @note: 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func calc(base int) (func(int) int, func(int) int) { 11 | add := func(i int) int { base += i 12 | return base } 13 | sub := func(i int) int { base -= i 14 | return base } 15 | return add, sub 16 | } 17 | func main() { 18 | f1,f2 := calc(10) 19 | fmt.Println(f1(1),f2(2)) // 11 9 20 | fmt.Println(f1(3),f2(4)) // 12 8 21 | fmt.Println(f1(5),f2(6)) // 13 7 22 | fmt.Println(f1(7),f2(8)) // 14 6 23 | } 24 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/并发/sync-map.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | func main() { 9 | var m sync.Map 10 | // 1. 写入 11 | m.Store("qcrao", 18) 12 | m.Store("qcrao", 20) 13 | 14 | // 2. 读取 15 | age, _ := m.Load("qcrao") 16 | fmt.Println(age.(int)) 17 | 18 | // 3. 遍历 19 | m.Range(func(key, value interface{}) bool { 20 | name := key.(string) 21 | age := value.(int) 22 | fmt.Println(name, age) 23 | return true 24 | }) 25 | 26 | // 4. 删除 27 | m.Delete("qcrao") 28 | age, ok := m.Load("qcrao") 29 | fmt.Println(age, ok) 30 | 31 | // 5. 读取或写入 32 | m.LoadOrStore("stefno", 100) 33 | age, _ = m.Load("stefno") 34 | fmt.Println(age) 35 | } 36 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/数组与切片/Go 输出两个slice切片的差集.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | 4 | @author:Hasee 5 | @data:2022/11/25 6 | @note: 7 | 8 | * 9 | */ 10 | package main 11 | 12 | import ( 13 | "fmt" 14 | "github.com/mao888/mao-gutils/slice" 15 | ) 16 | 17 | func main() { 18 | leyangjun1 := []int{1, 3, 5, 6} 19 | leyangjun2 := []int{1, 3, 5} 20 | 21 | retDiff := DifferenceSet(leyangjun1, leyangjun2) 22 | s := slice.DifferenceSet(leyangjun1, leyangjun2) 23 | fmt.Println(retDiff) 24 | fmt.Println(s) 25 | } 26 | 27 | // DifferenceSet 返回两个slice切片的差集 28 | func DifferenceSet(a []int, b []int) []int { 29 | var c []int 30 | temp := map[int]struct{}{} 31 | 32 | for _, val := range b { 33 | if _, ok := temp[val]; !ok { 34 | temp[val] = struct{}{} 35 | } 36 | } 37 | 38 | for _, val := range a { 39 | if _, ok := temp[val]; !ok { 40 | c = append(c, val) 41 | } 42 | } 43 | 44 | return c 45 | } 46 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/数组与切片/go数组变链表.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type ListNode struct { 8 | Val int 9 | next *ListNode 10 | } 11 | 12 | func SliceToLinkList(nums []int, head *ListNode) *ListNode { 13 | node := head 14 | for _, num := range nums { 15 | temp := ListNode{Val: num} 16 | head.next = &temp 17 | head = &temp 18 | } 19 | return node.next 20 | } 21 | func main() { 22 | arr := []int{1, 2, 3, 4, 5, 6} 23 | node := new(ListNode) 24 | 25 | linkNode := SliceToLinkList(arr, node) 26 | for { 27 | if linkNode != nil { 28 | fmt.Println(linkNode.Val) 29 | linkNode = linkNode.next 30 | continue 31 | } 32 | break 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/数组与切片/去重.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Printf("去重之后: %v", removeRepByMap([]string{"a", "b", "c", "d", "a", "b", "c", "d"})) 7 | } 8 | 9 | // 切片去重 10 | func removeRepByMap(slc []string) []string { 11 | result := make([]string, 0, len(slc)) 12 | tempMap := make(map[string]struct{}, len(slc)) 13 | for _, e := range slc { 14 | l := len(tempMap) 15 | tempMap[e] = struct{}{} 16 | if len(tempMap) != l { // 不存在 17 | result = append(result, e) 18 | } 19 | } 20 | return result 21 | } 22 | -------------------------------------------------------------------------------- /golang/go-study/exercise/Go/数组与切片/数组.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/6/28 4 | @note: 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | var a1 = []int{5, 1, 4} 12 | var a2 = []int{3} 13 | for _, i2 := range a2 { 14 | a1 = append(a1, i2) 15 | } 16 | fmt.Println(a1) 17 | } 18 | -------------------------------------------------------------------------------- /golang/go-study/exercise/其他/gomodule.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author:Hasee 3 | @data:2022/7/14 4 | @note: 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "os" 11 | ) 12 | 13 | func main() { 14 | dir, _ := os.UserConfigDir() 15 | fmt.Println(dir) 16 | } 17 | -------------------------------------------------------------------------------- /golang/go-study/exercise/其他/浮点数格式化输出.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | // 浮点数 1.0 输出后保存小数位 9 | func main() { 10 | var f float64 = 1.0 11 | fmt.Println(f) // 1 12 | value := strconv.FormatFloat(f, 'f', 2, 64) 13 | fmt.Println(value) // 1.00 14 | } 15 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/channel/channel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // 未初始化的通道类型变量其默认零值是nil 6 | var ch1 chan int // 声明一个传递整型的通道 7 | var ch2 chan bool // 声明一个传递布尔型的通道 8 | var ch3 chan []int // 声明一个传递int切片的通道 9 | 10 | var ch4 = make(chan int) 11 | var ch5 = make(chan bool, 1) // 声明一个缓冲区大小为1的通道 12 | 13 | func main() { 14 | fmt.Println(ch1) // 15 | fmt.Println(ch2) // 16 | fmt.Println(ch3) // 17 | 18 | fmt.Println(ch4) // 0xc000064060 19 | fmt.Println(ch5) // 0xc000100000 20 | } 21 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/channel/exercise.go: -------------------------------------------------------------------------------- 1 | package main 2 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/channel/多返回值模式.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func f2(ch chan int) { 6 | for { 7 | v, ok := <-ch 8 | if !ok { 9 | fmt.Println("通道已关闭") 10 | break 11 | } 12 | fmt.Printf("v:%#v ok:%#v\n", v, ok) 13 | } 14 | } 15 | 16 | // for range接收值 17 | func f3(ch chan int) { 18 | for v := range ch { 19 | fmt.Println(v) 20 | } 21 | } 22 | 23 | func main() { 24 | 25 | ch := make(chan int, 2) 26 | ch <- 1 27 | ch <- 2 28 | close(ch) // 当向通道中发送完数据时,我们可以通过close函数来关闭通道 29 | f2(ch) 30 | } 31 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/channel/无缓冲channel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func recv(c chan int) { 6 | ret := <-c 7 | fmt.Println("接收成功", ret) 8 | } 9 | func main() { 10 | ch := make(chan int) 11 | go recv(ch) 12 | ch <- 10 13 | fmt.Println("success") 14 | } 15 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/channel/有缓冲通道.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func rec2(c chan int) (int int, err error) { 6 | ret := <-c 7 | return ret, nil 8 | } 9 | 10 | func main() { 11 | ch := make(chan int, 2) 12 | for i := 0; i < cap(ch); i++ { 13 | ch <- i 14 | a, err := rec2(ch) 15 | if err != nil { 16 | return 17 | } 18 | fmt.Println(a) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/channel/生产者消费者模型/无缓冲channel.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: huchao 3 | @since: 2022/8/3 4 | @desc: //TODO 无缓冲channel 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func producer(out chan<- int) { 11 | for i := 0; i < 10; i++ { 12 | data := i * i 13 | fmt.Println("生产者生产数据:", data) 14 | out <- data // 缓冲区写入数据 15 | } 16 | close(out) //写完关闭管道 17 | } 18 | 19 | func consumer(in <-chan int) { 20 | // 同样读取管道 21 | //for{ 22 | // val, ok := <- in 23 | // if ok { 24 | // fmt.Println("消费者拿到数据:", data) 25 | // }else{ 26 | // fmt.Println("无数据") 27 | // break 28 | // } 29 | //} 30 | 31 | // 无需同步机制,先做后做 32 | // 没有数据就阻塞等 33 | for data := range in { 34 | fmt.Println("消费者得到数据:", data) 35 | } 36 | 37 | } 38 | 39 | func main() { 40 | // 传参的时候显式类型像隐式类型转换,双向管道向单向管道转换 41 | ch := make(chan int) //无缓冲channel 42 | go producer(ch) // 子go程作为生产者 43 | consumer(ch) // 主go程作为消费者 44 | } 45 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/channel/生产者消费者模型/有缓冲channel.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: huchao 3 | @since: 2022/8/3 4 | @desc: //TODO 有缓冲channel 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | func producer2(out chan<- int) { 11 | for i := 0; i < 10; i++ { 12 | data := i * i 13 | fmt.Println("生产者生产数据:", data) 14 | out <- data // 缓冲区写入数据 15 | } 16 | close(out) //写完关闭管道 17 | } 18 | 19 | func consumer2(in <-chan int) { 20 | 21 | // 无需同步机制,先做后做 22 | // 没有数据就阻塞等 23 | for data := range in { 24 | fmt.Println("消费者得到数据:", data) 25 | } 26 | 27 | } 28 | 29 | func main() { 30 | // 传参的时候显式类型像隐式类型转换,双向管道向单向管道转换 31 | ch := make(chan int, 5) // 添加缓冲区,5 32 | 33 | go producer2(ch) // 子go程作为生产者 34 | consumer2(ch) // 主go程作为消费者 35 | } 36 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/exercise/README.md: -------------------------------------------------------------------------------- 1 | 2 | # 练习题 3 | 4 | 1. 使用 goroutine 和 channel 实现一个计算int64随机数各位数和的程序,例如生成随机数61345,计算其每个位数上的数字之和为19。 5 | 1. 开启一个 goroutine 循环生成int64类型的随机数,发送到`jobChan` 6 | 2. 开启24个 goroutine 从`jobChan`中取出随机数计算各位数的和,将结果发送到`resultChan` 7 | 3. 主 goroutine 从`resultChan`取出结果并打印到终端输出 -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/goroutine/exercise.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | var wg3 sync.WaitGroup 9 | 10 | func main() { 11 | for i := 0; i < 5; i++ { 12 | wg3.Add(1) 13 | go func(i int) { 14 | defer wg3.Done() 15 | fmt.Println(i) 16 | }(i) 17 | } 18 | wg3.Wait() 19 | } 20 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/goroutine/启动单个goroutine-test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func hello3() { 9 | fmt.Println("hello") 10 | } 11 | 12 | func main() { 13 | go hello3() // 启动另外一个goroutine去执行hello函数 14 | fmt.Println("main goroutine done!") 15 | time.Sleep(time.Second) 16 | } 17 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/goroutine/启动单个goroutine.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | // 当你并不关心并发操作的结 9 | // 或者有其它方式收集并发操作的结果时, 10 | // WaitGroup是实现等待一组并发操作完成的好方法。 11 | 12 | // 声明全局等待组变量 13 | var wg sync.WaitGroup 14 | 15 | func hello() { 16 | fmt.Println("hello") 17 | wg.Done() // 告知当前goroutine完成 18 | } 19 | 20 | func main() { 21 | wg.Add(1) // 登记一个goroutine 22 | hello() 23 | fmt.Println("你好") 24 | wg.Wait() // 阻塞等待登记对goroutine完成 25 | } 26 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/goroutine/启动多个goroutine.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | var wg2 sync.WaitGroup 9 | 10 | func hello2(i int) { 11 | defer wg2.Done() // goroutine结束就登记-1 12 | fmt.Println("hello", i) 13 | } 14 | 15 | func main() { 16 | for i := 0; i < 10; i++ { 17 | wg2.Add(1) // 启动一个goroutine就登记+1 18 | go hello2(i) 19 | } 20 | wg2.Wait() // 等待所有登记的goroutine都结束 21 | } 22 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/select/select.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | ch := make(chan int, 1) 7 | for i := 1; i <= 10; i++ { 8 | select { 9 | case x := <-ch: 10 | fmt.Println(x) 11 | case ch <- i: 12 | fmt.Println("输入i:", i) 13 | } 14 | } 15 | } 16 | 17 | //第一次循环时 i = 1,select 语句中包含两个 case 分支,此时由于通道中没有值可以接收,所以x := <-ch 这个 case 分支不满足,而ch <- i这个分支可以执行,会把1发送到通道中,结束本次 for 循环; 18 | //第二次 for 循环时,i = 2,由于通道缓冲区已满,所以ch <- i这个分支不满足,而x := <-ch这个分支可以执行,从通道接收值1并赋值给变量 x ,所以会在终端打印出 1; 19 | //后续的 for 循环以此类推会依次打印出3、5、7、9。 20 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/并发安全和锁/Map/map.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: huchao 3 | @since: 2022/8/2 4 | @desc: //TODO sync.Map 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "strconv" 11 | "sync" 12 | ) 13 | 14 | /* 15 | go进阶14讲 语言中内置的 map 不是并发安全的,如下代码 16 | */ 17 | 18 | var m = make(map[string]int) 19 | 20 | func get(key string) int { 21 | return m[key] 22 | } 23 | 24 | func set(key string, value int) { 25 | m[key] = value 26 | } 27 | 28 | func main() { 29 | wg := sync.WaitGroup{} 30 | for i := 0; i < 10; i++ { 31 | wg.Add(1) 32 | go func(i int) { 33 | key := strconv.Itoa(i) 34 | set(key, i) 35 | fmt.Printf("k=:%v,v=:%v\n", key, get(key)) 36 | wg.Done() 37 | }(i) 38 | } 39 | wg.Wait() 40 | } 41 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/并发安全和锁/Map/syncMap.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: huchao 3 | @since: 2022/8/2 4 | @desc: //TODO 并发读写sync.Map 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "strconv" 11 | "sync" 12 | ) 13 | 14 | // 并发安全对map 15 | var sm = sync.Map{} 16 | 17 | func main() { 18 | wg := sync.WaitGroup{} 19 | // 对sm执行20个并发的读写操作 20 | for i := 0; i < 20; i++ { 21 | wg.Add(1) 22 | go func(i int) { 23 | key := strconv.Itoa(i) 24 | sm.Store(key, i) // 存储key-value 25 | value, _ := sm.Load(key) // 根据key取值 26 | fmt.Printf("k:=%v,v:=%v\n", key, value) 27 | wg.Done() 28 | }(i) 29 | } 30 | wg.Wait() 31 | } 32 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/并发安全和锁/Once/once.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: huchao 3 | @since: 2022/8/2 4 | @desc: //TODO sync.Once 5 | **/ 6 | package main 7 | 8 | import ( 9 | "image" 10 | "sync" 11 | ) 12 | 13 | var icons map[string]image.Image 14 | 15 | var loadIconsOnce sync.Once 16 | 17 | func loadIcons() { 18 | icons = map[string]image.Image{ 19 | "left": loadIcon("left.png"), 20 | "up": loadIcon("up.png"), 21 | "right": loadIcon("right.png"), 22 | "down": loadIcon("down.png"), 23 | } 24 | } 25 | 26 | func loadIcon(s string) image.Image { 27 | return icons[s] 28 | } 29 | 30 | // Icon 被多个goroutine调用时不是并发安全的 31 | func Icon(name string) image.Image { 32 | if icons == nil { 33 | loadIcons() 34 | } 35 | return icons[name] 36 | } 37 | 38 | // Icon2 是并发安全的 39 | func Icon2(name string) image.Image { 40 | loadIconsOnce.Do(loadIcons) 41 | return icons[name] 42 | } 43 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/并发安全和锁/Once/singleton.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: edy 3 | @since: 2022/8/2 4 | @desc: //TODO 5 | **/ 6 | package main 7 | 8 | import ( 9 | "sync" 10 | ) 11 | 12 | type singleton struct{} 13 | 14 | var instance *singleton 15 | var once sync.Once 16 | 17 | func GetInstance() *singleton { 18 | once.Do(func() { 19 | instance = &singleton{} 20 | }) 21 | return instance 22 | } 23 | 24 | func main() { 25 | GetInstance() 26 | } 27 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/并发安全和锁/WaitGroup/waitgroup.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: huchao 3 | @since: 2022/8/2 4 | @desc: //TODO sync.WaitGroup 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "sync" 11 | ) 12 | 13 | var wg sync.WaitGroup 14 | 15 | func hello() { 16 | defer wg.Done() 17 | fmt.Println("Hello Goroutine!") 18 | } 19 | func main() { 20 | wg.Add(1) 21 | go hello() // 启动另外一个goroutine去执行hello函数 22 | fmt.Println("main goroutine done!") 23 | wg.Wait() 24 | } 25 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/并发安全和锁/互斥锁/Mutex.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: huchao 3 | @since: 2022/8/2 4 | @desc: //互斥锁 5 | **/ 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "sync" 11 | ) 12 | 13 | var wg sync.WaitGroup // 等待组 14 | var x int64 15 | var mutex sync.Mutex 16 | 17 | // add 对全局变量x执行5000次加1操作 18 | func add() { 19 | for i := 0; i < 5000; i++ { 20 | mutex.Lock() // 修改x前加锁 21 | x += 1 22 | mutex.Unlock() // 改完解锁 23 | } 24 | wg.Done() 25 | } 26 | 27 | func main() { 28 | wg.Add(2) 29 | //runtime.GOMAXPROCS(1) 30 | go add() 31 | go add() 32 | 33 | wg.Wait() 34 | fmt.Println(x) 35 | } 36 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/并发/并发安全和锁/数据竞争示例.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | var wg sync.WaitGroup // 等待组 9 | var x int64 10 | 11 | // add 对全局变量x执行5000次加1操作 12 | func add() { 13 | for i := 0; i < 5000; i++ { 14 | x += 1 15 | } 16 | wg.Done() 17 | } 18 | 19 | func main() { 20 | wg.Add(2) 21 | //runtime.GOMAXPROCS(1) 22 | go add() 23 | go add() 24 | 25 | wg.Wait() 26 | fmt.Println(x) 27 | } 28 | 29 | /* 30 | 开启了两个 goroutine 分别执行 add 函数, 31 | 这两个 goroutine 在访问和修改全局的x变量时就会存在数据竞争, 32 | 某个 goroutine 中对全局变量x的修改可能会覆盖掉另一个 goroutine 中的操作, 33 | 所以导致最后的结果与预期不符。 34 | */ 35 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/接口/huchao.txt: -------------------------------------------------------------------------------- 1 | 用户创建成功! 用户名为:huchao 2 | 密码是:123 3 | 创建完成时间:2022-8-4 16:53:51 4 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/接口/值接收者实现接口.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: huchao 3 | @since: 2022/8/3 4 | @desc: //TODO 值接收者实现接口 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | // Mover 定义一个接口类型 11 | type Mover interface { 12 | Move() 13 | } 14 | 15 | // Dog 狗结构体类型 16 | type Dog struct{} 17 | 18 | // Move 使用值接收者定义Move方法实现Mover接口 19 | func (d Dog) Move() { 20 | fmt.Println("狗会走🐶") 21 | } 22 | 23 | var x Mover // 声明一个Mover类型的变量x 24 | 25 | var d1 = Dog{} // d1是Dog类型 26 | 27 | var d2 = &Dog{} // d2是Dog指针类型 28 | 29 | func main() { 30 | x = d1 // 可以将d1赋值给变量x 31 | x.Move() 32 | 33 | x = d2 // 也可以将d2赋值给变量x 34 | x.Move() 35 | } 36 | 37 | /* 38 | 从上面的代码中我们可以发现, 39 | 使用值接收者实现接口之后, 40 | 不管是结构体类型还是对应的结构体指针类型的变量都可以赋值给该接口变量 41 | */ 42 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/接口/指针接收者实现接口.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: huchao 3 | @since: 2022/8/3 4 | @desc: //TODO 指针接收者实现接口 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | // Cat 猫结构体类型 11 | type Cat struct{} 12 | 13 | // Move 使用指针接收者定义Move方法实现Mover接口 14 | func (c *Cat) Move() { 15 | fmt.Println("猫会动") 16 | } 17 | 18 | func main() { 19 | var c1 = &Cat{} // c1是*Cat类型 20 | 21 | x = c1 // 可以将c1当成Mover类型 22 | x.Move() 23 | 24 | /* 25 | // 下面的代码无法通过编译 26 | var c2 = Cat{} // c2是Cat类型 27 | x = c2 // 不能将c2当成Mover类型 28 | */ 29 | } 30 | 31 | /* 32 | 由于Go语言中有对指针求值的语法糖, 33 | 对于值接收者实现的接口,无论使用值类型还是指针类型都没有问题。 34 | 但是我们并不总是能对一个值求址,所以对于指针接收者实现的接口要额外注意。 35 | */ -------------------------------------------------------------------------------- /golang/go-study/go语言基础/接口/类型与接口的关系.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: huchao 3 | @since: 2022/8/3 4 | @desc: //TODO 类型与接口的关系 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | // WashingMachine 洗衣机 11 | type WashingMachine interface { 12 | wash() 13 | dry() 14 | } 15 | 16 | // 甩干器 17 | type dryer struct{} 18 | 19 | // 实现WashingMachine接口的dry()方法 20 | func (d dryer) dry() { 21 | fmt.Println("甩一甩") 22 | } 23 | 24 | // 海尔 25 | type haier struct { 26 | dryer 27 | } 28 | 29 | // 实现WashingMachine接口的wash()方法 30 | func (h haier) wash() { 31 | fmt.Println("洗刷刷") 32 | } 33 | 34 | var h haier 35 | var wa WashingMachine 36 | 37 | func main() { 38 | 39 | wa = h 40 | wa.wash() 41 | wa.dry() 42 | 43 | var haier = haier{} 44 | var s = WashingMachine(haier) 45 | s.wash() 46 | s.dry() 47 | haier.dry() 48 | haier.dryer.dry() 49 | haier.wash() 50 | } 51 | -------------------------------------------------------------------------------- /golang/go-study/go语言基础/接口/类型断言.go: -------------------------------------------------------------------------------- 1 | /** 2 | @author: HuChao 3 | @since: 2022/8/4 4 | @desc: //TODO 类型断言 5 | **/ 6 | package main 7 | 8 | import "fmt" 9 | 10 | type Mover2 interface { 11 | move2() 12 | } 13 | 14 | type Pig struct { 15 | Name string 16 | } 17 | 18 | func (p Pig) move2() { 19 | //TODO implement me 20 | panic("implement me") 21 | } 22 | 23 | func main() { 24 | 25 | var n Mover2 = &Pig{Name: "pig"} 26 | v, ok := n.(*Pig) 27 | if ok { 28 | fmt.Println("类型断言成功") 29 | v.Name = "pig1" // 变量v是*Pig类型 30 | fmt.Println(v.Name) 31 | } else { 32 | fmt.Println("类型断言失败") 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /golang/go-study/常用组件库/定时任务/cron.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/robfig/cron/v3" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | c := cron.New() 11 | 12 | // 1、调用cron对象的AddFunc()方法向管理器中添加定时任务。 13 | // AddFunc()接受两个参数,参数 1 以字符串形式指定触发时间规则,参数 2 是一个无参的函数,每次触发时调用。 14 | // @every 1s表示每秒触发一次,@every后加一个时间间隔,表示每隔多长时间触发一次。 15 | c.AddFunc("@every 1s", func() { 16 | fmt.Println("tick every 1 second") 17 | }) 18 | 19 | // 2、除了直接将无参函数作为回调外,cron还支持Job接口: 20 | c.AddJob("@every 1s", GreetingJob{Name: "超哥"}) // 调用cron对象的AddJob()方法将GreetingJob对象添加到定时管理器中 21 | 22 | // 调用c.Start()启动定时循环。 23 | c.Start() // 启动一个新的 goroutine 做循环检测 24 | time.Sleep(time.Second * 5) // 防止主 goroutine 退出 25 | } 26 | 27 | // Job 接口 28 | type Job interface { 29 | Run() 30 | } 31 | 32 | // GreetingJob 定义一个实现接口Job的结构: 33 | type GreetingJob struct { 34 | Name string 35 | } 36 | 37 | func (g GreetingJob) Run() { 38 | fmt.Println("Hello", g.Name) 39 | } 40 | -------------------------------------------------------------------------------- /golang/go-study/常用组件库/常用限流策略——漏桶与令牌桶/令牌桶/juju-ratelimit.go: -------------------------------------------------------------------------------- 1 | package 令牌桶 2 | -------------------------------------------------------------------------------- /golang/go-study/常用组件库/常用限流策略——漏桶与令牌桶/漏桶/uber-go-ratelimit.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | "go.uber.org/ratelimit" 8 | ) 9 | 10 | // 文档:https://www.liwenzhou.com/posts/Go/ratelimit/#autoid-0-2-0 11 | // github:https://github.com/uber-go/ratelimit 12 | 13 | func main() { 14 | rl := ratelimit.New(100) // per second 15 | 16 | prev := time.Now() 17 | for i := 0; i < 10; i++ { 18 | now := rl.Take() 19 | fmt.Println(i, now.Sub(prev)) 20 | prev = now 21 | } 22 | 23 | // Output: 24 | // 0 0 25 | // 1 10ms 26 | // 2 10ms 27 | // 3 10ms 28 | // 4 10ms 29 | // 5 10ms 30 | // 6 10ms 31 | // 7 10ms 32 | // 8 10ms 33 | // 9 10ms 34 | } 35 | -------------------------------------------------------------------------------- /golang/go-study/常用组件库/数据结构与算法库/container/ring.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "container/ring" 5 | "fmt" 6 | ) 7 | 8 | // ring实现了环形链表的操作。 9 | // http://doc.golang.ltd/ 10 | 11 | func main() { 12 | ring := ring.New(5) 13 | fmt.Println(ring) 14 | } 15 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/第五届字节跳动青训营/h_promotion/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar 3 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/logs/h_promotion-ERROR-2022-12-30_1.log.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/第五届字节跳动青训营/h_promotion/logs/h_promotion-ERROR-2022-12-30_1.log.gz -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/logs/h_promotion-WARN-2022-12-30_1.log.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/golang/go-study/第五届字节跳动青训营/h_promotion/logs/h_promotion-WARN-2022-12-30_1.log.gz -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/HPromotionApplication.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion; 2 | 3 | import com.camp.promotion.util.ApplicationContextUtil; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.context.ConfigurableApplicationContext; 7 | 8 | /** 9 | * author Ryan Cui 10 | */ 11 | @SpringBootApplication 12 | public class HPromotionApplication { 13 | 14 | public static void main(String[] args) { 15 | ConfigurableApplicationContext applicationContext = SpringApplication.run(HPromotionApplication.class, args); 16 | ApplicationContextUtil.setApplicationContext(applicationContext); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/common/Constant.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.common; 2 | 3 | public class Constant { 4 | 5 | public static final int PROMO_QUANTITY = 1; 6 | public static final int POSTAGE = 0; 7 | 8 | public static final String PROMO_PREFIX = "promo_product_"; 9 | public static final String PROMO_STOCK_PREFIX = "promo_product_"; 10 | 11 | public static String generatePromoProductKey (Long promoId, Long skuId, Long spuId) { 12 | return "promo_product_" + promoId + "_" + skuId + "_" + spuId; 13 | } 14 | 15 | public static String generatePromoStockKey (Long promoId, Long skuId, Long spuId) { 16 | return "promo_product_stock_" + promoId + "_" + skuId + "_" + spuId; 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/config/WebMvcConfig.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.config; 2 | 3 | public class WebMvcConfig { 4 | } 5 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/controller/request/CreatePromoProductRequest.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.controller.request; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.Min; 6 | import javax.validation.constraints.NotNull; 7 | 8 | @Data 9 | public class CreatePromoProductRequest { 10 | 11 | /** 12 | * 活动spu id 13 | */ 14 | @NotNull(message = "spuId不能为null") 15 | private Long spuId; 16 | /** 17 | * 活动sku id 18 | */ 19 | @NotNull(message = "skuId不能为null") 20 | private Long skuId; 21 | /** 22 | * 数量 23 | */ 24 | @Min(1) 25 | @NotNull(message = "promoStock不能为null") 26 | private Integer promoStock; 27 | /** 28 | * 价格 29 | */ 30 | @Min(0) 31 | @NotNull(message = "promoPrice不能为null") 32 | private Integer promoPrice; 33 | } 34 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/convertet/ConvertFunction.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.convertet; 2 | 3 | public interface ConvertFunction { 4 | U apply(T t, R r); 5 | } 6 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/convertet/Converter.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.convertet; 2 | 3 | import java.util.function.Function; 4 | 5 | public interface Converter { 6 | 7 | R convert(Function f); 8 | } 9 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/convertet/MultiConverter.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.convertet; 2 | 3 | public interface MultiConverter { 4 | 5 | U convert(ConvertFunction f); 6 | } 7 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/enums/OrderStatusEnum.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.enums; 2 | 3 | public enum OrderStatusEnum { 4 | 5 | CANCEL(0), 6 | NON_PAYMENT(1), 7 | PAID(2), 8 | SEND(3), 9 | SUCCESS(4), 10 | CLOSE(5); 11 | 12 | private final int code; 13 | 14 | OrderStatusEnum(int code) { 15 | this.code = code; 16 | } 17 | 18 | public int getCode() { 19 | return code; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/enums/PaymentTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.enums; 2 | 3 | public enum PaymentTypeEnum { 4 | 5 | ONLINE(1); 6 | 7 | private final int code; 8 | 9 | PaymentTypeEnum(int code) { 10 | this.code = code; 11 | } 12 | 13 | public int getCode() { 14 | return code; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/enums/ProductStatusEnum.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.enums; 2 | 3 | public enum ProductStatusEnum { 4 | 5 | ONLINE(1), 6 | OFFLINE(2), 7 | DELETE(3); 8 | 9 | private final int code; 10 | 11 | ProductStatusEnum(int code) { 12 | this.code = code; 13 | } 14 | 15 | public int getCode() { 16 | return code; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/enums/PromoStatusEnum.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.enums; 2 | 3 | public enum PromoStatusEnum { 4 | 5 | INIT(0), 6 | ONLINE(1), 7 | OFFLINE(2); 8 | 9 | private final int code; 10 | 11 | PromoStatusEnum(int code) { 12 | this.code = code; 13 | } 14 | 15 | public int getCode() { 16 | return code; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/limit/RateEnum.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.limit; 2 | 3 | public enum RateEnum { 4 | 5 | RATE_100_PER_SECONDS(100, 1), 6 | RATE_1000_PER_SECONDS(1000, 1), 7 | RATE_3000_PER_SECONDS(3000, 1), 8 | RATE_5000_PER_SECONDS(5000, 1); 9 | 10 | private int count; 11 | 12 | private int duration; 13 | 14 | RateEnum(int count, int duration) { 15 | this.count = count; 16 | this.duration = duration; 17 | } 18 | 19 | public int getCount() { 20 | return count; 21 | } 22 | 23 | public int getDuration() { 24 | return duration; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/limit/RateLimit.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.limit; 2 | 3 | import java.lang.annotation.*; 4 | 5 | @Documented 6 | @Target(ElementType.METHOD) 7 | @Retention(RetentionPolicy.RUNTIME) 8 | public @interface RateLimit { 9 | 10 | String value() default ""; 11 | 12 | RateEnum rate() default RateEnum.RATE_100_PER_SECONDS; 13 | } 14 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/service/HPromoOrderService.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.service; 2 | 3 | import com.camp.promotion.model.CreateOrderModel; 4 | import com.camp.promotion.model.OrderModel; 5 | 6 | public interface HPromoOrderService { 7 | 8 | OrderModel createOrder(CreateOrderModel createOrderModel); 9 | } 10 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/service/HPromotionService.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.service; 2 | 3 | import com.camp.promotion.model.CreateActivityModel; 4 | import com.camp.promotion.model.CreatePromoProductModel; 5 | import com.camp.promotion.model.HPromoProductModel; 6 | 7 | import java.util.List; 8 | 9 | public interface HPromotionService { 10 | 11 | List CreatePromoActivity(CreateActivityModel createActivityModel); 12 | 13 | HPromoProductModel getPromotionProductDetail(Long promoId, Long skuId, Long spuId); 14 | } 15 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/service/RiskManagementService.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.service; 2 | 3 | import org.springframework.stereotype.Service; 4 | 5 | @Service 6 | public class RiskManagementService { 7 | 8 | public boolean riskManagement(Long userId) { 9 | return userId == 123456; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/java/com/camp/promotion/util/ApplicationContextUtil.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion.util; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | 5 | public class ApplicationContextUtil { 6 | 7 | private static ApplicationContext applicationContext; 8 | 9 | public static void setApplicationContext(ApplicationContext applicationContext) { 10 | ApplicationContextUtil.applicationContext = applicationContext; 11 | } 12 | 13 | public static T getBean(Class clazz) { 14 | return applicationContext.getBean(clazz); 15 | } 16 | 17 | public static Object getBean(String name) { 18 | return applicationContext.getBean(name); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/resources/decrease-stock.lua: -------------------------------------------------------------------------------- 1 | if (redis.call('exists', KEYS[1]) == 1) then 2 | local stock = tonumber(redis.call('get', KEYS[1])) 3 | if (stock == -1) then 4 | return 1 5 | end 6 | if (stock > 0) then 7 | redis.call('incrby', KEYS[1], -1) 8 | return stock - 1 9 | end 10 | return 0 11 | end 12 | return -1 -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/main/resources/unlock.lua: -------------------------------------------------------------------------------- 1 | local key = KEYS[1] 2 | local content = ARGV[1] 3 | local value = redis.call('get', key) 4 | 5 | if value == content then 6 | local delResult = redis.call('del', key) 7 | if delResult == 1 then 8 | return 1 9 | end 10 | return 0 11 | end 12 | return 0 -------------------------------------------------------------------------------- /golang/go-study/第五届字节跳动青训营/h_promotion/src/test/java/com/camp/promotion/HPromotionApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.camp.promotion; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class HPromotionApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /images/Blued/Blued.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Blued/Blued.jpeg -------------------------------------------------------------------------------- /images/GOLANG ROADMAP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/GOLANG ROADMAP.png -------------------------------------------------------------------------------- /images/GO语言算法和数据结构(golang语言实现).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/GO语言算法和数据结构(golang语言实现).png -------------------------------------------------------------------------------- /images/Golang面试八股文-刷完面试成功率90%10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Golang面试八股文-刷完面试成功率90%10.png -------------------------------------------------------------------------------- /images/Golang面试八股文刷完面试成功率90%--毛神.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Golang面试八股文刷完面试成功率90%--毛神.jpg -------------------------------------------------------------------------------- /images/Gophers 1️⃣群聊二维码.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers 1️⃣群聊二维码.png -------------------------------------------------------------------------------- /images/Gophers/1faaf9020e0df18fdf0429e0db211f37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/1faaf9020e0df18fdf0429e0db211f37.png -------------------------------------------------------------------------------- /images/Gophers/21d7b19498ecea607e93b8a1ac0334fd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/21d7b19498ecea607e93b8a1ac0334fd.png -------------------------------------------------------------------------------- /images/Gophers/3a80147ec037492954f53e254516f876.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/3a80147ec037492954f53e254516f876.jpeg -------------------------------------------------------------------------------- /images/Gophers/7e57e31c27a6f674d37f361acc99fe18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/7e57e31c27a6f674d37f361acc99fe18.png -------------------------------------------------------------------------------- /images/Gophers/98068ce517fb3cde20c01b4da3faee36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/98068ce517fb3cde20c01b4da3faee36.png -------------------------------------------------------------------------------- /images/Gophers/9ea6c4d634d77fe67828e15114126c83.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/9ea6c4d634d77fe67828e15114126c83.png -------------------------------------------------------------------------------- /images/Gophers/Excelize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/Excelize.png -------------------------------------------------------------------------------- /images/Gophers/Gin-Gonic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/Gin-Gonic.png -------------------------------------------------------------------------------- /images/Gophers/The Cloud-Native Application Proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/The Cloud-Native Application Proxy.png -------------------------------------------------------------------------------- /images/Gophers/a4569e34ee3c8189513108a2f7bedc42.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/a4569e34ee3c8189513108a2f7bedc42.jpeg -------------------------------------------------------------------------------- /images/Gophers/c4e30ec316973e501df2e99427f9f9d3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/c4e30ec316973e501df2e99427f9f9d3.png -------------------------------------------------------------------------------- /images/Gophers/d5aa7fb03c892fc7aec2816864d30e61.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/d5aa7fb03c892fc7aec2816864d30e61.png -------------------------------------------------------------------------------- /images/Gophers/e52e65e839b0d5e53e3d28bbcb07d790.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/e52e65e839b0d5e53e3d28bbcb07d790.png -------------------------------------------------------------------------------- /images/Gophers/ff0f3f3c6016016f059fbfd8c15c5d94.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/ff0f3f3c6016016f059fbfd8c15c5d94.png -------------------------------------------------------------------------------- /images/Gophers/go-git-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/go-git-logo.png -------------------------------------------------------------------------------- /images/Gophers/go-git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/go-git.png -------------------------------------------------------------------------------- /images/Gophers/golang-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/golang-logo.png -------------------------------------------------------------------------------- /images/Gophers/json-to-go.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Gophers/json-to-go.png -------------------------------------------------------------------------------- /images/Go学习开发地图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Go学习开发地图.png -------------------------------------------------------------------------------- /images/Go语言中文网.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Go语言中文网.png -------------------------------------------------------------------------------- /images/Mysql是怎样运行的.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Mysql是怎样运行的.png -------------------------------------------------------------------------------- /images/Mysql面试八股文-刷完面试成功率90%.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/Mysql面试八股文-刷完面试成功率90%.png -------------------------------------------------------------------------------- /images/R-C.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/R-C.jpeg -------------------------------------------------------------------------------- /images/RBAC.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/RBAC.jpg -------------------------------------------------------------------------------- /images/advanced-oauth-security.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/advanced-oauth-security.png -------------------------------------------------------------------------------- /images/deepseek.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/deepseek.png -------------------------------------------------------------------------------- /images/elasticsearch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/elasticsearch.jpg -------------------------------------------------------------------------------- /images/golang.design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/golang.design.png -------------------------------------------------------------------------------- /images/go语言标准库.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/go语言标准库.png -------------------------------------------------------------------------------- /images/kafka-logo-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/kafka-logo-7.png -------------------------------------------------------------------------------- /images/linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/linux.png -------------------------------------------------------------------------------- /images/mysql-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/mysql-2.png -------------------------------------------------------------------------------- /images/redis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/redis.png -------------------------------------------------------------------------------- /images/redis设计与实现.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/redis设计与实现.png -------------------------------------------------------------------------------- /images/微信交流群.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/微信交流群.jpg -------------------------------------------------------------------------------- /images/数据结构c语言版.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/数据结构c语言版.png -------------------------------------------------------------------------------- /images/最新面试300问Golang面试八股文.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/最新面试300问Golang面试八股文.png -------------------------------------------------------------------------------- /images/最新面试300问Golang面试八股文offer拿到手软.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/最新面试300问Golang面试八股文offer拿到手软.png -------------------------------------------------------------------------------- /images/消息队列.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/消息队列.jpeg -------------------------------------------------------------------------------- /images/现代操作系统.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/现代操作系统.png -------------------------------------------------------------------------------- /images/第五届字节跳动青训营 - 后端专场基础班.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/第五届字节跳动青训营 - 后端专场基础班.png -------------------------------------------------------------------------------- /images/计算机网络-第七版-谢希仁.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/计算机网络-第七版-谢希仁.jpg -------------------------------------------------------------------------------- /images/贝塔-北京.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/贝塔-北京.jpeg -------------------------------------------------------------------------------- /images/贝塔-成都.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/贝塔-成都.jpeg -------------------------------------------------------------------------------- /images/飞书.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/飞书.png -------------------------------------------------------------------------------- /images/高并发设计的15个锦囊.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/images/高并发设计的15个锦囊.png -------------------------------------------------------------------------------- /k8s/README.md: -------------------------------------------------------------------------------- 1 | ## 💻 K8S 2 | ![https://mao888.github.io/picx-images-hosting/soft-learn/image.26ldszahww.webp](https://mao888.github.io/picx-images-hosting/soft-learn/image.26ldszahww.webp) 3 | 4 | - [K8S面经](https://github.com/mao888/golang-guide/blob/main/k8s/k8s%E9%9D%A2%E7%BB%8F.md) 5 | - [k8s操作命令](https://github.com/mao888/golang-guide/blob/main/k8s/k8s%E6%93%8D%E4%BD%9C%E5%91%BD%E4%BB%A4.md) -------------------------------------------------------------------------------- /mongo/查询.md: -------------------------------------------------------------------------------- 1 | 2 | - [$exists](https://www.mongodb.com/docs/manual/reference/operator/query/exists/) 找到某个字段不为空的 3 | ```sql 4 | { field: { $exists: } } 5 | ``` 6 | 7 | - 根据字段排序 8 | ```sql 9 | .sort( { "borough": 1 } ) 10 | ``` 11 | 12 | - [$lt](https://www.mongodb.com/docs/manual/reference/operator/query/gt/) 13 | - 选择 数量少于20 个的所有文档 14 | ```sql 15 | db.inventory.find( { quantity: { $lt: 20 } } ) 16 | ``` -------------------------------------------------------------------------------- /project/data-sync/mongo-to-mysql/art_need/BI 数据权限2023-03-03.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/project/data-sync/mongo-to-mysql/art_need/BI 数据权限2023-03-03.xlsx -------------------------------------------------------------------------------- /project/data-sync/mongo-to-mysql/art_need/art_need_id.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/project/data-sync/mongo-to-mysql/art_need/art_need_id.txt -------------------------------------------------------------------------------- /project/data-sync/mongo-to-mysql/art_need/gia导入ARK用户账号密码.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/project/data-sync/mongo-to-mysql/art_need/gia导入ARK用户账号密码.xlsx -------------------------------------------------------------------------------- /project/data-sync/mongo-to-mysql/art_need/url_replace.go: -------------------------------------------------------------------------------- 1 | package art_need 2 | 3 | import ( 4 | "fmt" 5 | db2 "github.com/mao888/golang-guide/project/data-sync/db" 6 | "strings" 7 | ) 8 | 9 | func RunUrlReplace() { 10 | var adMaterial []*ArtAttachment 11 | db2.MySQLClientCruiser.Table("art_attachments").Find(&adMaterial) 12 | fmt.Println("len(ArtAttachment):", len(adMaterial)) 13 | 14 | var newUrl string = "https://ark-oss.bettagames.com" 15 | var oldUrl string = "https://gia-artneeds.nuclearport.com" 16 | 17 | for i, material := range adMaterial { 18 | fmt.Println("ad_material:", i) 19 | 20 | materialUrl := strings.Replace(material.URL, oldUrl, newUrl, -1) 21 | 22 | err := db2.MySQLClientCruiser.Table("art_attachments").Where("id = ?", material.ID). 23 | UpdateColumn("url", materialUrl).Error 24 | if err != nil { 25 | fmt.Println("更新数据 错误:", err) 26 | return 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /project/data-sync/mongo-to-mysql/sdk_release/README.md: -------------------------------------------------------------------------------- 1 | ### SDK发版管理 数据迁移到 ARK admin_console 2 | - 1、建立MongoDb连接 3 | - 2、从mongo查询数据 4 | - 3、将mongo数据装入切片 5 | - 4、将装有mongo数据的切片入mysql库 6 | 7 | | 数据库/表(MongoDb) | 迁移方式 | 目标数据库/表(Mysql) | 8 | | ---------------------------- | -------- | -------------------------------------------- | 9 | | SDK发版管理/MongoDb | | admin_console/mysql | 10 | | plat_console/projects | go脚本 | admin_console/sdk_project | 11 | | plat_console/projectversions | go脚本 | admin_console/sdk_release_record | 12 | | plat_console/sdks | go脚本 | admin_console/child_sdk | 13 | | plat_console/sdkversions | go脚本 | admin_console/child_sdk_release_record | 14 | -------------------------------------------------------------------------------- /project/data-sync/mongo-to-mysql/version-console/is_gray_to2.go: -------------------------------------------------------------------------------- 1 | package version_console 2 | 3 | import ( 4 | "fmt" 5 | db2 "github.com/mao888/golang-guide/project/data-sync/db" 6 | ) 7 | 8 | func RunIsGrayTo2() { 9 | var version []*Version 10 | db2.MySQLClientVersion.Table("version").Where("is_gray = ?", 1). 11 | Where("gray_scale = ?", 100).Where("is_deleted = ?", 0).Find(&version) 12 | fmt.Println("len(version):", len(version)) 13 | 14 | for i, v := range version { 15 | fmt.Println("version:", i) 16 | 17 | err := db2.MySQLClientVersion.Table("version").Where("id = ?", v.ID). 18 | UpdateColumn("is_gray", 0).Error 19 | if err != nil { 20 | fmt.Println("更新数据 错误:", err) 21 | return 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /project/业务/BAISHUN (语聊房模式)游戏对接/README.md: -------------------------------------------------------------------------------- 1 | ![img.png](img.png) -------------------------------------------------------------------------------- /project/业务/BAISHUN (语聊房模式)游戏对接/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/project/业务/BAISHUN (语聊房模式)游戏对接/img.png -------------------------------------------------------------------------------- /project/业务/BAISHUN (语聊房模式)游戏对接/signature生成参考代码.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/md5" 5 | "crypto/rand" 6 | "encoding/hex" 7 | "fmt" 8 | "time" 9 | ) 10 | 11 | func GenerateSignature(signatureNonce string, appKey string, timestamp int64) string { 12 | data := fmt.Sprintf("%s%s%d", signatureNonce, appKey, timestamp) 13 | h := md5.New() 14 | h.Write([]byte(data)) 15 | return hex.EncodeToString(h.Sum(nil)) 16 | } 17 | 18 | func main() { 19 | tempByte := make([]byte, 8) 20 | rand.Read(tempByte) 21 | signatureNonce := hex.EncodeToString(tempByte) 22 | fmt.Println("nonce:", signatureNonce) 23 | appKey := "8ddcffff3a80f4f4189ca1c9d4d902c3c909" 24 | timestamp := time.Now().Unix() 25 | fmt.Println("signature:", GenerateSignature(signatureNonce, appKey, timestamp)) 26 | } 27 | -------------------------------------------------------------------------------- /project/业务/三方抓数/Taurusx/token.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/md5" 5 | "encoding/hex" 6 | "fmt" 7 | "time" 8 | ) 9 | 10 | func GenerateHash(apiKey string) string { 11 | // 获取当前时间戳 12 | timestamp := time.Now().Unix() 13 | 14 | // 对时间戳进行MD5哈希 15 | timestampHashInBytes := md5.Sum([]byte(fmt.Sprintf("%d", timestamp))) 16 | timestampHash := hex.EncodeToString(timestampHashInBytes[:]) 17 | 18 | // 将API密钥和MD5哈希后的时间戳连接,并计算MD5哈希值 19 | data := fmt.Sprintf("%s%s", apiKey, timestampHash) 20 | hashInBytes := md5.Sum([]byte(data)) 21 | hash := hex.EncodeToString(hashInBytes[:]) 22 | 23 | return hash 24 | } 25 | 26 | func main() { 27 | apiKey := "e1a476536eac4e60b727b570c7140be5" 28 | result := GenerateHash(apiKey) 29 | 30 | fmt.Println("Generated Hash:", result) 31 | } 32 | -------------------------------------------------------------------------------- /project/业务/三方抓数/bigo/Base64.encode.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/base64" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | clientID := "2401244203476908609792" 10 | secret := "chv65g99dlw9" 11 | 12 | // 拼接client_id和secret,并转换为字节数组 13 | data := []byte(clientID + ":" + secret) 14 | 15 | // 使用base64进行编码 16 | encoded := base64.StdEncoding.EncodeToString(data) 17 | authorization := "Basic " + encoded 18 | fmt.Println("Base64 Encoded:", authorization) // Basic MjQwMTI0NDIwMzQ3NjkwODYwOTc5MjpjaHY2NWc5OWRsdzk= 19 | } 20 | -------------------------------------------------------------------------------- /project/业务/三方抓数/mintegral/token.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/md5" 5 | "fmt" 6 | "strconv" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | apiKey := "8a89923f6ad7b65c68cbe6e12249e9fd" 12 | timestamp := strconv.FormatInt(time.Now().Unix(), 10) 13 | fmt.Println(timestamp) 14 | token := md5.Sum([]byte(apiKey + fmt.Sprintf("%x", md5.Sum([]byte(timestamp))))) 15 | fmt.Printf("%x\n", token) 16 | } 17 | -------------------------------------------------------------------------------- /project/业务/加密excel/JPLAndroid端美国地区付费用户gaid信息-sha256加密.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/project/业务/加密excel/JPLAndroid端美国地区付费用户gaid信息-sha256加密.xlsx -------------------------------------------------------------------------------- /project/业务/加密excel/JPLAndroid端美国地区付费用户gaid信息.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/project/业务/加密excel/JPLAndroid端美国地区付费用户gaid信息.xlsx -------------------------------------------------------------------------------- /project/业务/飞书多维表格/新增记录.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | //type name struct { 5 | // Fields struct { 6 | // CreatedAt int64 `json:"创建日期"` 7 | // } `json:"fields"` 8 | //} 9 | //var ( 10 | // art ArtNeedMap 11 | // na name 12 | //) 13 | //na.Fields.CreatedAt = art.CreatedAt 14 | } 15 | -------------------------------------------------------------------------------- /project/规范/github flow 推荐流程.md: -------------------------------------------------------------------------------- 1 | GitHub Flow 是一个简单的持续集成和持续部署的工作流程,适用于任何规模的项目和团队。它由以下五个步骤组成: 2 | 3 | 1. 创建分支:在 GitHub 上创建一个新的分支来开发新的功能或修复问题。 4 | 2. 编写代码:在本地计算机上编写代码,并在分支上进行提交。 5 | 3. 发起 pull request:将分支合并到主分支之前,您需要发起 pull request,以便其他人审查您的代码并提出意见或建议。 6 | 4. Code Review:其他团队成员或开源贡献者将审查您的代码并提供反馈。在这个阶段,您可以通过与团队成员合作来解决任何问题或错误。 7 | 5. 合并分支:一旦您的代码通过了审查并经过了必要的修改,您可以将其合并到主分支上,这样您的代码就会自动部署到生产环境中。 8 | 9 | 下面是一些 GitHub Flow 的最佳实践: 10 | 11 | - 在每个 pull request 中只添加或修改一种功能或问题。 12 | - 经常进行代码审查,以确保代码质量和可维护性。 13 | - 使用自动化测试来检查代码是否能够正常运行。 14 | - 及时进行部署,以便及时修复问题。 15 | - 记录每个变更,以便在必要时进行追溯。 16 | - 遵守代码风格和最佳实践,以便使代码易于理解和维护。 17 | 18 | 通过遵守这些最佳实践,您可以确保团队的协作和代码质量的高效和稳定。 -------------------------------------------------------------------------------- /project/规范/git规范/新需求开发和分支管理.md: -------------------------------------------------------------------------------- 1 | 新需求开发和分支管理是软件开发过程中的重要组成部分。在开发新需求时,我们需要确保代码的稳定性和可维护性。为了实现这一目标,我们可以采用一种称为分支管理的方法。以下是一些建议和最佳实践: 2 | 3 | 1. 采用Git流(Gitflow)或GitHub流(GitHub Flow)等成熟的工作流程。这些工作流程为开发新功能、修复bug和发布新版本提供了明确的指导。 4 | 2. 为每个新需求创建单独的分支。这样可以确保主分支始终保持稳定,并允许团队成员在自己的分支上独立工作。 5 | 3. 使用有意义的分支名称。分支名称应该简短且描述性强,以便其他团队成员了解分支的目的。 6 | 4. 定期从主分支合并代码到功能分支。这有助于确保功能分支上的代码始终与主分支同步,减少合并冲突的可能性。 7 | 5. 在合并分支之前进行代码审查。这有助于确保代码质量,发现并修复潜在问题。 8 | 6. 在合并分支之前进行测试。确保功能分支中的代码在合并到主分支之前能够通过所有测试,以保持主分支的稳定性。 9 | 7. 有计划地合并分支。尽量避免在关键时间节点(如发布前夕)进行大量分支合并,以减少风险。 10 | 8. 删除已合并的功能分支。一旦分支被合并并成功部署,应当删除该分支以保持代码库的整洁。 11 | 9. 对团队进行培训,确保所有成员了解并遵循分支管理策略。这将有助于提高团队协作效率和降低开发风险。 12 | 13 | 通过遵循这些建议和最佳实践,您可以更好地管理新需求开发和分支管理,确保软件开发过程的顺利进行。 -------------------------------------------------------------------------------- /project/设计方案及调研/国内支付前后端方案调研.md: -------------------------------------------------------------------------------- 1 | package 设计方案及调研 2 | -------------------------------------------------------------------------------- /test.log: -------------------------------------------------------------------------------- 1 | {"level":"debug","timestamp":"2023-01-19T15:10:47.608+0800","label":"go-zap/go-log.go:38","message":"test debug","s_code":"30800"} 2 | {"level":"info","timestamp":"2023-01-19T15:10:47.608+0800","label":"go-zap/go-log.go:39","message":"test: info","s_code":"30800"} 3 | {"level":"debug","timestamp":"2023-01-19T15:10:47.608+0800","label":"go-zap/go-log.go:40","message":"debugf: dddd","s_code":"30800"} 4 | {"level":"debug","timestamp":"2023-01-19T15:10:47.609+0800","label":"go-zap/go-log.go:41","message":"debugf: dddd","s_code":"30800"} 5 | {"level":"info","timestamp":"2023-01-19T15:10:47.609+0800","label":"go-zap/go-log.go:42","message":"test: info","s_code":"30800"} 6 | {"level":"info","timestamp":"2023-01-19T15:10:47.609+0800","label":"go-zap/go-log.go:44","message":"msg1msg2","s_code":"30800","temp_field":"glog is good "} 7 | -------------------------------------------------------------------------------- /web/README.md: -------------------------------------------------------------------------------- 1 | ## 💻 Web 2 | ### Web 开发技术 3 | #### Web 性能 4 | * [渲染页面:浏览器的工作原理](https://github.com/mao888/golang-guide/blob/main/web/Web%20%E5%BC%80%E5%8F%91%E6%8A%80%E6%9C%AF/Web%20%E6%80%A7%E8%83%BD/%E6%B8%B2%E6%9F%93%E9%A1%B5%E9%9D%A2%EF%BC%9A%E6%B5%8F%E8%A7%88%E5%99%A8%E7%9A%84%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86.md) -------------------------------------------------------------------------------- /其他/README.md: -------------------------------------------------------------------------------- 1 | ## 💻 其他 2 | * [天津落户](https://github.com/mao888/golang-guide/blob/main/%E5%85%B6%E4%BB%96/%E5%A4%A9%E6%B4%A5%E8%90%BD%E6%88%B7.md) 3 | * [后端通用面试题](https://github.com/mao888/golang-guide/blob/main/%E5%85%B6%E4%BB%96/%E5%90%8E%E7%AB%AF%E9%80%9A%E7%94%A8%E9%9D%A2%E8%AF%95%E9%A2%98.md) -------------------------------------------------------------------------------- /分布式/分布式事务(更新中).md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/分布式/分布式事务(更新中).md -------------------------------------------------------------------------------- /分布式/分布式配置中心(更新中).md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/分布式/分布式配置中心(更新中).md -------------------------------------------------------------------------------- /安全/README.md: -------------------------------------------------------------------------------- 1 | ## 安全 2 | ### 认证授权 3 | - [认证授权基础概念详解](https://github.com/Snailclimb/JavaGuide/blob/main/docs/system-design/security/basis-of-authority-certification.md) 4 | - [JWT 基础概念详解](https://github.com/Snailclimb/JavaGuide/blob/main/docs/system-design/security/jwt-intro.md) 5 | - [JWT 优缺点分析以及常见问题解决方案](https://github.com/Snailclimb/JavaGuide/blob/main/docs/system-design/security/advantages&disadvantages-of-jwt.md) 6 | - [SSO 单点登录详解](https://github.com/Snailclimb/JavaGuide/blob/main/docs/system-design/security/sso-intro.md) 7 | - [权限系统设计详解](https://github.com/Snailclimb/JavaGuide/blob/main/docs/system-design/security/design-of-authority-system.md) 8 | ### 数据脱敏 9 | 数据脱敏说的就是我们根据特定的规则对敏感信息数据进行变形,比如我们把手机号、身份证号某些位数使用 * 来代替。 10 | ### 敏感词过滤 11 | [敏感词过滤方案总结](https://github.com/Snailclimb/JavaGuide/blob/main/docs/system-design/security/sentive-words-filter.md) 12 | -------------------------------------------------------------------------------- /开发工具/linux/linux速查/Linux速查备忘手册.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/开发工具/linux/linux速查/Linux速查备忘手册.pdf -------------------------------------------------------------------------------- /微服务/code/HTTP调用RESTful API/client.go: -------------------------------------------------------------------------------- 1 | // client/selectsort.go 2 | 3 | package main 4 | 5 | import ( 6 | "bytes" 7 | "encoding/json" 8 | "fmt" 9 | "io/ioutil" 10 | "net/http" 11 | ) 12 | 13 | //type addParam struct { 14 | // X int `json:"x"` 15 | // Y int `json:"y"` 16 | //} 17 | // 18 | //type addResult struct { 19 | // Code int `json:"code"` 20 | // Data int `json:"data"` 21 | //} 22 | 23 | func main() { 24 | // 通过HTTP请求调用其他服务器上的add服务 25 | url := "http://127.0.0.1:9090/add" 26 | param := addParam{ 27 | X: 10, 28 | Y: 20, 29 | } 30 | paramBytes, _ := json.Marshal(param) 31 | resp, _ := http.Post(url, "application/json", bytes.NewReader(paramBytes)) 32 | defer resp.Body.Close() 33 | 34 | respBytes, _ := ioutil.ReadAll(resp.Body) 35 | var respData addResult 36 | json.Unmarshal(respBytes, &respData) 37 | fmt.Println(respData.Data) // 30 38 | } 39 | -------------------------------------------------------------------------------- /微服务/code/HTTP调用RESTful API/server.go: -------------------------------------------------------------------------------- 1 | // server/selectsort.go 2 | 3 | package main 4 | 5 | import ( 6 | "encoding/json" 7 | "io/ioutil" 8 | "log" 9 | "net/http" 10 | ) 11 | 12 | type addParam struct { 13 | X int `json:"x"` 14 | Y int `json:"y"` 15 | } 16 | 17 | type addResult struct { 18 | Code int `json:"code"` 19 | Data int `json:"data"` 20 | } 21 | 22 | func add(x, y int) int { 23 | return x + y 24 | } 25 | 26 | func addHandler(w http.ResponseWriter, r *http.Request) { 27 | // 解析参数 28 | b, _ := ioutil.ReadAll(r.Body) 29 | var param addParam 30 | json.Unmarshal(b, ¶m) 31 | // 业务逻辑 32 | ret := add(param.X, param.Y) 33 | // 返回响应 34 | respBytes, _ := json.Marshal(addResult{Code: 0, Data: ret}) 35 | w.Write(respBytes) 36 | } 37 | 38 | func main() { 39 | http.HandleFunc("/add", addHandler) 40 | log.Fatal(http.ListenAndServe(":9090", nil)) 41 | } 42 | -------------------------------------------------------------------------------- /微服务/code/gRPC/hello_gRPC_client/go.mod: -------------------------------------------------------------------------------- 1 | module hello_grpc_client 2 | 3 | go 1.18 4 | 5 | require ( 6 | google.golang.org/grpc v1.50.1 7 | google.golang.org/protobuf v1.28.1 8 | ) 9 | 10 | require ( 11 | github.com/golang/protobuf v1.5.2 // indirect 12 | golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect 13 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect 14 | golang.org/x/text v0.3.3 // indirect 15 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect 16 | ) 17 | -------------------------------------------------------------------------------- /微服务/code/gRPC/hello_gRPC_client/proto/hello.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; // 版本声明,使用Protocol Buffers v3版本 2 | 3 | option go_package = "hello_gRPC_client/proto"; // 指定生成的Go代码在你项目中的导入路径 4 | 5 | package proto; // 包名 6 | 7 | // 定义一个 HelloService 服务 8 | service HelloService { 9 | // 普通 rpc,客户端向服务器发送一个请求,然后得到一个响应,就像普通的函数调用一样 10 | // SayHello 方法 11 | rpc SayHello (HelloRequest) returns (HelloResponse); 12 | } 13 | 14 | // 请求消息 15 | message HelloRequest { 16 | string Name = 1; 17 | } 18 | 19 | // 响应消息 20 | message HelloResponse { 21 | string reply = 1; 22 | } -------------------------------------------------------------------------------- /微服务/code/gRPC/hello_gRPC_server/go.mod: -------------------------------------------------------------------------------- 1 | module hello_gRPC_server 2 | 3 | go 1.18 4 | 5 | require ( 6 | google.golang.org/grpc v1.50.1 7 | google.golang.org/protobuf v1.28.1 8 | ) 9 | 10 | require ( 11 | github.com/golang/protobuf v1.5.2 // indirect 12 | golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect 13 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect 14 | golang.org/x/text v0.3.3 // indirect 15 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect 16 | ) 17 | -------------------------------------------------------------------------------- /微服务/code/gRPC/hello_gRPC_server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "google.golang.org/grpc" 7 | "hello_gRPC_server/proto" 8 | "net" 9 | ) 10 | 11 | // hello server 12 | type server struct { 13 | proto.UnimplementedHelloServiceServer 14 | } 15 | 16 | func (s *server) SayHello(ctx context.Context, in *proto.HelloRequest) (*proto.HelloResponse, error) { 17 | return &proto.HelloResponse{Reply: "hello " + in.Name}, nil 18 | } 19 | 20 | func main() { 21 | // 监听本地的8972端口 22 | listen, err := net.Listen("tcp", ":8972") 23 | if err != nil { 24 | fmt.Printf("failed to listen: %v", err) 25 | return 26 | } 27 | s := grpc.NewServer() // 创建gRPC服务器 28 | proto.RegisterHelloServiceServer(s, &server{}) // 在gRPC服务端注册服务 29 | // 启动服务 30 | err = s.Serve(listen) 31 | if err != nil { 32 | fmt.Printf("failed to serve: %v", err) 33 | return 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /微服务/code/gRPC/hello_gRPC_server/proto/hello.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; // 版本声明,使用Protocol Buffers v3版本 2 | 3 | option go_package = "hello_gRPC_server/proto"; // 指定生成的Go代码在你项目中的导入路径 4 | 5 | package proto; // 包名 6 | 7 | // 定义一个 HelloService 服务 8 | service HelloService { 9 | // 普通 rpc,客户端向服务器发送一个请求,然后得到一个响应,就像普通的函数调用一样 10 | // SayHello 方法 11 | rpc SayHello (HelloRequest) returns (HelloResponse); 12 | } 13 | 14 | // 请求消息 15 | message HelloRequest { 16 | string Name = 1; 17 | } 18 | 19 | // 响应消息 20 | message HelloResponse { 21 | string reply = 1; 22 | } -------------------------------------------------------------------------------- /微服务/code/rpc demo/使用JSON协议的RPC/client-json.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net" 7 | "net/rpc" 8 | "net/rpc/jsonrpc" 9 | ) 10 | 11 | func main() { 12 | // 建立TCP连接 13 | conn, err := net.Dial("tcp", "127.0.0.1:9091") 14 | if err != nil { 15 | log.Fatal("dialing:", err) 16 | } 17 | // 使用JSON协议 18 | client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn)) 19 | 20 | // 同步调用 21 | args := &Args{10, 20} 22 | var reply int 23 | err = client.Call("ServiceA.Add", args, &reply) 24 | if err != nil { 25 | log.Fatal("ServiceA.Add error:", err) 26 | } 27 | fmt.Printf("ServiceA.Add: %d+%d=%d\n", args.X, args.Y, reply) 28 | 29 | // 异步调用 30 | var reply2 int 31 | divCall := client.Go("ServiceA.Add", args, &reply2, nil) 32 | replyCall := <-divCall.Done // 接收调用结果 33 | fmt.Println(replyCall.Error) 34 | fmt.Println(reply2) 35 | } 36 | -------------------------------------------------------------------------------- /微服务/code/rpc demo/使用JSON协议的RPC/server-json.go: -------------------------------------------------------------------------------- 1 | // rpc demo/server3.go 2 | 3 | package main 4 | 5 | import ( 6 | "log" 7 | "net" 8 | "net/rpc" 9 | "net/rpc/jsonrpc" 10 | ) 11 | 12 | func main() { 13 | service := new(ServiceA) 14 | rpc.Register(service) // 注册RPC服务 15 | l, e := net.Listen("tcp", ":9091") 16 | if e != nil { 17 | log.Fatal("listen error:", e) 18 | } 19 | for { 20 | conn, err := l.Accept() 21 | if err != nil { 22 | return 23 | } 24 | // 使用JSON协议 25 | rpc.ServeCodec(jsonrpc.NewServerCodec(conn)) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /微服务/code/rpc demo/使用JSON协议的RPC/service.go: -------------------------------------------------------------------------------- 1 | // rpc demo/service.go 2 | 3 | package main 4 | 5 | type Args struct { 6 | X, Y int 7 | } 8 | 9 | // ServiceA 自定义一个结构体类型 10 | type ServiceA struct{} 11 | 12 | // Add 为ServiceA类型增加一个可导出的Add方法 13 | func (s *ServiceA) Add(args *Args, reply *int) error { 14 | *reply = args.X + args.Y 15 | return nil 16 | } 17 | -------------------------------------------------------------------------------- /微服务/code/rpc demo/基于TCP协议的RPC/client-tcp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net/rpc" 7 | ) 8 | 9 | func main() { 10 | // 建立TCP连接 11 | client, err := rpc.Dial("tcp", "127.0.0.1:9091") 12 | if err != nil { 13 | log.Fatal("dialing:", err) 14 | } 15 | 16 | // 同步调用 17 | args := &Args{10, 20} 18 | var reply int 19 | err = client.Call("ServiceA.Add", args, &reply) 20 | if err != nil { 21 | log.Fatal("ServiceA.Add error:", err) 22 | } 23 | fmt.Printf("ServiceA.Add: %d+%d=%d\n", args.X, args.Y, reply) 24 | 25 | // 异步调用 26 | var reply2 int 27 | divCall := client.Go("ServiceA.Add", args, &reply2, nil) 28 | replyCall := <-divCall.Done // 接收调用结果 29 | fmt.Println(replyCall.Error) 30 | fmt.Println(reply2) 31 | } 32 | -------------------------------------------------------------------------------- /微服务/code/rpc demo/基于TCP协议的RPC/server-tcp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net" 6 | "net/rpc" 7 | ) 8 | 9 | func main() { 10 | service := new(ServiceA) 11 | rpc.Register(service) // 注册RPC服务 12 | listener, err := net.Listen("tcp", ":9091") 13 | if err != nil { 14 | log.Fatal("listen error:", err) 15 | } 16 | for { 17 | conn, err := listener.Accept() 18 | if err != nil { 19 | return 20 | } 21 | rpc.ServeConn(conn) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /微服务/code/rpc demo/基于TCP协议的RPC/service.go: -------------------------------------------------------------------------------- 1 | // rpc demo/service.go 2 | 3 | package main 4 | 5 | type Args struct { 6 | X, Y int 7 | } 8 | 9 | // ServiceA 自定义一个结构体类型 10 | type ServiceA struct{} 11 | 12 | // Add 为ServiceA类型增加一个可导出的Add方法 13 | func (s *ServiceA) Add(args *Args, reply *int) error { 14 | *reply = args.X + args.Y 15 | return nil 16 | } 17 | -------------------------------------------------------------------------------- /微服务/code/rpc demo/基于http协议(基础RPC)示例/client-http.go: -------------------------------------------------------------------------------- 1 | // rpc demo/client.go 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "log" 8 | "net/rpc" 9 | ) 10 | 11 | func main() { 12 | // 建立HTTP连接 13 | client, err := rpc.DialHTTP("tcp", "127.0.0.1:9091") 14 | if err != nil { 15 | log.Fatal("dialing:", err) 16 | } 17 | 18 | // 同步调用 19 | args := &Args{10, 20} 20 | var reply int 21 | err = client.Call("ServiceA.Add", args, &reply) 22 | if err != nil { 23 | log.Fatal("ServiceA.Add error:", err) 24 | } 25 | fmt.Printf("ServiceA.Add: %d+%d=%d\n", args.X, args.Y, reply) 26 | 27 | // 异步调用 28 | var reply2 int 29 | divCall := client.Go("ServiceA.Add", args, &reply2, nil) 30 | replyCall := <-divCall.Done // 接收调用结果 31 | fmt.Println(replyCall.Error) 32 | fmt.Println(reply2) 33 | } 34 | -------------------------------------------------------------------------------- /微服务/code/rpc demo/基于http协议(基础RPC)示例/server-http.go: -------------------------------------------------------------------------------- 1 | // rpc demo/server-http.go 2 | 3 | package main 4 | 5 | import ( 6 | "log" 7 | "net" 8 | "net/http" 9 | "net/rpc" 10 | ) 11 | 12 | func main() { 13 | service := new(ServiceA) 14 | rpc.Register(service) // 注册RPC服务 15 | rpc.HandleHTTP() // 基于HTTP协议 16 | listener, err := net.Listen("tcp", ":9091") 17 | if err != nil { 18 | log.Fatal("listen error:", err) 19 | } 20 | http.Serve(listener, nil) 21 | } 22 | -------------------------------------------------------------------------------- /微服务/code/rpc demo/基于http协议(基础RPC)示例/service.go: -------------------------------------------------------------------------------- 1 | // rpc demo/service.go 2 | 3 | package main 4 | 5 | type Args struct { 6 | X, Y int 7 | } 8 | 9 | // ServiceA 自定义一个结构体类型 10 | type ServiceA struct{} 11 | 12 | // Add 为ServiceA类型增加一个可导出的Add方法 13 | func (s *ServiceA) Add(args *Args, reply *int) error { 14 | *reply = args.X + args.Y 15 | return nil 16 | } 17 | -------------------------------------------------------------------------------- /操作系统/study/现代操作系统/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/操作系统/study/现代操作系统/img.png -------------------------------------------------------------------------------- /操作系统/study/现代操作系统/现代操作系统原书第4版.md: -------------------------------------------------------------------------------- 1 | * [现代操作系统-第四版](https://stpnxkbsbf.feishu.cn/file/boxcniB8KM7FJ76sTSo0uBiXHvh) 2 | -------------------------------------------------------------------------------- /数据结构与算法/排序算法全解析/概述.md: -------------------------------------------------------------------------------- 1 | ## 概述 2 | 3 | 排序算法是一类非常经典的算法,说来简单,说难也难。刚学编程时大家都爱用冒泡排序,随后接触到选择排序、插入排序等,历史上还有昙花一现的希尔排序,公司面试时也经常会问到快速排序等等,小小的排序算法,融入了无数程序大牛的心血。 4 | 5 | 6 | 7 | 排序算法在生活中的应用非常广泛,比如: 8 | 9 | 10 | 11 | 在学校时,每位学生的考试成绩会按照降序排出名次 12 | 13 | 在电商领域,需要按照出单量排序,快速找出销量领先的商品 14 | 15 | 在游戏清算时,根据用户的表现分评选出 MVP 16 | 17 | 在不同领域,排序算法的实现各有千秋。总体来看,排序算法大致可分为十类: 18 | 19 | 20 | 21 | 选泡插:选择排序、冒泡排序、插入排序 22 | 23 | 快归希堆:快速排序、归并排序、希尔排序、堆排序 24 | 25 | 桶计基:桶排序、计数排序、基数排序 26 | 27 | 虽然工作中很少需要我们手打排序算法,只需要调用基础库中的 Arrays.sort() 便可解决排序问题。但你可曾静下心来,阅读 Arrays.sort() 背后的原理,它是采用了哪种排序算法呢? 28 | 29 | 30 | 31 | 事实上,Arrays.sort() 函数并没有采用单一的排序算法。Java 中的 Arrays.sort() 函数是由 Java 语言的几位创始人编写的,这个小小的函数逻辑严密,并且每个步骤都被精心设计,为了最大化性能做了一层又一层的优化,根据数据的概况采用双轴快排、归并或二分插入算法完成排序,堪称工业级排序算法的典范,理清之后其乐无穷。 32 | 33 | 34 | 35 | 并且,排序算法深受面试官的喜爱,在人才招聘时,总是将排序算法作为程序员的基本功来考察。对排序算法的理解深度在一定程度上反映了程序员逻辑思维的严谨度。攻克排序算法的难关是每位程序大牛的必经之路。 36 | 37 | 38 | 39 | 如牛顿所言,正是站在巨人的肩膀上,我们才能望得更远。本系列文章我们就来一起梳理一下排序算法的前世今生。 -------------------------------------------------------------------------------- /消息队列/README.md: -------------------------------------------------------------------------------- 1 | ## 消息队列 2 | [MQ面经](https://github.com/mao888/golang-guide/blob/main/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/MQ%E9%9D%A2%E7%BB%8F.md) 3 | ### kafaka 4 | - [Kafka知识体系](https://github.com/mao888/golang-guide/blob/main/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/Kafka%E7%9F%A5%E8%AF%86%E4%BD%93%E7%B3%BB.md) 5 | - [Kafka面经](https://github.com/mao888/golang-guide/blob/main/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/Kafka%E9%9D%A2%E7%BB%8F.md) 6 | ### RabbitMq 7 | - [RabbitMq](https://github.com/mao888/golang-guide/blob/main/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/RabbitMq.md) -------------------------------------------------------------------------------- /简历/我的简历/春招版本/胡超-18836288306-后端开发工程师.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/简历/我的简历/春招版本/胡超-18836288306-后端开发工程师.docx -------------------------------------------------------------------------------- /简历/我的简历/春招版本/胡超-18836288306-后端开发工程师.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/简历/我的简历/春招版本/胡超-18836288306-后端开发工程师.pdf -------------------------------------------------------------------------------- /简历/我的简历/秋招版本/胡超-18836288306-后端开发工程师(1).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/简历/我的简历/秋招版本/胡超-18836288306-后端开发工程师(1).pdf -------------------------------------------------------------------------------- /简历/求职技巧.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/简历/求职技巧.pdf -------------------------------------------------------------------------------- /简历/简历投递.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/简历/简历投递.pdf -------------------------------------------------------------------------------- /简历/简历模板.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/简历/简历模板.pdf -------------------------------------------------------------------------------- /高可用/README.md: -------------------------------------------------------------------------------- 1 | ## 💻 高可用 2 | * [高可用系统设计指南](https://github.com/mao888/golang-guide/blob/main/%E9%AB%98%E5%8F%AF%E7%94%A8/%E9%AB%98%E5%8F%AF%E7%94%A8%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1%E6%8C%87%E5%8D%97.md) 3 | * [冗余设计详解](https://github.com/mao888/golang-guide/blob/main/%E9%AB%98%E5%8F%AF%E7%94%A8/%E5%86%97%E4%BD%99%E8%AE%BE%E8%AE%A1%E8%AF%A6%E8%A7%A3.md) 4 | * [服务限流详解](https://github.com/mao888/golang-guide/blob/main/%E9%AB%98%E5%8F%AF%E7%94%A8/%E6%9C%8D%E5%8A%A1%E9%99%90%E6%B5%81%E8%AF%A6%E8%A7%A3.md) 5 | * [降级&熔断详解(更新中)](https://github.com/mao888/golang-guide/blob/main/%E9%AB%98%E5%8F%AF%E7%94%A8/%E9%99%8D%E7%BA%A7%26%E7%86%94%E6%96%AD%E8%AF%A6%E8%A7%A3%EF%BC%88%E6%9B%B4%E6%96%B0%E4%B8%AD%EF%BC%89.md) 6 | * [超时&重试详解](https://github.com/mao888/golang-guide/blob/main/%E9%AB%98%E5%8F%AF%E7%94%A8/%E8%B6%85%E6%97%B6%26%E9%87%8D%E8%AF%95%E8%AF%A6%E8%A7%A3.md) 7 | * [性能测试入门](https://github.com/mao888/golang-guide/blob/main/%E9%AB%98%E5%8F%AF%E7%94%A8/%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95%E5%85%A5%E9%97%A8.md) -------------------------------------------------------------------------------- /高可用/降级&熔断详解(更新中).md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/高可用/降级&熔断详解(更新中).md -------------------------------------------------------------------------------- /高并发/README.md: -------------------------------------------------------------------------------- 1 | ## 💻高并发 2 | * [高并发系统设计](https://github.com/mao888/golang-guide/blob/main/%E9%AB%98%E5%B9%B6%E5%8F%91/%E9%AB%98%E5%B9%B6%E5%8F%91%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1.md) -------------------------------------------------------------------------------- /高性能/常见 SQL 优化手段总结(更新中).md: -------------------------------------------------------------------------------- 1 | 暂见: 2 | 3 | [**MySQL索引及优化全总结**](https://github.com/mao888/golang-guide/blob/main/mysql/MySQL%E7%B4%A2%E5%BC%95%E5%8F%8A%E4%BC%98%E5%8C%96%E5%85%A8%E6%80%BB%E7%BB%93.md) 4 | 5 | -------------------------------------------------------------------------------- /高性能/负载均衡详解(更新中).md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mao888/golang-guide/8db3be69f336c6a97b4c8987670c1f9dc3bbd7ea/高性能/负载均衡详解(更新中).md --------------------------------------------------------------------------------