golang sleep

golang sleep http://xiaorui.cc/2016/03/23/golang%E9%9A%8F%E6%9C%BAtime-sleep%E7%9A%84duration%E9%97%AE%E9%A2%98/ golang随机time.sleep的Duration问题 2016-3-23 Golang rfyiamcool 5,894 views 碰到一个Golang time.Sleep()的问题,这golang的time.sleep的功能貌似要比python ruby都要精细些,python的等待只是time.sleep()而已,而golang可以time.Sleep(10 * time.Second) 毫秒、秒分时等不同日期来搞… 大事不干,净整些没用的… 该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新http://xiaorui.cc/?p=3034 重现一下问题,用math/rannd得到10以内的随机数,然后time.sleep()等待… num := rand.Int31n(10) time.sleep(num * time.Second) num := rand.Int31n(10) time.sleep(num * time.Second) 会遇到下面的问题: xiaorui.cc command-line-arguments ./lock.go:88: invalid operation: int(DefaultTimeout) * time.Second (mismatched types int and time.Duration) xiaorui.cc command-line-arguments ./lock.go:88: invalid operation: int(DefaultTimeout) * time.Second (mismatched types int and time.Duration) 解决的方法: time.Sleep(time.Duration(num) * time.Second) time.Sleep(time.Duration(num) * time.Second) 期初原因以为是rand随机数有问题,简单看了rand的函数说明感觉没问题! 下面是产生的原因: func Sleep(d Duration) ...

2017-07-27 · 2 min · 231 words · -

logrotate

logrotate 确认 cronie 已经安装并启动 http://wiloon.com/cron 全局配置 /etc/logrotate.conf 不同应用的具体配置则在 /etc/logrotate.d/* 配置文件内容 /etc/logrotate.d/ansiblelog vim /etc/logrotate.d/ansiblelog /var/log/ansible.log { daily rotate 7 missingok dateext copytruncate compress } /var/log/nginx/*.log /var/log/tomcat/*log { # 可以指定多个路径, 用空格分隔, 或者用换行分隔 su root root # 切换到root用户操作文件 daily # 日志轮转周期, weekly, monthly, yearly, daily rotate 30 # 保存30天数据,超过的则删除 size +100M # 超过 100M 时分割, 单位 K,M,G, 优先级高于 daily compress # 切割后压缩, 也可以为 nocompress delaycompress # 切割时对上次的日志文件进行压缩 dateext # 日志文件切割时添加日期后缀 missingok # 如果没有日志文件也不报错 notifempty # 日志为空时不进行切换, 默认为ifempty create 640 nginx nginx # 使用该模式创建日志文件 sharedscripts # 所有的文件切割之后只执行一次下面脚本 postrotate if [ -f /var/run/nginx.pid ]; then kill -USR1 `cat /var/run/nginx.pid` fi endscript } # logrotate status cat /var/lib/logrotate/logrotate.status # 显示详细的信息;而且 --debug/-d 实际上不会操作具体文件 (Dry Run) logrotate --debug --verbose --force /etc/logrotate.d/nginx # 启用debug模式, 上不会操作具体文件 (Dry Run) # -d, --debug logrotate -d # 强制滚动日志, 手动执行, 所有配置 logrotate -f /etc/logrotate.conf # 单个配置 logrotate -f /etc/logrotate.d/nginx # -f,--force crontab -e * * */1 * * /usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.d/tcpcopy /etc/crontab 01 * * * * root run-parts /etc/cron.hourly 02 4 * * * root run-parts /etc/cron.daily 22 4 * * 0 root run-parts /etc/cron.weekly 42 4 1 * * root run-parts /etc/cron.monthly run-parts 命令位于 /usr/bin/run-parts, 内容是很简单的一个shell脚本, 就是遍历目标文件夹, 执行第一层目录下的可执行权限的文件。 ...

2017-07-25 · 2 min · 348 words · -

Chronograf

Chronograf wget https://dl.influxdata.com/chronograf/releases/chronograf-1.3.4.0.x86_64.rpm sudo yum localinstall chronograf-1.3.4.0.x86_64.rpm

2017-07-25 · 1 min · 7 words · -

rxvt-unicode 标签

rxvt-unicode 标签 http://0x3f.org/post/let-rxvt-unicode-support-tags-and-links/ 为rxvt-unicode开启标签和链接支持 写完urxvt-unicode快速上手,本以为已将urxvt的用法一网打尽,不料AndyWxy网友又找到了两个新的功能: 使urxvt启用标签和在urxvt中打开网页链接。 标签功能很实用,一般为了达到复用终端窗口的目的会采用两种方式: 一是配合screen使用,另一个就是启用标签。然而前者有一个缺点就是不直观,标签页恰好能弥补这个缺陷。urxvt不愧是个功能强大的终端工具,如果在编译时开启perl支持,则urxvt可启用多标签功能。用法如下: 一是在启动的时候加入命令行参数: urxvt -pe tabbed 二是在配置文件".Xresources"中添加如下配置信息: URxvt.perl-ext-common: default,tabbed 则默认情况下执行urxvt就会打开多标签功能。urxvt的标签支持使用鼠标操作,同时可以使用Ctrl+Shift+左右箭头来切换标签页,使用Ctrl+Shift+向下箭头开启新标签。 另外一个功能就是可以通过在urxvt中的链接上点击鼠标左键来通过设定的浏览器打开之。首先在".Xresources"文件中添加如下内容: URxvt.urlLauncher: firefox URxvt.matcher.button: 1 然后使用如下命令打开urxvt: urxvt -pe matcher 即可。也可以在配置文件中添加上述内容之后再添加一行: URxvt.perl-ext-common: matcher 此后即默认开启在终端窗口中打开链接的功能。注意修改".Xresources"文件后需要执行如下命令才能使修改后的配置文件生效: xrdb ~/.Xresources

2017-07-25 · 1 min · 31 words · -

yum

yum yum command 按版本安装 yum list|grep filebeat # 回显 filebeat.x86_64 7.2.0-1 @elastic filebeat.i686 7.2.1-1 elastic filebeat.x86_64 7.2.1-1 elastic # 安装 指定版本7.2.0-1 yum install filebeat-7.2.0-1 #search yum search iostat #search yum list java* # HTTP Error 404 - Not Found yum clean all rpm --rebuilddb yum update #check package installed yum list installed xxx # 列出所有已安装的软件包 yum list installed #升级所有包同时也升级软件和系统内核 yum -y update #只升级所有包,不升级软件和系统内核 yum -y upgrade #check installed package rpm -qa|grep jdk #安装 yum install httpd yum -y install httpd ## yum 安装 本地 rpm 包, local install sudo yum localinstall influxdb-1.2.4.x86_64.rpm #yum mirror /etc/yum.repos.d #Yum更新中排除特定的包 yum update --exclude=kernel* --exclude=php* https://www.howtoing.com/exclude-packages-from-yum-update 卸载 # 默认会卸载依赖包 yum remove httpd yum -y remove httpd # 不卸载依赖 rpm -e --nodeps foo Delta RPMs disabled because /usr/bin/applydeltarpm not installed # 查看哪个包提供 applydeltarpm yum provides '*/applydeltarpm' # 安装 deltarpm yum install deltarpm -y 清除metadata run yum --enablerepo=updates clean metadata yum 安装报错“rpmdb: BDB0113” error: rpmdb: BDB0113 Thread/process ****/************* failed: BDB1507 Thread died in Berkeley DB library error: db5 error(-30973) from dbenv->failchk: BDB0087 DB_RUNRECOVERY: Fatal error, run database recovery error: cannot open Packages index using db5 - (-30973) error: cannot open Packages database in /var/lib/rpm rm -f /var/lib/rpm/__db* rpm --rebuilddb https://my.oschina.net/andyfeng/blog/601291 ...

2017-07-21 · 2 min · 258 words · -

guava-retrying

guava-retrying http://blog.csdn.net/aitangyong/article/details/53840719 https://github.com/rholder/guava-retrying 对于开发过网络应用程序的程序员来说,重试并不陌生,由于网络的拥堵和波动,此刻不能访问服务的请求,也许过一小段时间就可以正常访问了。比如下面这段给某个手机号发SMS的伪代码: // 发送SMS public boolean sendSMS(String phone, String content) { int retryTimes = 3; for(int i=0; i<=3; i++) { try { boolean result = doSomething(phone, content); // 发送成功直接返回 if(result == true) { return true; } } catch(IOException e) { // 可能是网络问题导致IOException,所以我们继续重试 logger.error("send sms error", e); } catch(Exception e) { // 未知异常,与网络无关,有可能是代码出现问题,这个时候重试没用,我们直接返回false logger.error("unknown exception", e); return false; } } return false; } // 给某人发短信 private boolean doSomething(String phone, String content) { } 这段代码有什么问题呢?看起来很丑,为了实现重试逻辑,各种if-else,各种try-catch。重试逻辑太简单,只是控制了重试次数,并没有控制2次重试之间的时间间隔。因为重试代码与业务代码耦合在一起,所以看起来很复杂。 ...

2017-07-20 · 1 min · 150 words · -

ntp, chrony, 时钟服务, 时钟同步

systemd-timesyncd, ntp, chrony NTP,是 Net Time Protocol 的缩写,意即网络时间协议。 archlinux 默认启用 ntp systemd-timesyncd archinstall 默认使用 systemd-timesyncd 作时钟同步, UDP 123 端口(NTP 协议),不能用 https 代理 systemd-timesyncd 是一个用于跨网络同步系统时钟的守护服务。它实现了一个 SNTP 客户端。与NTP的复杂实现相比,这个服务简单的多,它只专注于从远程服务器查询然后同步到本地时钟。 # archlinux 的时钟同步是默认启用的. timedatectl status # System clock synchronized: yes # 检查其状态 systemctl status systemd-timesyncd # systemd-timesyncd 服务启用 sudo systemctl enable systemd-timesyncd --now # timedatectl 层面启用 NTP sudo timedatectl set-ntp true # 禁用 sudo systemctl stop systemd-timesyncd sudo systemctl disable systemd-timesyncd sudo systemctl mask systemd-timesyncd sudo timedatectl set-ntp false chrony install # install chrony - arch sudo pacman -S chrony # for centos yum install chrony # ubuntu apt install chrony chrony 配置 # 号和 ! 号都代表注释 ...

2017-07-20 · 6 min · 1215 words · -

database schema

database schema 对于MySQL,schema和database可以理解为等价的. As defined in the MySQL Glossary:In MySQL, physically, a schema is synonymous with a database. You can substitute the keyword SCHEMA instead of DATABASE in MySQL SQL syntax, for example using CREATE SCHEMA instead of CREATE DATABASE.Some other database products draw a distinction. For example, in the Oracle Database product, a schema represents only a part of a database: the tables and other objects owned by a single user. ...

2017-07-18 · 1 min · 74 words · -

InfluxDB

InfluxDB 时间序列数据库 InfluxDB 基于 Go 语言开发,社区非常活跃,项目更新速度很快,日新月异,关注度高。 特点 可以设置metric的保存时间。 支持通过条件过滤以及正则表达式删除数据。 支持类似 sql 的语法。 可以设置数据在集群中的副本数。 支持定期采样数据,写入另外的measurement,方便分粒度存储数据。 概念 数据格式 Line Protocol measurement[,tag_key1=tag_value1…] field_key=field_value[,field_key2=field_value2] [timestamp] cpu_load,host_id=1 value=0.1 1434055562000000000 相比于 JSON 格式,无需序列化,更加高效。 measurement: metric name,例如 cpu_load。 field-key, field-value: 通常用来存储数据,类似 opentsdb 中的 value=0.6,但是支持各种类型,数据存储时不会进行索引,每条数据必须拥有一个 field-key,如果使用 field-key 进行过滤,需要遍历一遍所有数据。 tags-key, tags-value: 和 field-key 类似,但是会进行索引,方便查询时用于过滤条件。 Series measurement, tag set, retention policy 相同的数据集合算做一个 series。 假设 cpu_load 有两个 tags,host_id 和 name,host_id 的数量为 100,name 的数量为 200,则 series 基数为 100 * 200 = 20000。 ...

2017-07-12 · 3 min · 578 words · -

IntelliJ IDEA

IntelliJ IDEA IntelliJ IDEA Windows JBR是什么 https://www.4spaces.org/what-is-intellij-idea-jbr/embed/#?secret=ZFT4esKgN4 idea without JBR JBR是指JetBrains Runtime,JetBrains Runtime是一个运行时环境,用于在Windows,macOS和Linux上运行基于IntelliJ Platform的产品。 JetBrains Runtime基于OpenJDK项目并进行了一些修改。 这些修改包括: 亚像素抗锯齿(Subpixel Anti-Aliasing),Linux上的增强字体渲染,HiDPI支持,连字(ligatures),macOS上的 San Francisco 字体系列支持,官方构建中未提供的本机崩溃的一些修复,以及其他小的增强功能。 JetBrains Runtime与所有JetBrains IDE的最新版本捆绑在一起,默认情况下使用,除非执行显式重新配置。 例外是32位Linux系统,其中IDE需要单独的JDK安装,因为目前只捆绑了64位JetBrains Runtime。 对于Windows,捆绑了32位JetBrains Runtime,它可以在32位和64位系统上运行。 中文 IntelliJ IDEA是一个非常强大的IDE,但是只有英文版,且默认的中文显示有一定问题。本文介绍了IntelliJ IDEA 12.0中文显示问题解决方案。 IDE本身的中文乱码 这个问题体现在IDE本身,比如打开文件浏览目录的时候,中文名的文件或目录会显示成方块。 解决方法: 进入设置页。File->Settings。 进入IDE Settings里的File Encodings项,把IDE Encoding项设置成UTF-8。确定。 进入IDE Settings里的Appearance项,选中Override default fonts by,把Name设置为你喜欢的字体 (我使用的是Yahei Consolas Hybrid) ,Size根据自己喜好设置 (我一般设为 14) 。确定。 以上应该可以保证中文显示没有问题了。 编辑器的中文问题 这个问题体现在代码编辑区中写中文时,可能会乱码或者中文汉子全部重叠在一起。 首先要确定你正在编辑的文件是UTF-8编码的,有很多文件可能默认是ANSI编码。 至于中文重叠那是因为你所选用的默认中文字体不对,一直以来我写代码都是用的consolas,但是这个字体不支持中文,Intellij IDEA 12中如果使用默认的中文字体 (不知道是哪个字体) 就会重叠在一起,在网上找了好久,终于找到一个神一般的字体Yahei Consolas Hybrid,即微软雅黑和consolas的混合! 于是乎,File->Settings IDE Settings->Editor->Color & Fonts->Font,设置字体为Yahei Consolas Hybrid即可。 ...

2017-07-11 · 1 min · 88 words · -

HBase Compaction

HBase Compaction HBase Compaction的前生今世-身世之旅 2016年7月13日 范欣欣 HBase 了解HBase的童鞋都知道,HBase是一种Log-Structured Merge Tree架构模式,用户数据写入先写WAL,再写缓存,满足一定条件后缓存数据会执行flush操作真正落盘,形成一个数据文件HFile。随着数据写入不断增多,flush次数也会不断增多,进而HFile数据文件就会越来越多。然而,太多数据文件会导致数据查询IO次数增多,因此HBase尝试着不断对这些文件进行合并,这个合并过程称为Compaction。 Compaction会从一个region的一个store中选择一些hfile文件进行合并。合并说来原理很简单,先从这些待合并的数据文件中读出KeyValues,再按照由小到大排列后写入一个新的文件中。之后,这个新生成的文件就会取代之前待合并的所有文件对外提供服务。HBase根据合并规模将Compaction分为了两类: MinorCompaction和MajorCompaction Minor Compaction是指选取一些小的、相邻的StoreFile将他们合并成一个更大的StoreFile,在这个过程中不会处理已经Deleted或Expired的Cell。一次Minor Compaction的结果是更少并且更大的StoreFile。 Major Compaction是指将所有的StoreFile合并成一个StoreFile,这个过程还会清理三类无意义数据: 被删除的数据、TTL过期数据、版本号超过设定版本号的数据。另外,一般情况下,Major Compaction时间会持续比较长,整个过程会消耗大量系统资源,对上层业务有比较大的影响。因此线上业务都会将关闭自动触发Major Compaction功能,改为手动在业务低峰期触发。 Compaction作用 | 副作用 上文提到,随着hfile文件数不断增多,一次查询就可能会需要越来越多的IO操作,延迟必然会越来越大,如下图一所示,随着数据写入不断增加,文件数不断增多,读取延时也在不断变大。而执行compaction会使得文件数基本稳定,进而IO Seek次数会比较稳定,延迟就会稳定在一定范围。然而,compaction操作重写文件会带来很大的带宽压力以及短时间IO压力。因此可以认为,Compaction就是使用短时间的IO消耗以及带宽消耗换取后续查询的低延迟。从图上来看,就是延迟有很大的毛刺,但总体趋势基本稳定不变,见下图二。 11 22 为了换取后续查询的低延迟,除了短时间的读放大之外,Compaction对写入也会有很大的影响。我们首先假设一个现象: 当写请求非常多,导致不断生成HFile,但compact的速度远远跟不上HFile生成的速度,这样就会使HFile的数量会越来越多,导致读性能急剧下降。为了避免这种情况,在HFile的数量过多的时候会限制写请求的速度: 在每次执行MemStore flush的操作前,如果HStore的HFile数超过hbase.hstore.blockingStoreFiles (默认7) ,则会阻塞flush操作hbase.hstore.blockingWaitTime时间,在这段时间内,如果compact操作使得HStore文件数下降到回这个值,则停止阻塞。另外阻塞超过时间后,也会恢复执行flush操作。这样做就可以有效地控制大量写请求的速度,但同时这也是影响写请求速度的主要原因之一。 可见,Compaction会使得数据读取延迟一直比较平稳,但付出的代价是大量的读延迟毛刺和一定的写阻塞。 Compaction流程 了解了一定的背景知识后,接下来需要从全局角度对Compaction进行了解。整个Compaction始于特定的触发条件,比如flush操作、周期性地Compaction检查操作等。一旦触发,HBase会将该Compaction交由一个独立的线程处理,该线程首先会从对应store中选择合适的hfile文件进行合并,这一步是整个Compaction的核心,选取文件需要遵循很多条件,比如文件数不能太多、不能太少、文件大小不能太大等等,最理想的情况是,选取那些承载IO负载重、文件小的文件集,实际实现中,HBase提供了多个文件选取算法: RatioBasedCompactionPolicy、ExploringCompactionPolicy和 StripeCompactionPolicy 等,用户也可以通过特定接口实现自己的Compaction算法;选出待合并的文件后,HBase会根据这些hfile文件总大小挑选对应的线程池处理, 最后对这些文件执行具体的合并操作。可以通过下图简单地梳理上述流程: 33 触发时机 HBase中可以触发compaction的因素有很多,最常见的因素有这么三种: Memstore Flush、后台线程周期性检查、手动触发。 Memstore Flush: 应该说compaction操作的源头就来自flush操作,memstore flush会产生HFile文件,文件越来越多就需要compact。因此在每次执行完Flush操作之后,都会对当前Store中的文件数进行判断,一旦文件数# > ,就会触发compaction。需要说明的是,compaction都是以Store为单位进行的,而在Flush触发条件下,整个Region的所有Store都会执行compact,所以会在短时间内执行多次compaction。 后台线程周期性检查: 后台线程CompactionChecker定期触发检查是否需要执行compaction,检查周期为: hbase.server.thread.wakefrequency_hbase.server.compactchecker.interval.multiplier。和flush不同的是,该线程优先检查文件数#是否大于,一旦大于就会触发compaction。如果不满足,它会接着检查是否满足major compaction条件,简单来说,如果当前store中hfile的最早更新时间早于某个值mcTime,就会触发major compaction,HBase预想通过这种机制定期删除过期数据。上文mcTime是一个浮动值,浮动区间默认为[7-7_0.2,7+7*0.2],其中7为hbase.hregion.majorcompaction,0.2为hbase.hregion.majorcompaction.jitter,可见默认在7天左右就会执行一次major compaction。用户如果想禁用major compaction,只需要将参数hbase.hregion.majorcompaction设为0 手动触发: 一般来讲,手动触发compaction通常是为了执行major compaction,原因有三,其一是因为很多业务担心自动major compaction影响读写性能,因此会选择低峰期手动触发;其二也有可能是用户在执行完alter操作之后希望立刻生效,执行手动触发major compaction;其三是HBase管理员发现硬盘容量不够的情况下手动触发major compaction删除大量过期数据;无论哪种触发动机,一旦手动触发,HBase会不做很多自动化检查,直接执行合并。 选择合适HFile合并 选择合适的文件进行合并是整个compaction的核心,因为合并文件的大小以及其当前承载的IO数直接决定了compaction的效果。最理想的情况是,这些文件承载了大量IO请求但是大小很小,这样compaction本身不会消耗太多IO,而且合并完成之后对读的性能会有显著提升。然而现实情况可能大部分都不会是这样,在0.96版本和0.98版本,分别提出了两种选择策略,在充分考虑整体情况的基础上选择最佳方案。无论哪种选择策略,都会首先对该Store中所有HFile进行一一排查,排除不满足条件的部分文件: 排除当前正在执行compact的文件及其比这些文件更新的所有文件 (SequenceId更大) 排除某些过大的单个文件,如果文件大小大于hbase.hzstore.compaction.max.size (默认Long最大值) ,则被排除,否则会产生大量IO消耗 经过排除的文件称为候选文件,HBase接下来会再判断是否满足major compaction条件,如果满足,就会选择全部文件进行合并。判断条件有下面三条,只要满足其中一条就会执行major compaction: ...

2017-07-07 · 1 min · 130 words · -

emacs rename file and buffer

emacs rename file and buffer https://stackoverflow.com/questions/384284/how-do-i-rename-an-open-file-in-emacs ;; source: http://steve.yegge.googlepages.com/my-dot-emacs-file (defun rename-file-and-buffer (new-name) “Renames both current buffer and file it’s visiting to NEW-NAME.” (interactive “sNew name: “) (let ((name (buffer-name)) (filename (buffer-file-name))) (if (not filename) (message “Buffer ‘%s’ is not visiting a file!” name) (if (get-buffer new-name) (message “A buffer named ‘%s’ already exists!” new-name) (progn (rename-file filename new-name 1) (rename-buffer new-name) (set-visited-file-name new-name) (set-buffer-modified-p nil))))))

2017-07-05 · 1 min · 65 words · -

sdkman

sdkman #install curl -s http://get.sdkman.io | bash sdk list gradle sdk install gradle sdk install gradle 4.2 sdk default gradle 4.2 http://blog.csdn.net/jjlovefj/article/details/51103578 1.sdkman介绍 sdkman(The Software Development Kit Manager), 中文名为:软件开发工具管理器.这个工具的主要用途是用来解决在类unix操作系统(如mac, Linux等)中多种版本开发工具的切换, 安装和卸载的工作.对于windows系统的用户可以使用Powershell CLI来体验. 例如: 项目A使用Jdk7中某些特性在后续版本中被移除 (尽管这是不好的设计) ,项目B使用Jdk8,我们在切换开发这两个项目的时候,需要不断的切换系统中的JAVA_PATH,这样很不方便,如果存在很多个类似的版本依赖问题,就会给工作带来很多不必要的麻烦. sdkman这个工具就可以很好的解决这类问题,它的工作原理是自己维护多个版本,当用户需要指定版本时,sdkman会查询自己所管理的多版本软件中对应的版本号,并将它所在的路径设置到系统PATH. 2.安装 直接打开终端,执行如下命令: $ curl -s http://get.sdkman.io | bash 上面的命令的含义: 首先sdkman官网下载对应的安装shell script,然后调用bash解析器去执行. 接下来,你需要打开一个新的终端窗口,执行命令: $ source “$HOME/.sdkman/bin/sdkman-init.sh” 再次之后,可以通过输入sdk help确认安装是否完成. jiangjian@jiangjian-ThinkPad-E450c:~$ sdk help Usage: sdk [candidate] [version] ...

2017-07-01 · 2 min · 292 words · -

/dev/net/tun,No such device

‘/dev/net/tun,No such device’ sudo pacman -Syu sudo pacman -S linux sudo modprobe tun modprobe: FATAL: Module tun not found in directory /lib/modules/4.6.3-1-ARCH sudo insmod /lib/modules/4.6.4-1-ARCH/kernel/drivers/net/tun.ko.gz lsmod | grep tun tun 28672 0 https://bbs.archlinux.org/viewtopic.php?id=184992

2017-06-30 · 1 min · 33 words · -

Java TreeMap, 红黑树, Red–black tree, R-B Tree

Java TreeMap, 红黑树, Red–black tree, R-B Tree java.util.TreeMap TreeMap<String,Integer> treeMap = new TreeMap<String,Integer>(); System.out.println("初始化后,TreeMap元素个数为: " + treeMap.size()); //新增元素: treeMap.put("hello",1); treeMap.put("world",2); 红黑树 TreeMap的实现是红黑树算法的实现,所以要了解TreeMap就必须对红黑树有一定的了解,其实这篇博文的名字叫做: 根据红黑树的算法来分析TreeMap的实现,但是为了与Java提高篇系列博文保持一致还是叫做TreeMap比较好。通过这篇博文你可以获得如下知识点: 红黑树的基本概念。 红黑树增加节点、删除节点的实现过程。 红黑树左旋转、右旋转的复杂过程。 Java 中 TreeMap是如何通过put、deleteEntry两个来实现红黑树增加、删除节点的。 我想通过这篇博文你对TreeMap一定有了更深的认识。好了,下面先简单普及红黑树知识。 红黑树简介 红黑树又称红-黑二叉树,它首先是一颗二叉树,它具有二叉树所有的特性。同时红黑树更是一颗自平衡的排序二叉树。 我们知道一颗基本的二叉树他们都需要满足一个基本性质-即树中的任何节点的值大于它的左子节点,且小于它的右子节点。按照这个基本性质使得树的检索效率大大提高。我们知道在生成二叉树的过程是非常容易失衡的,最坏的情况就是一边倒 (只有右/左子树) ,这样势必会导致二叉树的检索效率大大降低 (O(n)) ,所以为了维持二叉树的平衡,大牛们提出了各种实现的算法,如: AVL,SBT,伸展树,TREAP, 红黑树等等。 平衡二叉树必须具备如下特性: 它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。也就是说该二叉树的任何一个子节点,其左右子树的高度都相近。 红黑树顾名思义就是节点是红色或者黑色的平衡二叉树,它通过颜色的约束来维持着二叉树的平衡。对于一棵有效的红黑树二叉树而言我们必须增加如下规则: 节点是红色或者黑色的 根节点是黑色 每个叶子节点 (NIL节点(空节点)) 是黑色的。 如果一个结点是红的,则它两个子节点都是黑的。也就是说在一条路径上不能出现相邻的两个红色结点。 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。 这些约束强制了红黑树的关键性质: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。结果是这棵树大致上是平衡的。因为操作比如插入、删除和查找某个值的最坏情况时间都要求与树的高度成比例,这个在高度上的理论上限允许红黑树在最坏情况下都是高效的,而不同于普通的二叉查找树。所以红黑树它是复杂而高效的,其检索效率O(log n)。下图为一颗典型的红黑二叉树。 对于红黑二叉树而言它主要包括三大基本操作: 左旋、右旋、着色。 左旋 右旋 (图片来自: http://www.cnblogs.com/yangecnu/p/Introduce-Red-Black-Tree.html) 本节参考文献: http://baike.baidu.com/view/133754.htm?fr=aladdin–百度百科 注: 由于本文主要是讲解Java中TreeMap,所以并没有对红黑树进行非常深入的了解和研究,如果诸位想对其进行更加深入的研究Lz提供几篇较好的博文: 红黑树系列集锦 红黑树数据结构剖析 红黑树 二、TreeMap数据结构 ...

2017-06-28 · 7 min · 1371 words · -

ForkJoin

ForkJoin ForkJoinPool 适合执行计算密集型且可进行拆分任务并汇总结果(类似MapReduce)的任务,执行这种任务可以充分利用多核处理器优势提高任务处理速度,实际上 ForkJoinPool 内部的工作窃取队列的高性能 (远高于普通线程池的BlockingQueue) 也决定其适用于执行大量的简短的小任务。 ———————————————— 版权声明:本文为CSDN博主「heng_zou」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/heng_zou/article/details/118193846 什么是 Fork/Join 框架 Fork/Join 框架是 Java7 提供的一个用于并行执行任务的框架(Fork/Join Framework), 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。 我们再通过 Fork 和 Join 这两个单词来理解下 Fork/Join 框架,Fork 就是把一个大任务切分为若干子任务并行的执行,Join 就是合并这些子任务的执行结果,最后得到这个大任务的结果。比如计算 1+ 2+… + 10000,可以分割成 10 个子任务,每个子任务分别对 1000 个数进行求和,最终汇总这 10 个子任务的结果。 ForkJoinPool http://blog.dyngr.com/blog/2016/09/15/java-forkjoinpool-internals/ ForkJoinPool 不是为了替代 ExecutorService, 而是它的补充, 在某些应用场景下性能比 ExecutorService 更好。 (见 Java Tip: When to use ForkJoinPool vs ExecutorService ) https://www.infoworld.com/article/2078440/java-tip-when-to-use-forkjoinpool-vs-executorservice.html ForkJoinPool 主要用于实现"分而治之"的算法, 特别是分治之后递归调用的函数, 例如 quick sort 等。 [[quick-sort]] ForkJoinPool 最适合的是计算密集型的任务, 如果存在 I/O, 线程间同步, sleep() 等会造成线程长时间阻塞的情况时, 最好配合使用 ManagedBlocker ...

2017-06-22 · 4 min · 721 words · -

pstack

pstack http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/pstack.html pstack 跟踪进程栈 此命令可显示每个进程的栈跟踪。pstack 命令必须由相应进程的属主或 root 运行。可以使用 pstack 来确定进程挂起的位置。此命令允许使用的唯一选项是要检查的进程的 PID。请参见 proc(1) 手册页。 这个命令在排查进程问题时非常有用,比如我们发现一个服务一直处于work状态 (如假死状态,好似死循环) ,使用这个命令就能轻松定位问题所在;可以在一段时间内,多执行几次pstack,若发现代码栈总是停在同一个位置,那个位置就需要重点关注,很可能就是出问题的地方; 示例: 查看bash程序进程栈: /opt/app/tdev1$ps -fe| grep bash tdev1 7013 7012 0 19:42 pts/1 00:00:00 -bash tdev1 11402 11401 0 20:31 pts/2 00:00:00 -bash tdev1 11474 11402 0 20:32 pts/2 00:00:00 grep bash /opt/app/tdev1$pstack 7013 #0 0x00000039958c5620 in __read_nocancel () from /lib64/libc.so.6 #1 0x000000000047dafe in rl_getc () #2 0x000000000047def6 in rl_read_key () #3 0x000000000046d0f5 in readline_internal_char () ...

2017-06-10 · 1 min · 116 words · -

strace, 跟踪进程中的系统调用

strace, 跟踪进程中的系统调用 sudo pacman -S strace 统计系统调用的耗时 strace -cp <PID> http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/strace.html strace 跟踪进程中的系统调用 strace 常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。 输出参数 每一行都是一条系统调用,等号左边是系统调用的函数名及其参数,右边是该调用的返回值。 strace 显示这些调用的参数并返回符号形式的值。strace 从内核接收信息,而且不需要以任何特殊的方式来构建内核。 strace cat /dev/null execve("/bin/cat", [“cat”, “/dev/null”], [/* 22 vars */]) = 0 brk(0) = 0xab1000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f29379a7000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) … 参数 -c 统计每一系统调用的所执行的时间,次数和出错的次数等. -d 输出strace关于标准错误的调试信息. -f 跟踪由fork调用所产生的子进程. -ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号. -F 尝试跟踪vfork调用.在-f时,vfork不被跟踪. -h 输出简要的帮助信息. -i 输出系统调用的入口指针. ...

2017-06-08 · 1 min · 205 words · -

CPU 使用率, 服务器负载

CPU 使用率, 服务器负载 http://www.jianshu.com/p/e134b8498413 load average: 系统平均负载是 CPU 的L oad, 它所包含的信息不是 CPU 的使用率状况, 而是在一段时间内 CPU 正在处理以及等待 CPU 处理的进程数之和的统计信息, 也就是 CPU 使用队列的长度的统计信息, 这个数字越小越好。 CPU 负载和 CPU 使用率的区别 CPU 使用率: 显示的是程序在运行期间实时占用的 CPU 百分比 CPU 负载: 显示的是一段时间内正在使用和等待使用 CPU 的平均任务数 CPU使用率高, 并不意味着负载就一定大。 举例来说: 如果我有一个程序它需要一直使用CPU的运算功能,那么此时CPU的使用率可能达到100%,但是CPU的工作负载则是趋近于"1",因为CPU仅负责一个工作嘛!如果同时执行这样的程序两个呢?CPU的使用率还是100%,但是工作负载则变成2了。所以也就是说,当CPU的工作负载越大,代表CPU必须要在不同的工作之间进行频繁的工作切换。 举例说明: 网上有篇文章举了一个有趣比喻,拿打电话来说明两者的区别,我按自己的理解阐述一下。 某公用电话亭,有一个人在打电话,四个人在等待,每人限定使用电话一分钟,若有人一分钟之内没有打完电话,只能挂掉电话去排队,等待下一轮。电话在这里就相当于CPU,而正在或等待打电话的人就相当于任务数。 在电话亭使用过程中,肯定会有人打完电话走掉,有人没有打完电话而选择重新排队,更会有新增的人在这儿排队,这个人数的变化就相当于任务数的增减。为了统计平均负载情况,我们5分钟统计一次人数,并在第1、5、15分钟的时候对统计情况取平均值,从而形成第1、5、15分钟的平均负载。 有的人拿起电话就打,一直打完1分钟,而有的人可能前三十秒在找电话号码,或者在犹豫要不要打,后三十秒才真正在打电话。如果把电话看作CPU,人数看作任务,我们就说前一个人(任务)的CPU利用率高,后一个人(任务)的CPU利用率低。 当然, CPU并不会在前三十秒工作,后三十秒歇着,只是说,有的程序涉及到大量的计算,所以CPU利用率就高,而有的程序牵涉到计算的部分很少,CPU利用率自然就低。 结论: 无论CPU的利用率是高是低,跟后面有多少任务在排队没有必然关系。 负载为多少才算比较理想? 这个有争议,各有各的说法,个人比较赞同CPU负载小于等于0.5算是一种理想状态。 不管某个CPU的性能有多好,1秒钟能处理多少任务,我们可以认为它无关紧要,虽然事实并非如此。在评估CPU负载时,我们只以5分钟为单位为统计任务队列长度。如果每隔5分钟统计的时候,发现任务队列长度都是1,那么CPU负载就为1。假如我们只有一个单核的CPU,负载一直为1,意味着没有任务在排队,还不错。 但是我那台服务器,是双核双CPU,等于是有4个内核,每个内核的负载为1的话,总负载为4。这就是说,如果我那台服务器的CPU负载长期保持在4左右,还可以接受。 但是每个内核的负载为1,并不能算是一种理想状态!这意味着我们的CPU一直很忙,不得清闲。网上有说理想的状态是每个内核的负载为0.7左右,我比较赞同,0.7乘以内核数,得出服务器理想的CPU负载,比如我这台服务器,负载在3.0以下就可以。 如何来降低服务器的CPU负载? 最简单办法的是更换性能更好的服务器,不要想着仅仅提高CPU的性能,那没有用,CPU要发挥出它最好的性能还需要其它软硬件的配合。 在服务器其它方面配置合理的情况下,CPU数量和CPU核心数(即内核数)都会影响到CPU负载,因为任务最终是要分配到CPU核心去处理的。两块CPU要比一块CPU好,双核要比单核好。 因此,我们需要记住,除去CPU性能上的差异,CPU负载是基于内核数来计算的!有一个说法,“有多少内核,即有多少负载”。 CPU使用率到多少才算比较理想? CPU使用率长时间60-80%就认为机器有瓶颈出现。 2.load average 多少是正常? 既然load是cpu计算的队列,那就应该和cpu个处理方式和cpu的个数有关系。所以我个人认为应该按系统识别的cpu个数来确定load的临界值,系统识别为8个cpu,那么load为8就是临界点,高于8就属于over load了。 什么叫系统识别CPU个数? 这里涉及到cpu物理个数和超线程技术的问题。对于单处理器在满负载的情况下1.00,则双处理器的负载满额的情况是 2.00,它还有一倍的资源可以利用。从性能的角度上理解,一台主机拥有多核心的处理器与另台拥有同样数目的处理性能基本上可以认为是相差无几。当然实际 情况会复杂得多,不同数量的缓存、处理器的频率等因素都可能造成性能的差异。但即便这些因素造成的实际性能稍有不同,其实系统还是以处理器的核心数量计算负载均值 。这使我们有了两个新的法则: ...

2017-06-08 · 1 min · 92 words · -

Parallel Scavenge

Parallel Scavenge Parallel Scavenge收集器的特点是它的关注点与其他收集器不同,CMS等收集器的关注点尽可能地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量 (Throughput) 。所谓吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间) ,虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。 停顿时间越短就越适合需要与用户交互的程序,良好的响应速度能提升用户的体验;而高吞吐量则可以最高效率地利用CPU时间,尽快地完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务。 Parallel Scavenge收集器提供了两个参数用于精确控制吞吐量,分别是控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis参数及直接设置吞吐量大小的 -XX:GCTimeRatio参数。 MaxGCPauseMillis参数允许的值是一个大于0的毫秒数,收集器将尽力保证内存回收花费的时间不超过设定值。不过大家不要异想天开地认为如果把这个参数的值设置得稍小一点就能使得系统的垃圾收集速度变得更快,GC停顿时间缩短是以牺牲吞吐量和新生代空间来换取的: 系统把新生代调小一些,收集300MB新生代肯定比收集500MB快吧,这也直接导致垃圾收集发生得更频繁一些,原来10秒收集一次、每次停顿100毫秒,现在变成5秒收集一次、每次停顿70毫秒。停顿时间的确在下降,但吞吐量也降下来了。 GCTimeRatio参数的值应当是一个大于0小于100的整数,也就是垃圾收集时间占总时间的比率,相当于是吞吐量的倒数。如果把此参数设置为19,那允许的最大GC时间就占总时间的5% (即1 / (1+19) ) ,默认值为99,就是允许最大1% (即1 / (1+99) ) 的垃圾收集时间。 由于与吞吐量关系密切,Parallel Scavenge收集器也经常被称为"吞吐量优先"收集器。除上述两个参数之外,Parallel Scavenge收集器还有一个参数-XX:+UseAdaptiveSizePolicy值得关注。这是一个开关参数,当这个参数打开之后,就不需要手工指定新生代的大小 (-Xmn) 、Eden与Survivor区的比例 (-XX:SurvivorRatio) 、晋升老年代对象年龄 (-XX:PretenureSizeThreshold) 等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或最大的吞吐量,这种调节方式称为GC自适应的调节策略 (GC Ergonomics) 。如果读者对于收集器运作原理不太了解,手工优化存在困难的时候,使用Parallel Scavenge收集器配合自适应调节策略,把内存管理的调优任务交给虚拟机去完成将是一个很不错的选择。只需要把基本的内存数据设置好 (如-Xmx设置最大堆) ,然后使用MaxGCPauseMillis参数 (更关注最大停顿时间) 或GCTimeRatio参数 (更关注吞吐量) 给虚拟机设立一个优化目标,那具体细节参数的调节工作就由虚拟机完成了。自适应调节策略也是Parallel Scavenge收集器与ParNew收集器的一个重要区别。 HotSpot VM里多个GC有部分共享的代码。有一个分代式GC框架,Serial/Serial Old/ParNew/CMS都在这个框架内;在该框架内的young collector和old collector可以任意搭配使用,所谓的"mix-and-match"。 而ParallelScavenge与G1则不在这个框架内,而是各自采用了自己特别的框架。这是因为新的GC实现时发现原本的分代式GC框架用起来不顺手。请参考官方文档的Collector Styles一段。 ParallelScavenge (PS) 的young collector就如其名字所示,是并行的拷贝式收集器。本来这个young collector就是"Parallel Scavenge"所指,但因为它不兼容原本的分代式GC框架,为了凸显出它是不同的,所以它的young collector带上了PS前缀,全名变成PS Scavenge。对应的,它的old collector的名字也带上了PS前缀,叫做PS MarkSweep。 这个PS MarkSweep默认的实现实际上是一层皮,它底下真正做mark-sweep-compact工作的代码是跟分代式GC框架里的serial old (这个collector名字叫做MarkSweepCompact) 是共用同一份代码的。也就是说实际上PS MarkSweep与MarkSweepCompact在HotSpot VM里是同一个collector实现,包了两张不同的皮;这个collector是串行的。 ...

2017-06-05 · 1 min · 153 words · -