Go语言中文网 为您找到相关结果 519

golang双链表的实现

双链表的实现 基本概念 每一个节点都存储上一个和下一个节点的指针 实现思路 创建一个节点结构体 每个节点都有上节点指针与下节点指针 每个节点都有一个key => value 创建一个链表结构体 链表容量大小属性 链表大小属性 链表锁, 实现并发安全 链表头节点 链表尾节点 实现链表操作方法 添加头部节点操作AppendHead 添加尾部节点操作AppendTail 追加尾部节点操作Append 插入任意节点操作Insert 删除任意节点操作Remove 删除头部节点操作RemoveHead 删除尾部节点操作RemoveTail 获取指定位置的节点Get 搜索任意节点Search 获取链表大小GetSize 打印所有节点操作Print 反转所有节点操作Reverse 总结 学好算法是一个不断积...阅读全文

博文 2019-08-12 11:32:44 百里

深入理解Go-goroutine的实现及Scheduler分析

在学习Go的过程中,最让人惊叹的莫过于goroutine了。但是goroutine是什么,我们用go关键字就可以创建一个goroutine,这么多的goroutine之间,是如何调度的呢? 1. 结构概览 在看Go源码的过程中,遍地可见g、p、m,我们首先就看一下这些关键字的结构及相互之间的关系 1.1. 数据结构 这里我们仅列出来了结构体里面比较关键的一些成员 1.1.1. G(gouroutine) goroutine是运行时的最小执行单元 type g struct { // Stack parameters. // stack describes the actual stack memory: [stack.lo, stack.hi). // stackguard0 is the ...阅读全文

博文 2019-09-01 23:32:48 tyloafer

通用抽奖工具之系统设计

前言 上篇文章《通用抽奖工具之需求分析》我们已经通过一些常见的抽奖场景,得到了符合这些抽奖场景的抽奖工具五要素: 抽奖五要素 要素名称 第一要素 活动 第二要素 场次 第三要素 奖品 第四要素 中奖概率 第五要素 均匀投奖 以及创建一个抽奖活动的5个基本步骤,如下: 活动配置 场次配置 奖品配置 奖品中奖概率配置 奖品投奖配置 上篇文章回顾 《通用抽奖工具之需求分析》 需求已经分析完了,今天我们就来看看这通用抽奖工具具体的设计,分为如下三个部分: DB设计 配置后台设计 接口设计 DB设计 第一要素活动配置的抽奖活动表: -- 通用抽奖工具(万能胶Glue) glue_activity 抽奖活动表 CREATE TABLE `glue_activity` ( `id` int(11) uns...阅读全文

链表中倒数第k个结点

题目描述 输入一个链表,输出该链表中倒数第k个结点。 思路 设置一对快慢指针 2.快指针先走k步,若快指针没走完k步便为null,直接返回null即可 3.快慢指针同时移动,若快指针指向null,直接返回慢指针即可 Java代码实现 public ListNode FindKthToTail(ListNode head,int k) { ListNode fast = head; ListNode slow = head; while(k>0 && fast != null){ fast = fast.next; k--; } if(k>0){ return null; } while(fast != null){ slow = slow.next; fast = fast.next; } ...阅读全文

博文 2020-01-07 19:32:49 youzhihua

Golang数据结构 - 2 - 栈

栈 在上一部分中,我们用Go实现了最常用的数据结构-数组,并实现了数组的添加元素、删除元素、数组遍历、数组排序和数组查找等功能。 在数组中我们可以实现任意位置的添加或删除元素,但是在某些场景中,需要我们对数据的添加或删除进行进一步的限制,于是就有了栈和队列。本章将使用Go来实现栈和栈的一些基本功能。 栈是一种运算受限的线性表,对栈中数据进行操作的时候需要遵循后进先出(LIFO)原则。在栈中对元素进行入栈或出栈操作的一端叫作栈顶,另一端则为栈底。 本章中将基于Golang切片和链表两种实现方法来实现栈。 栈定义 首先定义栈接口,其中包含以下方法: Push(e ...Element):添加若干元素到栈顶 Pop() Element:弹出一个栈顶元素 Peek() Element:返回栈顶元素,...阅读全文

博文 2019-06-19 02:03:00 monigo

【数据结构原理与应用(Golang描述)】② 链表

_ _ _ _ _ _ _ | (_) | | | | | (_) | | | |_ _ __ | | _____ __| | | |_ ___| |_ | | | '_ \| |/ / _ \/ _` | | | / __| __| | | | | | | < __/ (_| | | | \__ \ |_ |_|_|_| |_|_|\_\___|\__,_| |_|_|___/\__| 1.1 原理 链表与数组都非常基础也非常常用,从底层数据结构上看,数组需要一块连续的内存空间来存储数据,而链表则不需要,链表通过指针将一组零散的内存块串联起来使用。 日常中有三种常见的链表结构: 单向链表 双向链表 循环链表 1.2 分析 对于单链表来说,插入和删除操作的时间复杂度为 $O(1)$。双向链表...阅读全文

博文 2020-02-07 13:32:39 vouv

深度解密Go语言之 map

这篇文章主要讲 map 的赋值、删除、查询、扩容的具体执行过程,仍然是从底层的角度展开。结合源码,看完本文一定会彻底明白 map 底层原理。 我要说明的是,这里对 map 的基本用法涉及比较少,我相信可以通过阅读其他入门书籍了解。本文的内容比较深入,但是由于我画了各种图,我相信很容易看懂。 什么是 map 维基百科里这样定义 map: In computer science, an associative array, map, symbol table, or dictionary is an abstract data type composed of a collection of (key, value) pairs, such that each possible key appe...阅读全文

博文 2019-06-03 23:32:41 Stefno

零基础学前端HTML+CSS

课程介绍 网页的本质就是超级文本标记语言HTML,我们这套课程从基础语法入门,讲解了HTML的常用标签,表单,排版等实用技术,同时深入讲解了CSS样式表的使用和如何使用DIV CSS设计网页布局。同时还介绍CSS3.0的新特性,阴影,圆角边框等实用案例。 课时列表 • 课时1:01互联网起源 • 课时2:02HTML概念 • 课时3:03标签 • 课时4:04HTML属性 • 课时5:05HTML固定基本结构 • 课时6:06第一个网页 • 课时7:07工具使用 • 课时8:08标题 • 课时9:09基本标签 • 课时10:10图像IMG标签 • 课时11:11路径概念 • 课时12:12超级链接 •...阅读全文

【数据结构原理与应用(Golang描述)】① 数组

.-. .- .-,.--..-,.--. \ \ / / __ | .-. | .-. | __ \ \ / / .:--.'. | | | | | | |.:--.'. \ \ / / / | \ || | | | | | / | \ | \ \ / / `" __ | || | '-| | '-`" __ | | \ ` / .'.''| || | | | .'.''| | \ / / / | || | | | / / | |_ / / \ \._,\ '|_| |_| \ \._,\ '|`-' / `--' `" `--' `" '..' GolangOnline Go tutorial 1.1 原理 数组(Array)是一种线性表数据结构,通过在内存中申请一组连续的存储空间,用于...阅读全文

HashMap原理摘要

HashMap介绍 HashMap是我们编程时经常会使用到的数据结构。这个数据结构的最大好处是能够帮助我们快速定位在内存中的某一个内容。 例如在Java中,我们快速取得Key所对应的值 //假设 map 是一个HashMap map.get("Key"); 原理 HashMap就是使用哈希函数将一个键映射到一个桶中,这个桶中就可能包含该键对应的值。 哈希函数 HashMap的关键就在于哈希函数的选择。哈希函数就将一个Key映射成一个序列的Index的操作。在Java中,哈希函数将Key这个对象,转换成一个数组的下标。 image.png 因为Key的集合往往远远大于我们保存数据的序列,所以哈希函数的的难度就在于需要将Key生成的这个Index尽量平均的分布在...阅读全文

Golang Iterator 设计

在学习《算法》这本书时,第一章有一个 Bag 的数据结构,它定义为不能删除元素的集合。之前看到一篇文章,说数据结构底层结构其实只有数组与链表,所以在实现 Bag 时想使用数组和链表分别实现。 但是在设计 Bag API 时发现,该如何提供一个通用的遍历方式给第三方调用?因为不像 Java,Golang 并未提供一个迭代接口,只是原生语法上支持对一些容器的遍历,如下所示: // 如果 container 是数组或者 Slice,那么 k => index,v => 数组元素; // 如果 container 是 Map,那么 k => key,v => value; for k, v := range container { } // 对于 channel 也是使用 range 方式,但是返回...阅读全文

博文 2020-04-07 22:32:43 Private

数据结构和算法(Golang实现)(26)查找算法-哈希表

哈希表:散列查找 一、线性查找 我们要通过一个键key来查找相应的值value。有一种最简单的方式,就是将键值对存放在链表里,然后遍历链表来查找是否存在key,存在则更新键对应的值,不存在则将键值对链接到链表上。 这种链表查找,最坏的时间复杂度为:O(n),因为可能遍历到链表最后也没找到。 二、散列查找 有一种算法叫散列查找,也称哈希查找,是一种空间换时间的查找算法,依赖的数据结构称为哈希表或散列表:HashTable。 Hash: 翻译为散列,哈希,主要指压缩映射,它将一个比较大的域空间映射到一个比较小的域空间。 简单的说就是把任意长度的消息压缩到某一固定长度的消息摘要的函数。Hash 算法虽然是一种算法,但更像一种思想,没有一个固定的公式,只要符合这种思想的算法都称 Hash 算法。 散...阅读全文

博文 2020-04-07 16:32:50 陈星星

值拷贝导致使用container/list出现的诡异问题分析

# golang值拷贝导致使用container/list出现的诡异问题分析 ## 先看正确使用list的两种方式 - 使用list.New() ```go package main import ( "container/list" "fmt" ) func main() { lPtr := list.New() lPtr.PushBack(1) for front := lPtr.Front(); front != nil; front = front.Next() { fmt.Println(front.Value) } } ``` 输出 ```go 1 ``` - 使用list.New() ```go package main import ( "container/list" "f...阅读全文

博文 2019-06-23 12:13:44 Nate-Ding

让我们一起啃算法----两数相加

两数相加(Add-Two-Numbers) 这是 LeetCode 的第二题,题目挺常规的,题干如下: 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。示例: 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807来源:力扣 解题思路 这个题目的解法类似我们小时候算两个多位数的加法:从低位开始相加,大于等于10时则取值的个位数,并向前进1。只不过现在多位数用链表来表示了并且最后的值用链表返回了而已。 根据上面...阅读全文

博文 2020-04-20 15:33:51 三斤和他的朋友们

Handler 源码解析(Java 层)

从很早开始就认识到 Handler 了,只不过那时修为尚浅,了解的不够深刻,也没有应用自如。不过随着工作时间的增长,对 Handler 又有了更深层次的认识,于是有了这篇博客,希望尽可能的总结出多的知识点。 Handler 在 Java 层源码主要有 4 个类:Looper、MessageQueue、Message、Handler。我归纳了他们的几个主要知识点: Looper:sThreadLocal、Looper.loop();Message:数据结构、消息缓存池;MessageQueue:enqueueMessage、next、管道等待、同步消息隔离、idleHandler;Handler:send/post、dispatchMessage 消息处理优先级。LooperLooper 数据...阅读全文

博文 2019-04-28 13:58:31 demaxiya

Go 和 PHP 基于两组数计算相加的结果

文链接:go letcode,作者:三斤和他的喵 php 代码个人原创 两数相加(Add-Two-Numbers) 这是 LeetCode 的第二题,题目挺常规的,题干如下: 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。示例: 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807来源:力扣 解题思路 这个题目的解法类似我们小时候算两个多位数的加法:从低位开始相加,大于等于10时则取值的个位数,并向前进1...阅读全文

博文 2020-04-16 20:32:42 hxd_

MySQL数据库入门学习

课程介绍 本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 课程目标 让小白也能够熟练掌握常用的数据库使用技巧,理解数据库的存储结构 适合人群 数据库入门学习者 前端学习者 课时列表 • 课时1: MySQL概要 • 课时2:MySQL在windows下的安装 • 课时3:MySQL在linux下的安装 • 课时4:MySQL在Mac下的安装 • 课时5:MySQL配置 • 课时6:添加和删除数据库(DB) • 课时7:数据类型 • 课时8:添加和删除数据表(table) • 课时9:给数据表添加或者删除列 • 课时10:修改某个数据列的名字或者数据类型 • 课时...阅读全文

golang 源码剖析(3): 内存分配

基本概念 基本策略: 先从操作系统申请一块大内存,以减少系统调用 将申请到的内存按照特定大小预先切成小块,构成一个链表 为对象分配内存时,只需从链表中取出一个大小合适的块使用就好 回收对象内存是,只需将对象放回原链表,以便服用 闲置过多时,会将部分内存归还系统,降低整体开销 内存块 分配器将其管理的内存块分成两种: span: 有多个地址连续的页(page)组成的大块内存 object: 将span按特定大小分成多个小块, 每个小块可存储一个对象 用途上来说,span面向的是内部管理,object面向的是对象的分配. 分配器按页数大小来区分不同大小的span。比如,以页数为单位将span存放到管理数组中,需要的时候就可以以页数为索引进行查找. 在runtime/sizeclasses.go中...阅读全文

博文 2020-03-05 03:32:47 darcyaf

深入理解Go-内存分配

Go语言内置运行时(就是runtime),抛弃了传统的内存分配方式,改为自主管理,最开始是基于tcmalloc,虽然后面改动相对已经很大了。使用自主管理可以实现更好的内存使用模式,比如内存池、预分配等等,从而避免了系统调用所带来的性能问题。 在了解Go的内存分配之前,我们可以看一下内存分配的基本策略,来帮助我们理解Go的内存分配 基本策略: 每次从操作系统申请一大块内存,以减少系统调用 将申请的大块内存按照特定大小预先切成小块,构成链表 为对象分配内存时,从大小合适的链表中提取一块即可 如果对象销毁,则将对象占用的内存,归还到原链表,以便复用 如果限制内存过多,则尝试归还部分给操作系统,降低整体开销 下面我们从源码角度来分析Go的内存分配策略有何异同 准备 在追踪源码之前,我们需要首先了解一...阅读全文

博文 2019-08-15 21:02:36 tyloafer

关于interface

Golang界面全面介绍 界面介绍 如果说够程和信道是转到并发的两大基石,那么接口是转到语言编程中数据类型的关键。在去语言的实际编程中,几乎所有的数据结构都围绕接口展开,接口是转到语言中所有数据结构的核心。 去不是一种典型的面向对象的语言,它在语法上不支持类和继承的概念。 没有继承是否就无法拥有多态行为了呢?答案是否定的,进入语言引入了一种新类型 - 接口,它在效果上实现了类似于C ++的“多态”概念,虽然与C ++的多态在语法上并非完全对等,但至少在最终实现的效果上,它有多态的影子。 虽然去语言没有类的概念,但它支持的数据类型可以定义对应的方法(或多个)。本质上说,所谓的方法(或多个)其实就是函数,只不过与普通函数相比,这类函数是作用在某个数据类型上的,所以在函数签名中,会有个接收器(接收...阅读全文

博文 2019-01-04 13:34:46 陈卧虫

day9 内核的malloc和free

今天看了下内核使用的malloc和free,受益颇丰,现在回想起来以前看golang的runtime中内存的管理部分感觉清晰了很多。linux0.11部分内核的方法名也叫malloc,之后的版本为了和用户程序的区分改成了kmalloc,但分桶思想大概相同 首先明确几个变量和数据结构 free_bucket_desc 这个是当前未使用的桶描述符的链表 _bucket_dir,通描述符目录,每个大小的通描述符的目录,其中size记录了桶的大小,bucket_desc是指向桶描述符的指针。每个bucket_desc都有next指针来组成一个链表 bucket_desc,关键对象,一个描述符被第一次使用的时候,会申请一页地址,并且根据该描述符所在的大小将该页切割成不同的块,每个块初始化的时候前4个字...阅读全文

博文 2018-12-12 14:34:46 柯基是只dog

自己动手用golang实现单向链表

单向链表特点:1、Head 节点 上一个节点为空2、Tail 节点下一个节点为空3、除Tail节点外,每个节点连接到下一个节点package main import ( "fmt" ) type LinkNode struct { Data interface{} Next *LinkNode } type SingleLink struct { head *LinkNode tail *LinkNode size int } // 初始化链表 func InitSingleLink()(*SingleLink){ return &SingleLink{ head:nil, tail:nil, size:0, } } // 获取头部节点 func (sl *SingleLink)GetHea...阅读全文

博文 2019-12-28 15:33:41 筑梦攻城狮

leetcode_21

Golang: 思路:这里可以取巧,拿到两个链表里所有的值,然后直接排序,用一个新的链表存一下并返回即可,但这种解法显然少了些营养。所以我们通过分别对两个链表进行比较,比较时,值小的那个被存进链表,然后该链表向后一格再做比较,直至某一条链表到达尾部。 func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode { var head =&ListNode{Val:0} res:=head for{ if l1==nil{ res.Next=l2 break } if l2==nil { res.Next=l1 break } if l1!=nil&&l2!=nil{ if l1.Val>l2.Val{ test:=ListNode{Val:...阅读全文

博文 2020-01-25 03:32:53 淳属虚构

理解Go 1.13中sync.Pool的设计与实现

Go 1.13版本中有几个比较大的修改,其中之一是sync.Pool修改了部分实现,减小某些极端情况下的性能开销。文中内容来源于笔者读完sync.Pool源代码的思考和总结,内容以Go 1.13中的实现为准,少量内容涉及到Go 1.13之前,如有误区请读者多多指教。 概念 在本文内容开始之前需要理解几个在Go runtime中的概念,以便于更好的理解sync.Pool中一些实现。 goroutine抢占 Go中调度器是GMP模型,简单理解G就是goroutine;M可以类比内核线程,是执行G的地方;P是调度G以及为G的执行准备所需资源。一般情况下,P的数量CPU的可用核心数,也可由runtime.GOMAXPROCS指定。本文的重点并非goroutine调度器,在此不做详细解释,感兴趣可以翻...阅读全文

博文 2020-03-07 22:32:42 shaoyuan1943

defer 链表如何被遍历执行

去年开始写文章的第一篇就是关于 defer,名字比较文艺:《Golang 之轻松化解 defer 的温柔陷阱》,还被吐槽了。因为这篇文章,到《Go 夜读》讲了一期。不过当时纯粹是应用层面的,也还没有跳进 Go 源码这个大坑,文章看着比较清新,也没有大段的源码解析。 自从听了曹大在《Go 夜读》分享的 Go 汇编,以及研读了阿波张的 Go 调度器源码分析的文章后,各种源码、汇编满天飞…… 上次欧神写了一篇《Go GC 20 问》,全文也没有一行源码,整体读下来很畅快。今天这篇也来尝试一下这种写法,不过,我们先从一个小的主题开始:defer 链表是如何被遍历并执行的。 关于 defer 的源码分析文章,网络上也有很多。不过,很少有能完全说明白这个话题的,除了阿波张的。 我们知道,为了在退出函数前...阅读全文

博文 2020-05-02 18:57:22 qcrao

GoLang 学习笔记 - 运算符

运算符用于在程序运行时执行数学或逻辑运算。 Go 语言内置的运算符有: 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 其他运算符 算术运算符 下表列出了所有Go语言的算术运算符。假定 A 值为 15,B 值为 5 。 运算符 描述 实例 + 相加 A + B 输出结果 20 - 相减 A - B 输出结果 10 * 相乘 A * B 输出结果 75 / 相除 B / A 输出结果 3 % 求余 B % A 输出结果 0 ++ 自增 A++ 输出结果 16 -- 自减 A-- 输出结果 14 GoLang 中 ++ 和 -- 操作只可以当成一个语句来使用,不可以作为表达式。这样可以避免很多问题。 a ++ //允许 b = a++ //不允许 即便如此,自增和自减仍然是一种很不规范...阅读全文

博文 2019-07-20 21:32:37 凉丶心园

小白也能够熟练掌握常用的数据库使用技巧

课程介绍 本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 课程目标 让小白也能够熟练掌握常用的数据库使用技巧,理解数据库的存储结构 适合人群 数据库入门学习者 前端学习者 课时列表 • 课时1: MySQL概要 • 课时2:MySQL在windows下的安装 • 课时3:MySQL在linux下的安装 • 课时4:MySQL在Mac下的安装 • 课时5:MySQL配置 • 课时6:添加和删除数据库(DB) • 课时7:数据类型 • 课时8:添加和删除数据表(table) • 课时9:给数据表添加或者删除列 • 课时10:修改某个数据列的名字或者数据类型 • 课时...阅读全文

算法图解阅读笔记-选择排序

数组与链表 数组是连续内存的应用方式,它的特点就是所有的单元的内存地址都是连续的,当需要扩展而初始化的内存不足够的时候,就需要重新申请内存。 链表是已上一个元素指向来完成存储的,它在内存的存储是分散的,无论是添加还是删除较数组的最大优势就是都不需要整体动,只需要上一个元素的指向调整就好,缺点就是无法直接通过计算获得某个元素,如果要在链表中查找某一个元素,就需要遍历整个链表(最差情况) 选择排序 遍历所有元素,挑出最小的元素放在结果集中并删除该元素,直到要排序的数据集中没有元素为止。 golang版本 package main import "fmt" func main() { info := []int{12, 3, 54, 6, 6777, 2342, 234, 55, 6, 6777,...阅读全文

博文 2018-10-22 16:35:02 zhaoxi_yu

第十天:golang学习笔记之container

★container | heap堆操作, list双向链表,ring环形链表 现在网上的算法题,很少有可以用golang作答的,不过看看别人造的轮子还是挺有意思的 container本身并不是包,但目录下包括三个子包:heap,list,ring heap 包含一个Interface接口,接口定义了Push(x interface{}),Pop() interface{} ,并包含了sort.Interface接口。 这里的堆是小顶堆 heap并没有可用的实现,但在test中找到一个: // An IntHeap is a min-heap of ints. type IntHeap []int func (h IntHeap) Len() int { return len(h) } fu...阅读全文

博文 2019-12-27 21:32:41 Macmillan_

GO语言学习笔记(四)GO语言控制语句

一、小程序要求:输出100以内能被2整除的数代码如下: package main import "fmt" func main() { var max int = 100 number := 2 for i := 1; i <= max; i++ { if i%number == 0 { fmt.Println(i) } } } 运行以及输出如下:执行:go run test1.go输出结果:2468101214161820......9092949698100 包含的知识点:1)变量Go语言包含的值类型:字符串、整型、浮点型、布尔型等 变量的声明和赋值的四种写法: ⑴var 变量 = "字符串"解释:使用var关键字声明一个变量并赋值 ⑵var 变量a, 变量b int = 数字1, 数字...阅读全文

博文 2019-01-28 17:35:13 Mr大表哥

Golang筑基 ——运算符

golang的运算符同C/C++一样,共有如下几种 算术运算符 下表列出了所有Go语言的算术运算符。假定 A 值为 10,B 值为 20。 图片.png 注意: 自增(++)和自减(--)不同于C/C++,a++和++a在golang中是没有区别的,同理,a--和--a也是如此。我觉得这也是golang方便之处,去除一些没必要功能设计,让语言本身更便捷。 关系运算符 下表列出了所有Go语言的关系运算符。假定 A 值为 10,B 值为 20。 图片.png 逻辑运算符 下表列出了所有Go语言的逻辑运算符。假定 A 值为 True,B 值为 False。 图片.png 位运算符 位运算符对整数在内存中的二进制位进行操作。 下表列出了位运算符 &, |, 和 ^ 的计算: 图片.png 赋值运算符...阅读全文

博文 2020-04-13 21:32:49 技术修仙

Golang 数据结构到底是怎么回事?gdb调一调?

“ 不仅限于语法,使用gdb,dlv工具更深层的剖析golang的数据结构” Golang数据结构 变量:有意义的一个数据块。 变量名:一个有意义的数据块的名字。 为什么特意会有这个章节? golang本质是全局按照值传递的,也就是copy值,那么你必须知道你的内存对象是包含哪些内容,才能清楚掌握你在copy值的时候复制了哪些东西,这个很重要,第一部分的正文内容从这里开始。具体如下类型: num bool string array slice map channel interface 这些结构实际在地址空间栈是什么形式的实现?这里直接看地址空间的内容,以下都是以这个例子进行分析: package main func main () { var n int64 = 11 var b bool...阅读全文

博文 2020-04-12 19:32:44 奇伢云存储

Golang map

前些天看了DAVE CHENEY大神的直播。里面讲到了go的map实现。做个笔记 (我用的是go1.13 貌似大神直播时候用的是还没发布的1.15 所以本文中的代码都是1.13中的。与1.15略有差异) compile time rewriting: 左边对map的操作实际上被编译成了右边的调用 v := m["key"] -> runtime.mapaccess1(m, "key", &v) v, ok := m["key"] -> runtime.mapaccess2(m, "key", &v, &ok) m["key"] = 9001 -> runtime.mapinsert(m, "key", 9001) delete(m, "key") -> runtime.mapdelete(m...阅读全文

博文 2020-05-12 11:35:48 郭老汉

Go 1.13中 sync.Pool 是如何优化的?

Go 1.13持续对 sync.Pool进行了改进,这里我们有两个简单的灵魂拷问: 1、做了哪些改进?2、如何做的改进? 首先回答第一个问题: 对STW暂停时间做了优化, 避免大的sync.Pool严重影响STW时间 第二个优化是GC时入股对sync.Pool进行回收,不会一次将池化对象全部回收,这就避免了sync.Pool释放对象和重建对象导致的性能尖刺,造福于sync.Pool重度用户。 第三个就是对性能的优化。 对以上的改进主要是两次提交:: sync: use lock-free structure for Pool stealing和sync: use lock-free structure for Pool stealing。 两次提交都不同程度的对性能有所提升,依据不同的场景,...阅读全文

博文 2019-11-10 00:02:22 smallnest

删除排序链表中的重复元素

题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 思路 1.这道题的核心思想是跳过值重复的结点。 2.可以设置一个哑结点,防止链表中全部的值都是重复的。 3.可以设置两个值,分别用于标记当前结点是否重复。 4.整体流程就是: 进入循环 保存当前结点 循环跳过重复结点 判断当前结点是否移动过,若移动过,需要跳过 Java代码实现 class Solution { public int findMin(int[] array) { if(array.length == 0) return 0; int left = 0; int right = array.len...阅读全文

博文 2020-03-17 05:32:49 youzhihua

golang中defer的执行过程是怎样的?

在同一个goroutine中: 多个defer的调用栈原理是什么?defer函数是如何调用的? 为了探究其中的奥秘我准备了如下代码: package main import "fmt" func main() { xx() } func xx() { defer aaa(100, "hello aaa") defer bbb("hello bbb") return } func aaa(x int, arg string) { fmt.Println(x, arg) } func bbb(arg string) { fmt.Println(arg) } 输出:bbb100 hello aaa从输出结果看很像栈的数据结构特性:后进先出(LIFO)。 首先从汇编入手去查看xx()函数的执行过程,...阅读全文

博文 2019-07-19 03:02:37 XITEHIP

c++对象模型

使用c++有些年头了,有一本深度搜索c++对象模型的书写的很赞,很经典。本文是本书的读书笔记。 #### 关于对象 ##### 加上封装后的布局成本 c语言中如下声明一个结构体 ``` typedef struct point3d{ float x; float y; float z;}Point3d; ``` struct point3d 转化为class Point3d之后 ``` class Point3d { public: Point3d(float x = 0.0f, float y = 0.0f; float z = 0.0f) :_x(x),_y(y),_z(z){} private: float _x,_y,_y; } ``` 封装带来的布局成本增加了多少?实际是没有增加布...阅读全文

博文 2019-11-06 09:53:55 bytemode

面试必备!就凭借着这份Java 高频面试题,我拿下了阿里,字节的offer!

List 1. 为什么 arraylist 不安全? 我们查看源码发现 arraylist 的 CRUD 操作,并没有涉及到锁之类的东西。底层是数组,初始大小为 10。插入时会判断数组容量是否足够,不够的话会进行扩容。所谓扩容就是新建一个新的数组,然后将老的数据里面的元素复制到新的数组里面(所以增加较慢)。 2. CopyOnWriteArrayList 有什么特点? 它是 List 接口的一个实现类,在 java.util.concurrent(简称 JUC,后面我全部改成 juc,大家注意下)。 内部持有一个 ReentrantLock lock = new ReentrantLock(); 对于增删改操作都是先加锁再释放锁,线程安全。并且锁只有一把,而读操作不需要获得锁,支持并发。 读...阅读全文

博文 2020-06-02 17:32:50 前程有光

栈的性质 只允许一段插入和删除数据 先进后出 栈可以用链表实现也可以用数组实现 操作时间复杂度 入栈和出栈时间复杂度都为O(1) (因为只涉及操作栈顶部的第一个元素) 涉及到可扩容的栈的时候,因为栈满了要扩容,数据迁移时间复杂度为O(n) 但是前n次插入的时间复杂度都是O(1) 进行均摊后, 时间复杂度为O(2) = O(1) 所以不管是否扩容 时间复杂度都是O(1) 曾经(去年) 面试的时候有个面试官曾过我, 你知道栈吗? 两个栈怎么组成一个先进先出的队列, 可是我太年轻那,bb半天也没有让人家满意。 栈的golang代码实现 type ArrayStack struct { data []interface{} top int } func NewArrayStack() *ArrayS...阅读全文

博文 2019-06-26 13:32:40 五知小白羊

redis 基础数据结构

1 前言 Redis的5种数据类型(String,Hash,List,Set,Sorted Set),每种数据类型都提供了最少两种内部的编码格式,而且每个数据类型内部编码方式的选择对用户是完全透明的,Redis会根据数据量自适应地选择较优化的内部编码格式。 查看某个键的内部编码格式,使用命令object encoding keyname Reids的每个键值内部都是使用叫redisObject这个C语言结构体保存的,代码如下: type:表示键值的数据类型,也就是那5种基本数据类型。 encoding:表示键值的内部编码方式, #define OBJ_ENCODING_RAW 0 /* Raw representation */ #define OBJ_ENCODING_INT 1 /* E...阅读全文

博文 2019-12-17 18:32:48 LZhan

图解Go语言内存分配

载自图解Go语言内存分配 Go语言内置运行时(就是runtime),抛弃了传统的内存分配方式,改为自主管理。这样可以自主地实现更好的内存使用模式,比如内存池、预分配等等。这样,不会每次内存分配都需要进行系统调用。 Golang运行时的内存分配算法主要源自 Google 为 C 语言开发的TCMalloc算法,全称Thread-Caching Malloc。核心思想就是把内存分为多级管理,从而降低锁的粒度。它将可用的堆内存采用二级分配的方式进行管理:每个线程都会自行维护一个独立的内存池,进行内存分配时优先从该内存池中分配,当内存池不足时才会向全局内存池申请,以避免不同线程对全局内存池的频繁竞争。 基础概念 Go在程序启动的时候,会先向操作系统申请一块内存(注意这时还只是一段虚拟的地址空间,并不...阅读全文

博文 2020-03-02 01:32:44 网管同学

12 - go简单实现hashmap

注意:还没有解决hash冲突和hash倾斜的问题。 package main import "fmt" var nowCapacity = 10 //当前容量 const maxCapacity = 100 //最大容量 const loadFactor = 0.75 //负载因子(决定扩容因数) type Entry struct { k string //key v interface{} //值 next *Entry } type HashMap struct { size int //map的大小 bucket []Entry //存放数据的桶,为slice } //创建一个CreateHashMap的函数,返回一个HashMap指针 func CreateHashMap() *H...阅读全文

博文 2020-05-12 19:32:47 欢乐毅城

golang container/ring源码解读

最近在看gokit的熔断器源码的时候看到了内部有使用到 container/ring 的这个数据结构;虽然大体知道这个数据结构提供的一个常用API,也知道该怎么用;但是不知道内部具体是怎么实现的。所以就看了内部的源码实现;在这里分享出来,有不对的地方欢迎大家指正。 在正式开始讲解源码之前先铺垫几个基础的数据结构知识 1、单链表 节点内部会存储当前节点的值跟下一个节点的指针,单链表的访问只能向前推进访问不能后退 单链表 2、单向循环链表 单向循环链表的尾节点的后继节点指向了链表的头结点;其他跟单链表完全相同 单向循环链表 3、双向链表 双向链表每个节点内部存储了当前节点的值,后继节点的指针,前驱节点的指针 双向链表 4、双向循环链表 双向循环链表的头结点的前驱节点为链表的尾节点指针,而尾结点的...阅读全文

博文 2020-05-28 21:32:46 airun

通用抽奖工具之系统设计

前言 上篇文章《通用抽奖工具之需求分析》我们已经通过一些常见的抽奖场景,得到了符合这些抽奖场景的抽奖工具五要素: 抽奖五要素 要素名称 第一要素 活动 第二要素 场次 第三要素 奖品 第四要素 中奖概率 第五要素 均匀投奖 以及创建一个抽奖活动的5个基本步骤,如下: 活动配置 场次配置 奖品配置 奖品中奖概率配置 奖品投奖配置 上篇文章回顾 《通用抽奖工具之需求分析》 需求已经分析完了,今天我们就来看看这通用抽奖工具具体的设计,分为如下三个部分: DB设计 配置后台设计 接口设计 DB设计 第一要素活动配置的抽奖活动表: -- 通用抽奖工具(万能胶Glue) glue_activity 抽奖活动表 CREATE TABLE `glue_activity` ( `id` int(11) uns...阅读全文

博文 2020-01-02 10:34:20 TIGERB

面试:从尾到头打印链表

题目:从尾到头打印链表 要求:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 示例: ` 输入:head = [1,3,2] 输出:[2,3,1] ` 限制: 0 <= 链表长度="" <="10000 题解1:递归法 因为是从尾到头返回每一个节点的值,所以很容易想到如果从最后的节点将值放入数组中,然后再往前逐步将数据放入数组,最后回到头节点返回即可,可以想到递归就能轻松做到,只要注意递归函数的结束条件即可。 /** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ func reversePrint(head *ListNode...阅读全文

博文 2020-02-28 16:34:31 若鱼治水

让我们一起啃算法----合并两个有序链表

合并两个有序链表(Merge-Two-Sorted-Lists) 题干如下: 将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4来源:力扣 这个题目和 两数相加 相似,都是考察对链表的操作。其实具体实现方式也差不多啦。 解题思路 根据题干我们知道,给定的两个链表是有序的。假设 l1 指向其中一个链表的头部,l2 指向另一个链表的头部,并初始化 head 和 current,使它们指向一个默认的节点。我们比较 l1 指向节点的值 V(l1) 与 l2 指向节点的值 V(l2) 的大小,如果 V(l1) 的值小于 V(l2) 的值,则使 current.next 指向...阅读全文

博文 2020-05-05 16:32:40 三斤和他的朋友们

C++ 虚函数表剖析

一、概述 为了实现C++的多态,C++使用了一种动态绑定的技术。这个技术的核心是虚函数表(下文简称虚表)。本文介绍虚函数表是如何实现动态绑定的。 二、类的虚表 每个包含了虚函数的类都包含一个虚表。 我们知道,当一个类(A)继承另一个类(B)时,类A会继承类B的函数的调用权。所以如果一个基类包含了虚函数,那么其继承类也可调用这些虚函数,换句话说,一个类继承了包含虚函数的基类,那么这个类也拥有自己的虚表。 我们来看以下的代码。类A包含虚函数vfunc1,vfunc2,由于类A包含虚函数,故类A拥有一个虚表。 class A { public: virtual void vfunc1(); virtual void vfunc2(); void func1(); void func2(); pri...阅读全文

博文 2019-08-23 17:21:31 qq470603823

图解Go语言内存分配

Go语言内置运行时(就是runtime),抛弃了传统的内存分配方式,改为自主管理。这样可以自主地实现更好的内存使用模式,比如内存池、预分配等等。这样,不会每次内存分配都需要进行系统调用。Golang运行时的内存分配算法主要源自 Google 为 C 语言开发的 TCMalloc算法,全称 Thread-CachingMalloc。核心思想就是把内存分为多级管理,从而降低锁的粒度。它将可用的堆内存采用二级分配的方式进行管理:每个线程都会自行维护一个独立的内存池,进行内存分配时优先从该内存池中分配,当内存池不足时才会向全局内存池申请,以避免不同线程对全局内存池的频繁竞争。为了更好的阅读体验,手动贴上文章目录: 基础概念Go在程序启动的时候,会先向操作系统申请一块内存(注意这时还只是一段虚拟的地址...阅读全文

博文 2019-03-14 01:34:40 ddu_sw

两个链表的第一个公共结点

题目描述 输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的) 思路 假设两个链表的第一个公共结点为c。 链表1可以表示为a+c,链表2可以表示为b+c。 可以通过a+c+b+c = b+c+a+c来快速求出c的值,若没有公共结点,那c便是null。 可以根据下图,简单理解下这个过程。 Java代码实现 public class Solution { public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { ListNode p1 = pHead1; ListNode p2 = pHead2; while(p1 != p2){ p...阅读全文

博文 2020-02-27 12:32:41 youzhihua

golang 源码剖析(7): 延迟defer

简介 延迟调用(defer)的优势是: 即使函数执行出错,依然能保证回收资源等操作得以执行 可以在变量的定义处加入defer,代码结构上避免忘记做某些数据的回收 劣势: 性能上会会比直接调用慢一些 如果在defer中释放,相对来说只会在函数执行结束的时候才会调用,变量生命周期会变长. 定义 编写以下程序, dump出汇编. defer主要调用了一下两个函数func deferprocStack(d *_defer)和func deferreturn(arg0 uintptr) package main import ( "fmt" ) func main() { defer fmt.Println(0x11) } (base) ➜ readsrc go tool objdump -s "ma...阅读全文

博文 2020-03-08 17:32:42 darcyaf