Java性能 -- HashMap
实现结构
HashMap是基于哈希表实现的,继承了AbstractMap并且实现了Map接口
HashMap根据键的Hash值来决定对应值的存储位置,通过这种索引方式,HashMap获取数据的速度会非常快
当发生哈希冲突时,有3种常用的解决方法:开放定址法、再哈希函数法、链地址法
开放定址法
当发生哈希冲突时,如果哈希表未被填满,说明在哈希表中必然还有空位置
可以把Key存放到冲突位置后面的空位置上
该方法存在很多问题,例如查找、扩容等,不推荐
再哈希函数法
在同义词产生地址冲突时再计算另一个哈希函数地址,直到不再冲突
这种方法不容易产生聚集,但却增加了计算时间
链地址法
HashMap综合考虑了所有因素,采用了链地址法来解决哈希冲突问题
该方法采用了数组(哈希表)+链表的数据结构,当发生哈希冲突时,就用一个链表结构存储相同Hash值的数据
重要属性NodeHashMap是由一个Node数组构成的,每个Node包含一个Key-Value键值对
1transient Node<K,V>[] table;
Node类是HashMap的一个内部类,定义了一个next指针,指向具有 ...
Kafka -- 线上部署
操作系统Linux的表现更胜一筹:IO模型的使用、网络传输效率、社区支持度
IO模型
主流的IO模型:阻塞式IO、非阻塞式IO、IO多路复用、信号驱动IO、异步IO,后一种模型比前一种高级
Java中的Socket对象的阻塞模式和非阻塞模式,对应阻塞式IO和非阻塞式IO
Linux中的系统调用select函数属于IO多路复用模型
大名鼎鼎的epoll系统调用则介于第三种模型和第四种模型之间
很少有Linux系统支持异步IO,Windows系统提供的IOCP线程模型属于异步IO
Kafka客户端底层使用了Java的selector,selector在Linux上的实现机制是epoll,在Windows上是select
Kafka部署在Linux上,能够获得更高效的IO性能
网络传输效率
Kafka生产和消费的消息都是通过网络传输的,而消息是保存在磁盘上的
因此Kafka需要在磁盘和网络间进行大量的数据传输
Linux支持零拷贝技术
当数据在磁盘和网络进行传输时,避免昂贵的内核态数据拷贝,从而实现快速的数据传输
在Windows平台必须等待Java 8 Update 60才能享受到类似Linux ...
Java性能 -- Stream
Stream API
Java 8集合中的Stream相当于高级版的Iterator
Stream API通过Lambda表达式对集合进行各种非常便利高效的聚合操作,或者大批量数据操作
Stream的聚合操作与数据库SQL的聚合操作sorted、filter、map等非常类似
在数据操作方面,Stream不仅可以通过串行的方式实现数据操作,还可以通过并行的方式处理大批量数据,提高处理效率
12345678// java.util.Collectiondefault Stream<E> stream() { return StreamSupport.stream(spliterator(), false);}default Stream<E> parallelStream() { return StreamSupport.stream(spliterator(), true);}
123456789101112131415161718192021222324@Dataclass Student { privat ...
Kafka -- “发行版”
Kafka Connect
Kafka Connect, an open source component of Kafka, is a framework for connecting Kafka with external systems such as databases, key-value stores, search indexes, and file systems.
Using Kafka Connect you can use existing connector implementations for common data sources and sinks to move data into and out of Kafka.
Apache Kafka
Apache Kafka是最正宗的Kafka,被称为社区版Kafka,是其他发行版的基础
优点:开发人数最多,版本迭代速度最快,社区响应度高
缺点:仅仅提供最基础的组件,没有提供任何监控框架或工具,缺失高级功能
应用场景:仅仅需要一个消息引擎系统或者简单的流处理应用场景,同时需要对系统有较大的把控度
Confluent ...
Java性能 -- ArrayList + LinkedList
List接口
ArrayList、Vector、LinkedList继承了AbstractList,AbstractList实现了List,同时继承了AbstractCollection
ArrayList和Vector使用了数组实现,LinkedList使用了双向链表实现
ArrayList常见问题
ArrayList的对象数组elementData使用了transient(表示不会被序列化)修饰,为什么?
ArrayList在大量新增元素的场景下,效率一定会变慢?
如果要循环遍历ArrayList,采用for循环还是迭代循环?
类签名123public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}
ArrayList实现了List接口,继承了AbstractList抽象类,底层是数组实现,并且实现了自增扩容
ArrayList实现了Cloneabl ...
Kafka -- 分布式流处理平台
历史消息引擎系统
Kafka在刚诞生时是以消息引擎系统的面目出现在大众视野中
Kafka在0.10.0.0之前的定位:分布式、分区化且带备份功能的提交日志(Commit Log)服务
Kafka在设计之初的功能特性
提供一套API实现生产者和消费者
降低网络传输和磁盘存储开销
实现高伸缩架构
分布式流处理平台
Kafka于2011年正式进入Apache基金会孵化并于次年10月成为Apache顶级项目
Kafka社区于0.10.0.0版本正式推出流处理组件Kafka Streams,定位变成了分布式流处理平台
同等级的实时流处理平台:Apache Kafka、Apache Storm、Apache Spark、Apache Flink
目前国内对Kafka是流处理平台的认知还不普及,其核心的流处理组件Kafka Streams更是少有大厂在使用
优势端到端的正确性
Kafka更容易实现端到端的正确性(Correctness)
流处理要替代批处理需要具备两个核心优势
实现正确性(正确性是流处理能够匹敌批处理的基石)
提供能够推导时间的工具
正确性一直都是批处理的强项,而实现正确性的基石是要求框架能 ...
Java性能 -- 正则表达式
元字符
正则表达式使用一些特定的元字符来检索、匹配和替换符合规则的字符串
元字符:普通字符、标准字符、限定字符(量词)、定位字符(边界字符)
正则表达式引擎
正则表达式是一个用正则符号写出来的公式
程序对正则表达式进行语法分析,建立语法分析树
再根据语法分析树结合正则表达式引擎生成执行程序(状态机),用于字符匹配
正则表达式引擎是一套核心算法,用于建立状态机
小结
正则表达式 => 语法分析树
语法分析树 + 正则表达引擎 => 状态机 => 用于字符匹配
目前实现正则表达式引擎的方式有两种
DFA自动机(Deterministic Finite Automaton,确定有限状态自动机)
NFA自动机(Nondeterministic Finite Automaton,非确定有限状态自动机)
DFA自动机的构造代价远大于NFA自动机,但DFA自动机的执行效率高于NFA自动机
假设一个字符串的长度为n,如果采用DFA自动机作为正则表达式引擎,则匹配的时间复杂度为O(n)
如果采用NFA自动机作为正则表达式引擎,NFA自动机在匹配过程中存在 ...
Kafka -- 术语
主题 + 客户端
发布订阅的对象是主题(Topic)
向主题发布消息的客户端应用程序称为生产者(Producer),生产者可以持续不断地向多个主题发送消息
订阅这些主题消息的客户端应用程序称为消费者(Consumer),消费者能够同时订阅多个主题的消息
生产者和消费者统称为客户端
服务端
Kafka的服务端由被称为Broker的服务进程构成,一个Kafka集群由多个Broker组成
Broker负责接收和处理客户端发送过来的请求,以及对消息进行持久化
多个Broker进程能够运行在同一台机器上,但更常见的做法是将不同的Broker分散运行在不同的机器上
这样如果集群中某一台机器宕机了,即使在它上面运行的所有Broker进程都挂掉了
其他机器上的Broker也依然能够对外提供服务,这是Kafka提供高可用的手段之一
备份
实现高可用的另一个手段是备份机制(Replication)
备份:把相同的数据拷贝到多台机器上,这些相同的数据拷贝在Kafka中被称为副本(Replica)
副本的数量是可以配置的,Kafka定义了两类副本:领导者副本(Leader Replica)和追随者副本(Follower ...
Kafka -- 消息引擎系统
术语
Apache Kafka是一款开源的消息引擎系统
消息队列:给人某种暗示,仿佛Kafka是利用队列实现的
消息中间件:过度强调中间件,而不能清晰地表达实际解决的问题
解决的问题
系统A发送消息给消息引擎系统,系统B从消息引擎系统中读取A发送的消息
消息引擎传输的对象是消息
如何传输消息属于消息引擎设计机制的一部分
消息格式
成熟解决方案:CSV、XML、JSON
序列化框架:Google Protocol Buffer、Facebook Thrift
Kafka:纯二进制的字节序列
消息引擎模型
点对点模型
即消息队列模型,系统A发送的消息只能被系统B接收,其他任何系统不能读取A发送的消息
发布订阅模型
主题(Topic)、发布者(Publisher)、订阅者(Subscriber)
多个发布者可以向相同的主题发送消息,多个订阅者可以接收相同主题的消息
Kafka同时支持上面两种消息引擎模型
JMS
JMS:Java Message Service
JMS也支持上面的两种消息引擎模型
JMS并非传输协议,而是一组API
JMS非常出名,很多主流的消息引擎系统都支持JMS规范
Acti ...
Java并发 -- CSP模型
Go
Go是一门号称从语言层面支持并发的编程语言,支持并发也是Go非常重要的特性之一
Go支持协程,协程可以类比Java中的线程,解决并发问题的难点在于线程(协程)之间的协作
Go提供了两种方案
支持协程之间以共享内存的方式通信,Go提供了管程和原子类来对协程进行同步控制,该方案与Java类似
支持协程之间以消息传递的方式通信,本质上是要避免共享,该方案是基于CSP模型实现的,Go推荐该方案
CSP模型
CSP:Communicating Sequential Processes
Do not communicate by sharing memory; instead, share memory by communicating.
累加器12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455package mainimport ( "fmt" "time")func main() { ...