编程语言底层之数据结构

课程简介

本课程从开发人员需要了解的基础数据结构出发,带着这些基础知识去学习一门编程语言是怎么实现的(内含视频演示),并且思考为什么这么实现,反过来再系统完善知识体系,并运用到实际工作中。通过这门课的学习将体验思考的过程,以便后面更加深入的了解学习其他开发语言知识。

相关联的系列达人课:《编程语言底层之函数执行》和《编程语言底层之系统和并发》。

作者介绍

李永京,从事互联网后端系统开发,擅长高并发分布式系统,熟悉 Go、C、C#、Python 等语言。架构龙珠直播平台基础框架,开发过道具、任务、红包、直播、聊天、调度系统等。曾任职阿里妈妈,开发过移动广告 DMP、DSP、广告数据人群分析等。个人博客 积分排名前 30,300万 PV。

课程内容

导读:带着研究来学习

如何学习

大家是否有这样一个困惑:同时学习一样东西,结果我写的代码可能没有其他人写的好,其他人写的那种代码我甚至都没有见过。这是为什么呢?因为很多技巧跟语言无关,其实是和原理有关,了解原理的话不管用什么语言都可以实现。因为现在多种语言混合编程是很正常的一件事。

经常有这样的疑问,有些时候看官方文档,看了以后云山雾罩的不知道文档说的什么意思,好像理解了但又好像不明白。

例如有两种不同的数据结构,文档中说了某种数据结构占用内存小,复制的时候数据小。但是我们仔细想下可能不对,既然一种比另外一种好,干嘛不把两种合并了。如果不合并,他们肯定有不同的适用场景,这种事情很多文档不会提。

所以学习语言的时候光看文档是没有用的,因为根本没有办法深入到细节里面,我们需要一个手段去逆向推导这件事情,需要搞清楚文档说的每一句话到底是什么意思,哪些东西是文档没有表达清楚的,哪些东西是需要注意的,这个非常重要,否则还是不知其所以然。

本系列以及将来的系列让读者明白我们利用这种方法去推导某种细节,做一件事用什么样的方法是很重要的。说起来学习也是一件很复杂的事情,若开始没学好,到开发的时候也写不出很优化的代码,长时间下来,自己也慢慢对编程失去了兴趣。

新的语言多半是为了解决一些老的语言的弊端,本课程我们不是去学习一门语言,而是学习用一些技巧逆向推导一些原理,跟学习某种语言无关,只是选择了 Go 语言作为案例,如果工作上没有使用 Go,使用 Java、C#、Python 等语言也没有太大关系,可以把 Go 语言当作伪码来阅读,然后把这些原理和推导过程带到工作的语言中做对比,会发现这些底层实现去学习新的语言也是很轻松的事情。

抽象的数据类型

我们站在汇编的角度基本上没有数据结构一说,只有纯数字。要么传地址,地址也是一些整数;要么就是把内存中一些字节从寄存器搬到内存或者从内存搬到寄存器或者做一些简单的数学运算。所以站在汇编的角度事情很简单、很直接。这样的好处就是我们可以抛开很复杂的抽象理论去研究计算机本质是怎样工作的。

那么带来的问题是在我们编程时不可能全部用数字来表达所有的东西,需要用抽象概念来表达这些数字。从本质上来说,不管是字符串还是对象还是类型,都是由一些数字构成的一些数学模型。当我们学习这些抽象概念的时候,一定要有一种途径把它还原成原始的状态。

这个系列我们就来研究一些基本类型以外的复合类型。从字面上来说复合类型就是由多个基本类型构成的。我们管这种由多个独立内存块构成的数据结构通常称之为复合类型。当然在不同的语言里对于复合类型的定义不太一样。比如说 C 语言里默认没有字符串的概念,它是以某个结束符标记的字节数组称之为字符串。

我们想象一下整个内存看做成超大号的字节数组,其中地址就是数组的序号,所以说不管类型多么复杂,归根到底它是在数组之上进行抽象的。所谓的虚拟地址空间就是看做成字节数组,在这字节数组之上通过一些关联逻辑把它构想成一个复杂的数据结构。

我们还是最终需要把数据结构最终还原成具体的内存布局。学习 C 语言时都知道研究一个对象的时候首先需要知道它的内存布局结构,理解内存布局结构关系到代码优化,选择什么样的算法。因为这样才知道当传递一个对象的时候究竟复制的是什么东西,如果是简单的整数就把整数复制过去;如果是复合结构是复制一块呢还是把两块全部复制?这是有很大差别的,如果是由指针指向的,是复制本身还是连指针指向的内存块一起复制?如果只复制本身,那么是不是有另外的指针也指向那块内存块,那么这时候就会存在数据竞争问题。所以对于一个复合类型来说,我们必须要知道它究竟在内存中是什么样的?它是怎么构成的?这个对于我们选择什么样的数据结构或者进行什么样的优化有直接的关系。

有什么收获

我们常见的复合结构有很多,从简单的学起,如字符串、数组、字典、结构体。

本课程将带领读者一步一步去探究这些结构的实现原理,了解下面一些问题:

  • 为什么所有语言把字符串实现为不可变类型?
  • 不同语言对拼接字符串有什么不同实现方式?
  • 怎么样优化字符串转换性能?
  • 为什么 Go 语言用切片来管理数组,而不是动态数组或数组指针?
  • 怎么基于数组实现数据结构栈、队列?
  • 字典基本实现方式有哪些?
  • 如何改进字典的链表实现性能?
  • 字典如何性能调优?清理方法真的有效么?
  • 字典有哪些数据竞争问题?
  • 结构体内存是怎么布局的?
第01课:字符串
第02课:数组
第03课:基于数组实现数据结构
第04课:字典
第05课:结构体

阅读全文: http://gitbook.cn/gitchat/column/5a38da12c5896e6e1cf17830

你可能感兴趣的:(编程语言底层之数据结构)