04 2020 档案
摘要:Trait是PHP 5.4引入的新概念,看上去既像类又像接口,其实都不是,Trait可以看做类的部分实现,可以混入一个或多个现有的PHP类中,其作用有两个:表明类可以做什么;提供模块化实现。Trait是一种代码复用技术,为PHP的单继承限制提供了一套灵活的代码复用机制。 为什么使用Trait PHP
阅读全文
摘要:善用接口 接口不是现代PHP的新特性,但是非常重要,学会使用接口,可以极大提升我们的编程能力,所以在日常开发中应该尽可能多地使用接口。 接口是两个PHP对象之间的契约(Contract),Laravel底层就直接将接口放在Contracts目录中: 接口将我们的代码和依赖解耦了,而且允许我们的代码依
阅读全文
摘要:强推一个学设计模式的网站: Refactoring Guru (https://refactoringguru.cn) 这是国外的一个网站,建立的初衷,是帮助开发者以更为简单便捷的方式,迅速掌握各个设计模式的学习。 每个设计模式都对应配有一篇图文并茂的文章,让开发者可以很轻松的搞懂每个设计模式的具体
阅读全文
摘要:堆和堆的构建 什么是堆 堆是一种特殊的二叉树,具备以下特性: 堆是一个完全二叉树 每个节点的值都必须大于等于(或小于等于)其左右孩子节点的值 如果每个节点的值都大于等于左右孩子节点的值,这样的堆叫大顶堆;如果每个节点的值都小于等于左右孩子节点的值,这样的堆叫小顶堆。 上图中,左侧的堆是大顶堆,右侧的
阅读全文
摘要:前面几篇分享中我们陆续介绍了平衡二叉树的定义、实现原理、构建过程演示以及对应的实现代码,我们提到平衡二叉树是最理想的二叉排序树,性能最好,也最稳定,但是缺点是维护成本高,需要在插入和删除节点时维护新树的平衡性,所以工程实践中,我们倾向于使用另一种二叉排序树 —— 红黑树,什么是红黑树?红黑树的性能如
阅读全文
摘要:1、什么是命名空间 如果你只需要知道现代PHP特性中的一个,那就应该是命名空间。命名空间在PHP5.3.0中引入,其作用是按照一种虚拟的层次结构组织PHP代码,这种层次结构类似操作系统中文件系统的目录结构。命名空间是现代PHP组件生态的基础,现代的PHP组件框架代码都是放在各自全局唯一的厂商命名空间
阅读全文
摘要:引子 上一篇我们介绍了二叉排序树,并且提到理想情况下,二叉排序树的插入、删除、查找时间复杂度都是 ,非常高效,而且它是一种动态的数据结构,插入删除性能合查找一样好,不像之前提到的二分查找,虽然查找性能也是 ,但是需要先对线性表进行排序,二排序的最好时间复杂度也是 ,所以二分查找不适合动态结构的排序。
阅读全文
摘要:为什么要引入二叉排序树 我们前面已经介绍了很多数据结构,比如数组、链表、散列表等,数组查找性能高,但是插入、删除性能差,链表插入、删除性能高,但查找性能差,在不考虑散列冲突的话,散列表的插入、删除、查找性能都很高,但是前提是没有散列冲突,此外,散列表存储的数据是无序的,散列表的扩容非常麻烦,涉及到散
阅读全文
摘要:二叉树的定义及其特性 树的相关概念 树这种数据结构模拟了自然界中树的概念,自然界中的树有根、叶子、枝干,数据结构中的树也是如此,只不过是倒过来的: 其中的每个元素叫做节点。树的顶点(没有父元素的节点)叫根节点,如 E;每个分支的末端节点(没有子元素的节点)叫叶子节点,如 G、H、I、J、K、L;用来
阅读全文
摘要:PHP 提供的字符串匹配函数多是单模式匹配,因此大多通过 KMP算法 实现,我们以 函数为例,简单对底层实现源码进行剖析。 是 PHP 标准库提供的函数,所以可以在 中找到其定义: 阅读这段源码可知,真正的匹配逻辑通过 函数实现,我们继续溯源,可以追踪到 文件中的 函数定义,核心匹配逻辑在这里: 如
阅读全文
摘要:今天开始,我们将花三篇文章的篇幅由浅及深地介绍几个字符串匹配算法,首先从最简单的字符串匹配算法 —— BF 算法说起,BF 是 Brute Force 的缩写,中文译作暴力匹配算法,也叫朴素匹配算法。 BF算法(暴力匹配算法) BF 算法的原理很简单,在继续介绍之前,我们先引入两个术语: 主串和模式
阅读全文
摘要:数组是 PHP 中非常强大、灵活的一种数据类型,和 Java、C 等静态语言不同,我们在初始化 PHP 数组的时候不必指定大小和存储数据的类型,在赋值的时候可以通过数字索引,也可以通过字符串索引的方式: 基于 PHP 数组的强大特性,我们可以轻易实现更加复杂的数据结构,比如栈、队列、列表、集合、字典
阅读全文
摘要:散列表 散列表(HashTable,也叫哈希表),是根据键(Key)直接访问在内存存储位置的数据结构。 其实现原理是: 通过散列函数(也叫哈希函数)将元素的键映射为数组下标(转化后的值叫做散列值或哈希值),然后在对应下标位置存储记录值。当我们按照键值查询元素时,就是用同样的散列函数,将键值转化数组下
阅读全文
摘要:插入查找 $container[ $middle ]) { $lower = $middle + 1; } else { return $middle; } } return false; } // + // | 方案测试 | php || PHPStorm 右键 Run // + echo ins
阅读全文
摘要:前面我们提到的二分查找适用于有序线性表的查找,此外针对二分查找还有升级版的插值查找,以及利用斐波那契原理进行查找的斐波那契查找,在后面的随笔里会补充对应的实现,一般我们使用二分查找就可以了。 我们也提到二分查找不适用于高速增长的海量数据,因为维护这个排序非常麻烦,所以我们引出索引这种数据结构。 索引
阅读全文
摘要:二分查找的引入 在介绍二分查找之前,对于基于数字索引的数组元素的查找,我们可能第一反应都是遍历这个数组,直到给定数组元素值和待查找的值相等时,返回索引值并退出,否则一直遍历到最后一个元素,如果还是没有找到则返回 1,这样的查找虽然是简单粗暴了点,但是对于规模不大的数据集,也是没什么问题的,不过很明显
阅读全文
摘要:线性表(即线性数据结构,如数组和链表)的常规排序算法,包括冒泡、插入、选择、归并和快排,其中综合性能最好的就是快排(快速排序),所以快排在工程实践中也有大量的应用,比如很多编程语言都提供了排序函数,而这些排序函数基本都是基于快速排序实现的,比如 PHP 的数组排序函数 sort 就是如此。 今天我们
阅读全文
摘要:快速排序 实现原理 归并排序算法虽好,但是不是原地排序算法,需要消耗额外的内存空间,今天我们要介绍的是常规排序里综合排名最高的排序算法:快速排序,江湖人称「快排」。 快排的核心思想是这样的: 如果要排序数组中下标从 p 到 r 之间的一组数据,我们选择 p 到 r 之间的任意一个数据作为 pivot
阅读全文
摘要:归并排序 实现原理 所谓归并排序,指的是如果要排序一个数组,我们先把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就都有序了。 归并排序使用了分治思想,分治,顾名思义,就是分而治之,将一个大问题分解成小的子问题来解决。说到这里,可能你就能联想起我们之前
阅读全文
摘要:选择排序 实现原理 选择排序算法的实现思路有点类似插入排序,也分已排序区间和未排序区间。但是选择排序每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。图示如下: 同样,可以在 VisuAlgo 上看动态图:https://visualgo.net/zh/sorting。 示例代码 选择排
阅读全文
摘要:插入排序 实现原理 插入排序的原理是:我们将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序区间中的元素,在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一直有序。重复这个过程,直到未排序区间中元素为空,算
阅读全文
摘要:常见基于选择的排序算法有冒泡排序、插入排序、选择排序、归并排序和快速排序,我们在选择排序算法的时候,通常会根据以下几个维度来考虑: 1. 时间复杂度 2. 空间复杂度(对内存空间的消耗) 3. 算法的稳定性(如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变) 我们首先
阅读全文
摘要:介绍完数组和链表,以及两个特殊的线性结构栈和队列后,已经算是迈入了数据结构的门了,后面很多其他更复杂的数据结构都会基于数组和链表来实现,比如散列表、树、图等,有些甚至需要结合数组和链表来实现,在继续介绍后续复杂的数据结构之前,我们穿插进来一些常见的排序算法和查找算法,在系统介绍这些算法之前,我们先来
阅读全文
摘要:另一种跟栈很相似的数据结构 —— 队列,和栈一样,队列也是一中特殊的线性表结构,只不过队列是在一端插入,另一端删除,就跟我们平常排队一样的道理,从队尾入队,在队头出去,所以队列的特性是先入先出(FIFO),允许插入的一端叫队尾,允许删除的一端叫队头。 一张图可以形象的体现两者的差别: 队列 和栈一样
阅读全文
摘要:数组和链表,从逻辑角度来说,它们都是线性结构(就是排成一条线的结构,只有前后两个方向,非线性结构包括树、图等,后面会讲到),从存储角度来说,一个是顺序存储,一个是链式存储,各有利弊,数组需要预先申请连续内存,超出限制会溢出,但是对明确知道规模的小型数据集而言,使用数组会更加高效,随机访问的特性也更加
阅读全文
摘要:链表,和数组不同,链表并不需要一块连续的内存空间,它通过“指针”将一组零散的内存块串联起来使用,如图所示: 单链表 链表有多种类型,最简单的是单链表,单链表是最原生的链表,其结构如图所示: 单链表中有两个节点比较特殊,分别是第一个结点和最后一个结点。我们通常把第一个结点叫作头结点,把最后一个结点叫作
阅读全文
摘要:一、基础 二、创建表 三、修改表 四、插入 五、更新 六、删除 七、查询 八、排序 九、过滤 十、通配符 十一、计算字段 十二、函数 十三、分组 十四、子查询 十五、连接 十六、组合查询 十七、视图 十八、存储过程 十九、游标 二十、触发器 二十一、事务管理 二十二、字符集 二十三、权限管理 参考资
阅读全文
摘要:一、事务 概念 ACID AUTOCOMMIT 二、并发一致性问题 丢失修改 读脏数据 不可重复读 幻影读 三、封锁 封锁粒度 封锁类型 封锁协议 MySQL 隐式与显示锁定 四、隔离级别 未提交读(READ UNCOMMITTED) 提交读(READ COMMITTED) 可重复读(REPEATA
阅读全文
摘要:什么是Docker Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。 容器是完全使用沙箱机制,相互之间不会有任
阅读全文
摘要:集中式与分布式 中心服务器 工作流 分支实现 冲突 Fast forward 储藏(Stashing) SSH 传输设置 .gitignore 文件 Git 命令一览 参考资料 集中式与分布式 Git 属于分布式版本控制系统,而 SVN 属于集中式。 集中式版本控制只有中心服务器拥有一份代码,而分布
阅读全文
摘要:"一、性能" "二、伸缩性" "三、扩展性" "四、可用性" "五、安全性" "参考资料" 一、性能 性能指标 1. 响应时间 指某个请求从发出到接收到响应消耗的时间。 在对响应时间进行测试时,通常采用重复请求的方式,然后计算平均响应时间。 2. 吞吐量 指系统在单位时间内可以处理的请求数量,通常使
阅读全文

浙公网安备 33010602011771号