/images/avatar.png

哈希表

定义 散列Hash是和顺序、链接和索引一样,是存储集合或者线性表的一种方法。 散列的基本思想是:以集合或线性表中的每个元素的关键字K为自变量,通过一个散列函数 h(K) 得到的结果,将这个结果解释为一块连续的存储空间(如数组)的地址(如数组下标),将这个元素存储到这个空间中。 h(K) 称为散列函数或者哈希函数,它实现了关键字到存储地址的映射,散列算法,变换成固定长度的输出,该输出就是散列值。h(K)的值 称为散列地址或者哈希地址。存储空间是线性表进行散列存储的空间,所以称之为散列表或者哈希表。 释义 这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。 所有散列函数都有如下一个基本特性:根据同一散列函数计算出的散列值如果不同,那么输入值肯定也不同。但是,根据同一散列函数计算出的散列值如果相同,输入值不一定相同。 两个不同的输入值,根据同一散列函数计算出的散列值相同的现象叫做碰撞,衡量一个哈希函数的好坏的重要指标就是发生碰撞的概率以及发生碰撞的解决方案。 常见的Hash函数 直接定址法:直接以关键字k或者k加上某个常数(k+c)作为哈希地址。 数字分析法:提取关键字中取值比较均匀的数字作为哈希地址。 除留余数法:用关键字k除以某个不大于哈希表长度m的数p,将所得余数作为哈希表地址。 分段叠加法:按照哈希表地址位数将关键字分成位数相等的几部分,其中最后一部分可以比较短。然后将这几部分相加,舍弃最高进位后的结果就是该关键字的哈希地址。 平方取中法:如果关键字各个部分分布都不均匀的话,可以先求出它的平方值,然后按照需求取中间的几位作为哈希地址。 伪随机数法:采用一个伪随机数当作哈希函数。 解决碰撞方法 开放定址法:开放定址法就是一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入。 链地址法:将哈希表的每个单元作为链表的头结点,所有哈希地址为i的元素构成一个同义词链表。即发生冲突时就把该关键字链在以该单元为头结点的链表的尾部。 再哈希法:当哈希地址发生冲突用其他的函数计算另一个哈希函数地址,直到冲突不再产生为止。 建立公共溢出区:将哈希表分为基本表和溢出表两部分,发生冲突的元素都放入溢出表中。 散列存储的缺点 计算散列地址需要花费时间,关键字不是整数还先要转换为整数。 占用更多的存储空间,开放定址法的装载因子小于1,链接法则需要空间存储指针。 只能按关键字查找,无法按非关键字查找。

链表

定义 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 详解 链表的存在就是为了解决数组的增删复杂耗时,内存占用较大的问题。它并不需要一块连续的内存空间,它通过指针将一组零散的内存块串联起来。 根据指针的不同,有单链表,双向链表,循环链表之分。 数组和链表是相互补充的一对数据结构。 优点: 操作指针即可删除该元素或者插入新元素,时间复杂度 O(1)。 链表因为元素不连续,而是靠指针指向下一个元素的位置,本身没有大小的限制,不存在数组的扩容问题,所以天然地支持动态扩容。 空间没有限制 插入删除元素很快 缺点: 因为存储空间不连续,你无法根据一个索引算出对应元素的地址,所以不能随机访问。 由于每个元素必须存储指向前后元素位置的指针,会消耗相对更多的储存空间。 同时内存不连续,容易造成内存碎片。 存取速度很慢 对比 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大。但数组的二分查找时间复杂度小,为O(1);数组的特点是:寻址容易,插入和删除困难。 链表 链表存储区间离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度很大,达O(N)。链表的特点是:寻址困难,插入和删除容易。 哈希表 那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?这就是我们要提起的哈希表。 分类 单向链表 一个节点指向下一个节点。 双向链表 一个节点有两个指针域。 循环链表 能通过任何一个节点找到其他所有的节点,将两种(双向/单向)链表的最后一个结点指向第一个结点从而实现循环。

数组

定义 有限个相同数据类型的元素按顺序排列的集合为数组。 特性 数组是相同数据类型的元素的集合。 数组中的各元素的存储是有先后顺序的,它们在内存中按照这个先后顺序连续存放在一起。 优点: 由于是紧凑连续存储,可以随机访问,通过索引快速找到对应元素,而且相对节约存储空间,查询修改元素的效率O(1)。 缺点: 正因为连续存储,内存空间必须一次性分配够,所以说数组如果要扩容,需要重新分配一块更大的空间,再把数据全部复制过去,时间复杂度 O(N)。 想在数组中间进行插入和删除,每次必须搬移后面的所有数据以保持连续,时间复杂度 O(N) 二维数组 二维数组也称为矩阵,因为是二维的,所以需要两个下标才能确定一个元素,即行下标和列下标。

数据结构概览

概览 数据结构研究的是数据的存储方式,算法研究的是解决问题的思路。数据结构与算法是相辅相成的。 常用存储结构 线性表,还可细分为顺序表(数组)、链表、栈和队列。 树结构,包括普通树,二叉树,二叉查找树等。 图存储结构。 线性表 线性表并不是一种具体的存储结构,它包含顺序存储结构和链式存储结构,是顺序表和链表的统称。 线性表是一种线性结构,它是由零个或多个数据元素构成的有限序列。 线性表的特征是在一个序列中,除了头尾元素,每个元素都有且只有一个直接前驱,有且只有一个直接后继,而序列头元素没有直接前驱,序列尾元素没有直接后继。 数据结构中常见的线性结构有数组、单链表、双链表、循环链表等。线性表中的元素为某种相同的抽象数据类型。 线性表 如图 3a) 所示,将数据依次存储在连续的整块物理空间中,这种存储结构称为顺序存储结构(简称顺序表,数组); 如图 3b) 所示,数据分散的存储在物理空间中,通过一根线保存着它们之间的逻辑关系,这种存储结构称为链式存储结构(简称链表)。 数组和矩阵(顺序表) 数组是一种连续存储线性结构,元素类型相同,大小相等,数组是多维的,通过使用整型索引值来访问他们的元素,数组尺寸不能改变。 链表 我们知道,使用顺序表(底层实现靠数组)时,需要提前申请一定大小的存储空间,这块存储空间的物理地址是连续的,链表则完全不同,使用链表存储数据时,是随用随申请,因此数据的存储位置是相互分离的,换句话说,数据的存储位置是随机的。 n个节点离散分配,彼此通过指针相连,每个节点只有一个前驱节点,每个节点只有一个后续节点,首节点没有前驱节点,尾节点没有后续节点。确定一个链表我们只需要头指针,通过头指针就可以把整个链表都能推出来。 哈希表(散列) 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。 栈和队列 数组和链表都是线性存储结构的基础,栈和队列都是线性存储结构的应用,栈和队列隶属于线性表,是特殊的线性表,因为它们对线性表中元素的进出做了明确的要求。 栈(LIFO) 使用数组实现的叫静态栈 使用链表实现的叫动态栈 栈(FIFO) 使用数组实现的叫静态队列 使用链表实现的叫动态队列 树存储结构 树存储结构适合存储具有“一对多”关系的数据。 树 图存储结构 图存储结构适合存储具有“多对多”关系的数据。 图 和线性表,树的差异: 线性表中我们把数据元素叫元素,树中将数据元素叫结点,在图中数据元素,我们则称之为顶点(Vertex)。 线性表可以没有元素,称为空表;树中可以没有节点,称为空树;但是,在图中不允许没有顶点(有穷非空性)。 线性表中的各元素是线性关系,树中的各元素是层次关系,而图中各顶点的关系是用边来表示(边集可以为空)。 总结 我们知道,实际应用当中,我们经常使用的是查找和排序操作,这在我们的各种管理系统、数据库系统、操作系统等当中,十分常用。 数组 的下标寻址十分迅速,但计算机的内存是有限的,故数组的长度也是有限的,实际应用当中的数据往往十分庞大;而且无序数组的查找最坏情况需要遍历整个数组;后来人们提出了二分查找,二分查找要求数组的构造一定有序,二分法查找解决了普通数组查找复杂度过高的问题。任和一种数组无法解决的问题就是插入、删除操作比较复杂,因此,在一个增删查改比较频繁的数据结构中,数组不会被优先考虑 普通链表 由于它的结构特点被证明根本不适合进行查找 哈希表 是数组和链表的折中,同时它的设计依赖散列函数的设计,数组不能无限长、链表也不适合查找,所以也不适合大规模的查找 二叉查找树 因为可能退化成链表,同样不适合进行查找 AVL树 是为了解决可能退化成链表问题,但是AVL树的旋转过程非常麻烦,因此插入和删除很慢,也就是构建AVL树比较麻烦 红黑树 是平衡二叉树和AVL树的折中,因此是比较合适的。集合类中的Map、关联数组具有较高的查询效率,它们的底层实现就是红黑树。 多路查找树 是大规模数据存储中,实现索引查询这样一个实际背景下,树节点存储的元素数量是有限的(如果元素数量非常多的话,查找就退化成节点内部的线性查找了),这样导致二叉查找树结构由于树的深度过大而造成磁盘I/O读写过于频繁,进而导致查询效率低下。 B树 与自平衡二叉查找树不同,B树适用于读写相对大的数据块的存储系统,例如磁盘。它的应用是文件系统及部分非关系型数据库索引。 B+树 在B树基础上,为叶子结点增加链表指针(B树+叶子有序链表),所有关键字都在叶子结点 中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中。通常用于关系型数据库(如Mysql)和操作系统的文件系统中。 B*树 是B+树的变体,在B+树的非根和非叶子结点再增加指向兄弟的指针, 在B+树基础上,为非叶子结点也增加链表指针,将结点的最低利用率从1/2提高到2/3。 R树是用来做空间数据存储的树状数据结构。例如给地理位置,矩形和多边形这类多维数据建立索引。 Trie树 是自然语言处理中最常用的数据结构,很多字符串处理任务都会用到。Trie树本身是一种有限状态自动机,还有很多变体。什么模式匹配、正则表达式,都与这有关。 针对大量数据,如果在内存中作业优先考虑红黑树(map,set之类多为RB-tree实现),如果在硬盘中作业优先考虑B系列树(B+, B, B)*

计算机网络

网络通信协议 是指一种网络通用语言,为连接不同操作系统和不同硬件体系结构的互联网络提供通信支持的一堆协议 常见的网络通信协议: TCP/IP协议、IPX/SPX协议、NetBEUI协议等。 主要是对信息传输的速率、传输代码、代码结构、传输控制步骤、出错控制等作出规定并制定出标准。 TCP/IP协议 互联网相关联的协议集的总称:TCP/IP 全称传输控制协议/因特网互联协议( Transmission Control Protocol/Internet Protocol) 是最基本、应用最广泛的一套互联网协议,定义了计算机如何接入互联网,数据在互联网如何传输 TCP/IP四层体系结构: 针对应用开发者的OSI体系结构简化版 OSI七层体系结构: 五层协议体系结构:网络接口层分为数据链路层 + 物理层 协议对照 各层协议对照 一般网线传输的模拟信号需要通过猫(调制解调器)转换成数字信号,再经由路由器把信号发给PC端,如果PC端数量超过了路由器的连接上限就需要加装交换器。因此,家里有宽带就必须有猫,有多台电脑上网就必须要路由器,假如电脑很多,超过路由器的接口数就需要交换机扩展接口。 计算机网络 是网络通信技术与计算机技术相结合体,按照网络通信协议将计算机连接起来进行通信 连接介质可以是电缆、双绞线、光纤、微波、载波或通信卫星 分类:局域网(LAN)、城域网(MAN)、广域网(WAN) 互联网 全世界范围的计算机网络,信息社会的基石,使用TCP/IP协议 网络中的设备:交换机、路由器、服务器、PC、手机、物联网终端、车联网设备 TCP与UDP协议 TCP:传输控制协议 (Transmission Control Protocol)。 传输控制协议 (Transmission Control Protocol),可以保证传输数据的安全,相对于UDP 面向连接的协议,先建立连接,再传输数据,传输的过程中还会保障传输数据的可靠性 建立连接三次握手,关闭连接四次挥手 应用场景:http请求都基于TCP进行数据传输,浏览网页,图片,下载文档 UDP:用户数据报送协议(User Datagram Protocol)。 用户数据报送协议(User Datagram Protocol),不保证数据传输的安全 面向无连接的协议,传输数据不需要建立连接,不管对方服务是否启动,发数据包就完了 传输数据速度快,安全性差,可能会丢失数据包 应用场景:视频会议,语音通话,视频直播… TCP-三次握手 三次握手:TCP协议在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠 1次握手:Client发送带有 SYN 标志的数据包给Server 2次握手:Server发送带有 SYN/ACK 标志的数据包给Client 3次握手:Client发送带有 ACK 标志的数据包给Server【多此一举?】 TCP-三次握手 为什么要三次握手? 三次握手的目的是建立可靠的通信信道,双方确认自己与对方的发送与接收是正常的 1次握手: Client 什么都不能确认; Server 确认对方发送正常,自己接收正常 2次握手: Client 确认自己发送接收正常,对方发送接收正常; 3次握手: Server 确认自己发送正常,对方接收正常 TCP-四次挥手 数据传输完毕,断开⼀个 TCP 连接则需要四次挥手:

git 代理配置

设置https 代理 Git代理有两种设置方式,分别是全局代理和只对Github代理,建议只对github 代理。 代理协议也有两种,分别是使用http代理和使用socks5代理,建议使用socks5代理。 注意下面代码的端口号需要根据你自己的代理端口设定,比如我的代理socks端口是51837。 全局设置(不推荐) 1 2 3 4 5 6 #使用http代理 git config --global http.proxy http://127.0.0.1:58591 git config --global https.proxy https://127.0.0.1:58591 #使用socks5代理 git config --global http.proxy socks5://127.0.0.1:51837 git config --global https.proxy socks5://127.0.0.1:51837 只对Github代理(推荐) 1 2 3 4 #使用socks5代理(推荐) git config --global http.https://github.com.proxy socks5://127.0.0.1:51837 #使用http代理(不推荐) git config --global http.https://github.com.proxy http://127.0.0.1:58591 取消代理 当你不需要使用代理时,可以取消之前设置的代理。 1 git config --global --unset http.proxy git config --global --unset https.proxy 参考文章 1.https://zhuanlan.zhihu.com/p/481574024

操作

提前看盘前重点消息,留意相关有消息刺激的板块或个股。 集合竞价就留意并筛选有大量拉升抢筹的个股,比如十几万手拉五个点以上的抢筹,而且一定是买盘量大于卖盘量。 注意筛选的个股的日线形态,流通市值等,假定自己是大游资,会不会今天封板这支股票。 以上加入自选开盘时重点观察。 设置合适找涨停票版面,我设置的有按上涨幅度排序的沪深主板的,重点观察开盘就拉伸五六甚至七八个点个股。 然后根据自己的指标判断,是否直接扫板还是打回封板。 我自己大概是这样的过程。判断指标这个要讲的东西太多了,以后有空结合实例慢慢和大家交流分享。

估值

第一大块 蓝筹股 是以金融、地产、公用事业,还有建筑为主的蓝筹股,比较典型的特征是,估值很低,盈利质量好,盈利增速比较低。但是他不太愿意去参与蓝筹股投资,因为虽然低估值,但是并不满足盈利出现非线性变化的特征。换句话说就是,盈利无法突变。 这些行业可能十年前,甚至十年后的商业模式和盈利增速都是相对稳定,这种相对比较低的增速,它无法平抑估值上的波动。 巴菲特所说的捡烟蒂,指的就是这类股票,这类票机构看不上,但是对散户来说,拿着搏个稳定增长,还是很舒服的。 第二大块 低估值成长 我们挑的基金,挑的都是低估值成长风格的基金。他认为,中国制造业太大了,很多细分行业是没人注意的到的,只有靠基金经理自己去挖,去走访调研,寻找小领域里别人没注意到,但是业绩即将爆发的票,先买入这种票,等市场开始关注到的时候,就会出现一个估值和业绩的双抬升,戴维斯双击。 第三大块 顺周期行业 顺周期行业投资者参与热情并不高,因为在大家看来,顺周期是一个短久期的资产,没有量的逻辑,只有价格的逻辑,而价格的波动又过于频繁,所以个人投资者很难去判断行业盈利中枢到底在哪,容易造成永久性亏损(套几年)。讲白了就是,你摸不准这个行业在高景气度的时候,到底能赚多少钱,因为它可能十年才来一个牛市,十年前那个价格早就不具有参考性了,就像现在的煤炭、钢铁、有色、化工,你能准确说出它的历史高位在哪吗?没有一个人能够打包票。这就是顺周期的难点,他认为当前顺周期的分歧很大。

投资纲领

总体策略 低估加倍 高估不买 高估卖出 好资产 + 好价格 + 长期持有 资产配置 购买标的 宽基指数(沪深300和中证500) 我们可以把沪深300和中证500这样的宽基指数作为「核心」资产,比如占整体仓位的 60% 以上,保证我们能够跟上中国经济的增长,投资到未来头部的公司。 40% 基于估值和增强型指数基金进一步提高仓位。 「卫星」资产 我们可以根据自己的判断或者市场的估值,加入一部分「卫星」资产。 主动基金(优秀基金精力管理的基金)中概互联基金 科创板(还需观看) 。 30% 分散投资给几个优秀的主动型基金经理。 债券 30% 的债券仓位,用债券基金以及有知有行未来推荐的其它「固收+」产品来进一步提高收益。 计算得出年化收益率:40% * 13% + 30% * 11% + 30% * 4% + 1% = 10.7%。 具体操作 每年一次大额买入 参考有知有行的「股市温度计」来确定自己一次性买入的仓位。 假如当年大额资金5万,当时股市温度为40处于中估状态,则先投入50%,计算得出当年大额买入资金为2.5万。 每年一次的再平衡 根据自定的家庭资产比例和当年股债实时状态,进行股债再平衡调整。 每月定投 参考有知有行的「股市温度计」,在中估时投入,低估时加倍,高估时停止买入 高估状态卖出部分锁定收益 A股的波动大,牛市之后往往出现暴跌,而浮亏越大,回本难度越大,甚至难度是呈指数级增长的。