- 博客(76)
- 收藏
- 关注
原创 Go 并发编程:Goroutine常见应用范式
一、多独立协程并发——worker分工模式并发协程独立运行且互不通信,主协程等待处理独立子协程的结果并发编程有一种常见方式就是许多工作子协程都是独立的,互不干扰,但他们又是“同一时间”处理。例如http服务器的工作模式就是这种,在go标准包net/http中,http服务启动后,它所接收的每一个请求都是独立协程处理的,每个请求的运行协程之间都互不通信。我们知道,go http服务的请求...
2020-03-06 00:50:01
404
原创 Go 并发编程:通道应用范式之管道模式
管道模式一、类Unix串行管道:使用通道实现串行管道功能我们在使用类Unix系统时常常用到管道命令,如"ls |grep 'path/to' ",它可以让数据在多个命令操作中串行处理。Go的通道也可以做到如此,利用通道通信的特性我们可以创建多个连续通道,让一个函数的输出作为另一个函数的输入,而另一个函数的输出也可以作为其他函数的输入。Go标准库中的io.Pipe()可以创建类Unix风格管道...
2020-03-05 00:20:53
350
原创 Go 并发编程:通道常见应用范式
通道经典应用一、闭包实现通道访问限制在Go的并发编程中,创建通道和开辟协程是非常方便且容易的,正因如此,有可能会导致开发者滥用。如果在团队开发中没有良好的协商和规范,更可能会导致并发数据不安全。例如:func Demo() { ch := make(chan int, 0) go dosomething(ch, 10) go dosomething(ch, 20)...
2020-03-04 22:46:03
376
原创 Go 并发编程:利用通道创建并发安全的数据结构
利用通道创建并发安全的映射或切片创建一个并发安全的映射或切片,不需要使用锁或者其他底层原语我们之前讲过值类型的数据在函数参数传递时是拷贝传递,所以没有并发安全问题,我们并不用担心传递的值被多个协程操作的后果。然而当我们使用切片、映射等引用类型参数,甚至指针等参数时,多个并发协程对该参数的操作会引起混乱,这样的参数传递是数据不安全的。我们知道对于引用或指针在协程内的操作,如果它同时被多个协...
2020-03-04 13:40:44
357
原创 Go 并发编程:错误处理及错误传递
一、协程错误管理我们在基础系列讲过Go程序开发中的错误处理规范,展示了几种函数执行中的错误返回问题,而在Go并发编程中,我们常常会忽略协程里面的错误处理问题,有时候,我们花了很多时间思考我们的各种流程将如何共享信息和协调,却忘记考虑如何优雅地处理错误。Go避开了流行的错误异常模型,Go认为错误处理非常重要,并且在开发程序时,我们应该像关注算法一样关注它,即错误处理也是业务流程的一部分~思考错误...
2020-03-04 13:40:12
676
原创 Go 并发编程:防止Goroutine泄露
防止Goroutine泄露Goroutine开启后一般会一直执行到它终止,也有遇到不可恢复的错误(如协程内部错误或父协程退出)时被迫终止。如果没有一定的手段,父协程是没法控制子协程的,有没有什么方式让父协程控制或感知子协程的运行呢?答案是有的,一般有三种典型方式:使用done通道控制使用sync.WaitGroup同步组使用Context一、使用done通道控制创建一个监控通道d...
2020-03-04 13:39:15
228
原创 Go并发编程小贴士
一、死锁陷阱关于Go的并发编程,你会遇到哪些陷阱:主协程退出时,所有子协程都一并退出;所有子协程都已经完成工作,但主协程和一些工作协程还存活,这是由于主协程无法获得工作协程的完成状态;多个不同的协程都锁定了受保护的资源而且同时尝试去获得对方资源的时候,即死锁。以上陷阱的主要缘由是主协程不知道子协程的工作状态和结果常见解决方案:简约方法:让主协程在一个done 通道上等待,根据接收...
2020-02-22 21:50:26
101
原创 常见算法思想6:回溯法
回溯法回溯法也叫试探法,试探的处事方式比较委婉,它先暂时放弃关于问题规模大小的限制,并将问题的候选解按某种顺序逐一进行枚举和检验。当发现当前候选解不可能是正确的解时,就选择下一个候选解。如果当前候选解除了不满足问题规模要求外能够满足所有其他要求时,则继续扩大当前候选解的规模,并继续试探。如果当前候选解满足包括问题规模在内的所有要求时,该候选解就是问题的一个解。在试探算法中,放弃当前候选解,并继续...
2020-02-20 16:24:27
757
原创 常见算法思想8:动态规划法
动态规划问题的分类求最大最小值从左上角走到右下角路径的最大数字和最长上升子序列长度计数有多少种方式...有多少种方法选出k个数使得和是sum求存在性取石子游戏,先手是否必胜能不能选出k个数使得和是sum常见动态规划问题的类型坐标型动态规划(20%) :二维数组下标就是坐标,如机器人路线问题序列型动态规划(20%) :划分型动态规划(20%) :给一...
2020-02-19 21:50:40
119
原创 常见算法思想7:贪心法
贪心算法的思想即对于目标T,对于达成它的每一局部都选择最优选项,直到满足或最终近似满足为止,最终结果或许不是全局最优解,但应该是近似最优解,因为它足够简单。每一步都采取局部最优做法!贪婪算法大多时候都是近似最优算法!贪心算法的三步走:第一步:明确到底什么是最优解?第二步:明确什么是子问题的最优解?第三步:分别求出子问题的最优解再堆叠出全局最优解?贪心算法的前提:原问题复杂度过高...
2020-02-19 21:50:08
158
原创 常见算法思想5:分治法
分治法分治算法采取了各个击破的方法,将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。我们只要求出子问题的解,就可得到原问题的解。在编程过程中,我们经常遇到处理数据相当多、求解过程比较复杂、直接求解法会比较耗时的问题。在求解这类问题时,我们可以采用“各个击破”的方法。具体做法是先把这个问题分解成几个较小的子问题,找到求出这几个子问题的解法后,再找到合适的方法...
2020-02-19 21:49:41
572
原创 常见算法思想4:迭代法
迭代法迭代法也被称为辗转法,是一种不断用变量的旧值递推新值的过程,在解决问题时总是重复利用一种方法。与迭代法相对应的是直接法(或者称为一次解法),即一次性解决问题。迭代法又分为精确迭代和近似迭代。“二分法”和“牛顿迭代法”属于近似迭代法,功能都比较类似。在使用迭代算法解决问题时,需要做好如下3个方面的工作:(1)确定迭代变量在可以使用迭代算法解决的问题中,至少存在一个迭代变量,即直接或间接...
2020-02-19 21:38:37
2947
原创 常见算法思想3:递归法
递归法在计算机编程应用中,我们常常遇到代码的递归调用,事实上,递归是一种编程技巧,它是分治思想的一种重要体现。递归算法对解决大多数问题是十分有效的,它能够使算法的描述变得简洁而且易于理解。从直观上讲,递归是将大问题化为相同结构的小问题,从待求解的问题出发,一直分解到已经已知答案的最小问题为止,然后再逐级返回,从而得到大问题的解。从本质上讲,计算机在执行递归调用时是一个不断压栈出栈的过程,递归...
2020-02-19 17:14:20
1691
原创 常见算法思想2:递推法
递推法递推算法犹如稳重的有经验的老将,使用“稳扎稳打”的策略,不断利用已有的信息推导出新的东西。在日常应用中有如下两种递推算法:(1)顺推法:从已知条件出发,逐步推算出要解决问题的方法。(2)逆推法:从已知的结果出发,用迭代表达式逐步推算出问题开始的条件,即顺推法的逆过程。顺推法例如斐波那契数列就可以通过顺推法不断递推算出新的数据:兔子问题:有一对兔子,从出生后第3个月起每个月生一...
2020-02-19 17:13:59
664
原创 常见算法思想1:枚举法
一、枚举法枚举算法的思想是:将问题的所有可能的答案一一列举,然后根据条件判断此答案是否合适,保留合适的,丢弃不合适的。使用枚举算法解题的基本思路如下所示:(1)确定枚举对象、枚举范围和判定条件。(2)逐一枚举可能的解,验证每个解是否是问题的解。枚举算法一般按照如下3个步骤进行:(1)题解的可能范围,不能遗漏任何一个真正解,也要避免有重复。(2)判断是否是真正解的方法。(3)使可能解...
2020-02-19 17:13:42
5830
原创 17 基本查找算法:插值查找与斐波那契查找
一、插值查找原理在介绍插值查找之前,首先考虑一个新问题,为什么二分查找算法一定要是折半,而不是折四分之一或者折更多呢?打个比方,在英文字典里面查“apple”,你下意识翻开字典是翻前面的书页还是后面的书页呢?如果再让你查“zoo”,你又怎么查?很显然,这里你绝对不会是从中间开始查起,而是有一定目的的往前或往后翻。同样的,比如要在取值范围1 ~ 10000 之间 100 个元素从小到大均匀...
2020-02-18 15:09:51
212
原创 16 基本查找算法:二分查找算法
二分查找算法原理二分查找算法也叫折半法查找法,要求待查找的列表必须是按关键字大小有序排列的顺序表。查找过程如下所示:(1)将表中间位置记录的关键字与查找关键字比较,如果两者相等则表示查找成功;否则利用中间位置记录将表分成前、后两个子表。(2)如果中间位置记录的关键字大于查找关键字,则进一步查找前一个子表,否则查找后一个子表。(3)重复以上过程,一直到找到满足条件的记录为止时表明查找成功...
2020-02-18 15:09:18
1575
原创 15 基本查找算法:顺序查找与分块查找
一、顺序查找算法在基于线性表查找的算法中,顺序查找是最简单的,基本思想就是暴力枚举查找。顺序查找法的特点是逐一比较指定的关键字与线性表中各个元素的关键字,一直到查找成功或失败为止。说明:顺序查找适合于存储结构为顺序存储或链接存储的线性表。基本思想:顺序查找也称为线形查找,属于无序查找算法。从数据结构线形表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成...
2020-02-18 15:08:31
445
原创 14 基本查找算法概述
基本查找算法概述在之前的文章中已经数据结构的基本知识,包括线性表、哈希表、树、图结构,并讨论了这些结构的存储映像,以及定义在其上的相应运算,并且我们概述了几种排序算法。除了基本排序算法外,我们接下来了解几种基于基本数据结构的查找算法,包括基于线性表的查找、基于树的查找、基于哈希的查找等。在同样的数据结构中,我们通过前面介绍的线性结构、树和图保存数据以后,在使用时也需要通过查找来调用这个数据。由...
2020-02-18 15:07:49
101
原创 13 基本排序算法:基数排序
基数排序原理基数排序属于"低位优先”排序法,通过反复进行分配与收集操作完成排序。假设记录r[i]的关键字为keyi,keyi是由d位十进制数字构成的,即keyi=Ki1 Ki2 …Kid ,则每一位可以视为一个子关键字,其中Ki1 是最高位,Kid 是最低位,每一位的值都在0≤Kij ≤9的范围内,此时基数rd=10。如果keyi是由d个英文字母构成的,即keyi=Ki1 Ki2 …Kid ,...
2020-02-18 00:58:15
150
原创 12 基本排序算法:归并排序
归并排序原理归并排序思想该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。时间复杂度是 O(nlogn),空间复杂度O(n)。归并排序就是利用归并过程,开始时先将k个数据看成k个长度为1的已排好序的表,将相邻的表成对合并,得到长度为...
2020-02-18 00:56:08
203
原创 11 基本排序算法:桶排序与计数排序
一、桶排序原理桶排序(Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶里。每个桶再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序),最后依次把各个桶中的记录列出来记得到有序序列。桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。但桶排序并不是比较排序,他不受到O(n log...
2020-02-18 00:47:38
305
原创 10 基本排序算法:直接选择排序与堆排序
一、直接选择排序原理直接选择排序又被称为简单选择排序,第i趟简单选择排序是指通过n-i次关键字的比较,从n-i+1个记录中选出关键字最小的记录,并和第i个记录进行交换。这样共需进行i-1趟比较,直到排序完成所有记录为止。例如当进行第i趟选择时,从当前候选记录中选出关键字最小的k号记录,并和第i个记录进行交换。对于拥有n个记录的文件的直接选择排序来说,其过程可以经过n-1趟直接选择排序得到一个...
2020-02-18 00:27:19
353
原创 9 基本排序算法:直接插入排序与希尔排序
一、直接插入排序原理直接插入排序是一种最基本的插入排序方法,能够将第i个记录插入到前面i-1个已排好序的记录中,具体插入过程如下所示。将第i个记录的关键字Ki 顺序与其前面记录的关键字Ki-1 , Ki-2 , …, K1 进行比较,将所有关键字大于Ki 的记录依次向后移动一个位置,直到遇见关键字小于或者等于Ki 的记录Kj 。此时Kj 后面必为空位置,将第i个记录插入空位置即可。完整的直接...
2020-02-18 00:02:15
221
原创 8 基本排序算法:冒泡排序与快速排序
一、冒泡排序原理冒泡排序是一种简单的交换类排序方法,能够将相邻的数据元素进行交换,从而逐步将待排序序列变成有序序列。冒泡排序的基本思想是:从头扫描待排序记录序列,在扫描的过程中顺次比较相邻两个元素的大小。下面以升序为例介绍排序过程:1.在第一趟排序中,对n个记录进行如下操作。①对相邻的两个记录的关键字进行比较,逆序时就交换位置。②在扫描的过程中,不断向后移动相邻两个记录中关键字较大的记...
2020-02-17 18:37:46
789
原创 7 基本排序算法概述
通过排序(Sorting)可以重新排列一个数据元素集合或序列,目的是排列成一个按数据元素某个项值排序的序列。排序是计算机程序设计中的一种重要操作,作为排序依据的数据项被称为“排序码”,即数据元素的关键码。排序的目的和过程为了便于查找,我们很希望计算机中的数据表是按关键码进行有序排列的,例如使用有序表的折半查找会提高查找效率。另外,二叉排序树、B-树和B+树的构造过程也都是一个排序过程。如果关键...
2020-02-17 18:20:23
148
原创 6 基本数据结构:图
图的概述在众多数据结构中,图应该是最复杂的数据结构了,要了解图的全貌需要较深厚的数学基础,这里不可能在一篇文章内讲完,所以只做抛砖引玉。图的基本概念图的两种形式.png有向图:图G中的每条边都是有方向的,则称G为有向图(Digraph)。在有向图中,一条有向边是由两个顶点组成的有序对,有序对通常用尖括号表示。有向边也被称为弧,将边的始点称为弧尾,将终点称为弧头。无向图:如果图...
2020-02-17 01:56:22
128
原创 5 基本数据结构:堆
什么是堆堆是一种经过排序的树形数据结构,每个节点都有一个值。通常我们所说的堆的数据结构,是指二叉堆。堆的特点是根节点的值最小(或最大),且根节点的两个子树也是一个堆。最大堆和最小堆.jpg由于堆的这个特性,所有常用来实现优先队列。堆的存取是随意的,这就如同我们在图书馆的书架上取书,虽然书的摆放是有顺序的,但是我们想取任意一本时不必像栈一样,先取出前面所有的书,书架这种机制不同于箱子...
2020-02-17 01:56:07
84
原创 3 基本数据结构:哈希表
哈希表什么是哈希表?哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。哈希函数index = hashtable(key)这里的对应关系f称为散列函数,又称为哈希(Hash函数),采用散列技术将记录存储在...
2020-02-17 01:55:24
540
原创 4 基本数据结构:树与二叉搜索树
树在计算机领域中,树是一种很常见的数据结构之一,这是一种非线性的数据结构。树能够把数据按照等级模式存储起来,例如树干中的数据比较重要,而小分支中的数据的功能一般比较次要。在学习树结构之前需要先了解一些概念:树形关系结构图.png节点的度:是指一个节点的子树个数。树的度:一棵树中节点度的最大值。叶子(终端节点):度为0的节点。分支节点(非终端节点):度不为0的节点。内部节...
2020-02-17 01:54:57
395
原创 2 基本数据结构:队列与栈
一、队列队列是一种受限的线性表,一般由链表实现(也可以用数组实现,链表队列性能较高),因为它只允许表头进入表尾推出,顺序为先进先出。队列的常见操作:enqueue(element) 向队尾添加一个或多个项dequeue(): 移除队列的第一(即趴在队列最前面的)项,并返回被移除的元素front():返回队列中的第一个元素——即最先被添加,也将是最先被移除的元素,队列不做任何变动(不移除...
2020-02-17 01:54:43
89
原创 1 基本数据结构:数组与链表
线性表基本概念线性表是最基本、最简单、最常用的一种数据结构之一。在实际应用中,线性表都是以数组、字符串、链表、栈、队列、位图等特殊线性表的形式来使用的。因为这些特殊线性表都具有自己的特性,所以掌握这些特殊线性表的特性,对于数据运算的可靠性和提高操作效率是至关重要的。线性表.png线性表是一个线性结构,它是一个含有n≥0个节点的有限序列。在节点中,有且仅有一个开始节点没有前驱并有一...
2020-02-17 01:54:08
138
原创 0 数据结构与算法概述
概述在当今程序员的世界,算法已经成为衡量一名程序员水平高低的参照物。高深的程序员都会看重数据结构和算法的作用,水平越高,就越能理解算法的重要性。算法不仅仅是运算工具,它更是程序的“灵魂”。在现实项目开发过程中,很多实际问题需要精心设计的算法才能有效解决。对个人来讲,对算法的掌握也是区别于他人、保持竞争力的重要方面。算法是计算机处理信息的本质,因为计算机程序本质上是一个算法,告诉计算机确切的步骤...
2020-02-17 01:52:04
101
原创 19 Go Web 框架(二):框架技术详解
一、 net/http包够用吗?Go的net相关标准包提供web开发的大多数实现支持,如果你的项目的路径端点在十个以内,如一个简单的企业网站,这当然是够用的。但如果你的项目是构建一个大型电商网站,有成千上万个页面的路径端点,如下:GET /goods/:idPOST /order/:idDELTE /goods/:idGET /goods/:id/name...GET ...
2019-07-24 15:28:36
381
原创 18 Go Web框架(一):Web技术概述
Web技术概述1. Web简介Web的本意是蜘蛛网或网,在网页设计中称为网页。现广泛译作网络、互联网等技术领域,表现为三种形式,即超文本(hypertext)、超媒体(hypermedia)、超文本传输协议(HTTP)等。WEB技术指的是开发互联网应用的技术总称,一般包括WEB服务端技术和WEB客户端技术。Web技术本质就是实现网络各端点互联互通的技术,无论是C/S架构、B/S架构,还是...
2019-07-21 13:49:38
295
原创 17 Go 鉴权(三):JWT
Go 使用JWT鉴权一、实现思路:实现一个基于jwt-go包的JWT编解码工具实现一个HTTP服务器编写登录处理器,接收用户认证信息后,从数据库获取用户信息(假设用户已注册),使用TokenService编码成token返回给用户保存编写获取用户信息处理器,接收后湖token,解码token,返回信息给用户。二、jwt-go简单用例:1.实现一个简单的JWT编解码服务:jw...
2019-07-20 20:24:50
187
原创 16 Go 鉴权(二):实现Session管理器及Session存储
一、Go实现Session管理器Go官方没有提供Session管理器,我们需自己实现Session管理器,Session的存储可以使用文件系统、缓存系统或数据库系统都可以。以下实现出自Github开源项目beego的Session实现,仅供参考:出处:https://github.com/astaxie/sessionSession创建过程session的基本原理是由服务器为每个会话维护一...
2019-07-20 18:49:21
611
原创 15 Go 鉴权(一):鉴权机制概述
一、系统鉴权概述在现代web开发中,系统鉴权服务已是基本标配模块,有些开发框架甚至内置了鉴权模块的实现,或者提供一些鉴权的工具类,然而鉴权的方式也分为多种,了解各种鉴权方式的特点及使用场景可以帮助我们构建更健壮的web系统。以下列出四种常见的鉴权方式,我们来认识一下:HTTP Basic AuthenticationSession-Cookie机制Token令牌机制OAuth2.0授权...
2019-07-20 18:49:12
658
原创 14 Go Debug
一、Debug概述在程序开发过程中,多多少少会出现编译出错,运行时错误等等,有些是语法错误,有些是拼写错误,有些是语言特性没理解到位,这些因素都会造成程序开发的暂时中断,影响开发进度。所以常见的错误还是要认识并避免的,这里有一篇国外Gopher整理的《Go 陷阱及常见错误》,可以让你快速定位常见的问题,缩短debug的时间。但现实世界并非一帆风顺,有时让你走运遇到一些并不常见,或者不容易发现的错...
2019-07-19 23:32:38
176
原创 Go 陷阱和常见错误
本文为国外Gopher的常见错误总结,以下为出处:原文:http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/翻译:https://colobu.com/2015/09/07/gotchas-and-common-mistakes-in-go-golangGo是一门简单有趣的语言,但与其他语言类似...
2019-07-19 23:09:42
614
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人