HashMap源码分析
基本原理HashMap是由数组Node<K,V>[] table 和链表(或者树)组成的一个复合结构。
数组被分成一个个的桶(buket),通过下面的这个算法决定元素在桶中的位置:
12// n为数组长度,hash为key的哈希值p = tab[i = (n - 1) & hash]
若p相同,则以链表形式存储。当链表长度超过阈值(TREEIFY_THRESHOLD=8)时,则将链表转换为红黑树。
此处为什么需要这么做?
主要是基于查询的效率考虑。链表查询元素的时间复杂度为O(n),随着链表长度的增大,查询时间也会递增。而红黑树的时间复杂度为O(logn),此处是一个以空间换时间的典型案例。
HashMap中几个特殊值说明:
initialCapacity:HashMap初始容量,默认为16
loadFactor:负载因子,默认0.75
threshold:键值对数量的最大值(不是table数组的长度),超过这个值,则需要扩容,会变为原先值的两倍
TREEIFY_THRESHOLD:链表转换红黑树阈值,默认为8, 当超过该值时, 链表就会转换为红黑树 ...
java大图片压缩与裁剪时防止oom
常规使用java进行图片裁剪或压缩的时候, 比如使用ImageIO.read()读取图片信息的时候, 或者使用Thumb nails框架进行压缩时, 都会调用DataBufferByte类的下面这个方法:
12345678910public DataBufferByte(int size, int numBanks) { super(STABLE, TYPE_BYTE, size, numBanks); bankdata = new byte[numBanks][]; for (int i= 0; i < numBanks; i++) { // 构造数组 bankdata[i] = new byte[size]; } data = bankdata[0];}
当图片像素很大时, size的值会很大, 此时构造这个数据就有可能会出现oom,比如当一张6.4M的图片, 宽高是5472*7296, size的值是114M。
基于此, ...
arthas中如何获取Bean
现在大部分应用都是通过Spring来管理对象, 在使用arthas分析线上问题时, 如何获取Spring中已经注入到容器中的Bean, 主要是使用tt命令。
首先执行如下命令,等待输出
1tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod -n 3
假设要搜索的类名为com.example.DemoService, 注意此处需要使用类的全限定名。
1tt -i 1000 -w 'target.getApplicationContext().getBean("com.example.DemoService").getTargetSource().target'
arthas的一些使用技巧
arthas获取spring中的bean现在大部分应用都是通过Spring来管理对象, 在使用arthas分析线上问题时, 如何获取Spring中已经注入到容器中的Bean, 主要是使用tt命令。
首先执行如下命令,等待输出
1tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod -n 3
假设要搜索的类名为com.example.DemoService, 注意此处需要使用类的全限定名。
1tt -i 1000 -w 'target.getApplicationContext().getBean("com.example.DemoService").getTargetSource().target'
arthas获取http请求的入参和出参有时我们需要线上跟踪某个请求的入参和出参, 此时可以使用arthas的watch命令。
基于spring的工程,所有请求都会走Request ...
Linux中文件权限说明
概述
Linux下的文件权限包括读, 写, 执行, 英文简写分别是 r, w, x
文件权限包含三个方面: 拥有者, 用户组, 其他组。每个文件可分别对这三个方面设置不同的rwx权限。通常情况下,一个文件只能归属于一个用户和组, 如果其它的用户想有这个文件的权限,则可以将该用户加入具备权限的群组,一个用户可以同时归属于多个组。
查看文件权限ls -l
输出格式如下:
-rw-r--r-- 1 root root 25934 Jun 26 10:35 X120
其中第一列除了第一个表示文件类型外, 剩下9个则表示该文件在上面三个粒度下的权限,具体信息
2,3,4列表示文件所有者权限
5,6,7列表示该文件所属用户组的权限
7,8,9列表示其他组的权限
更改文件权限chmod命令, 其参数如下:
-R 以递归的方式对目前目录下的所有档案与子目录进行相同的权限变更
下面只介绍一下使用数字来表示的权限使用方法。
基本规定如下:
4 读r
2 写w
1 执行x
其他的权限组合用这几个进行相加就行, 示例如下:
7 可读+可写+可执行 rwx (4+2+1=7)
6 ...
Shell语法参考
几点注意事项
一次执行多条命令,可以有如下三种方法, 其区别如下:
分号: 顺序地独立执行各条命令, 彼此之间不关心是否失败, 所有命令都会执行
&& : 顺序执行各条命令, 只有当前一个执行成功时候, 才执行后面的
|| : 顺序执行各条命令, 只有当前面一个执行失败的时候, 才执行后面的
设置shell脚本遇到错误时自动退出, 不执行后续命令
1#!/bin/bash -e 或者 set -e
特殊符号使用12345678910> 覆写原先的内容>> 在原先的内容后追加$? 前一个命令或者函数的返回码, 0表示执行成功$1 表示第一个参数,$2 表示第二个$# 命令行参数的个数$0 当前程序的名称$* 以"参数1 参数2 ..."的形式保存所有参数$ 本程序进程PID$! 上一个命令的PID脚本内取得输入命令时的参数: $n n代表第几个参数
特殊文件
/dev/null 重定向到此文件的数据都会被系统丢掉
/dev/tty 自动重定向到一个终端
函数使用
注意: ...
Linux常用命令参考
当做个人字典使用, 会进行不定期更新!
tar打包与压缩命令。
常用参数:
-c (–create) 建立新的备份文件
-x (–extract) 从备份文件中还原文件
-z (–gzip或–ungzip) 通过gzip指令处理备份文件
-v (–verbose) 输出执行过程中的详细信息
-f (–file) 指定备份文件
12345# 将/home文件夹下所有内容打包压缩成home.tar.gz文件tar -czvf home.tar.gz /home# 将home.tar.gz文件解压到当前目录tar -xzvf home.tar.gz
getops该命令可以用来解析命令行参数。
以下表示获取命令行参数 -d -t的值
1234567891011while getopts 'd:t:' OPT; do case $OPT in d) echo "d $OPTARG" exit 0;; t) echo "t $OPTARG";; ?) ec ...
docker安装confluence
自己搭建一个confluence wiki,现记录一下搭建过程和其中需要注意的点。
编写docker-compose12345678910111213141516171819202122232425version: '3'services: db: image: postgres:latest container_name: confluence-db ports: - "15202:5432" restart: always environment: - POSTGRES_PASSWORD=123456 volumes: - /opt/docker/confluence/pgsql-data:/var/lib/postgresql/data confluence: image: cptactionhank/atlassian-confluence:latest container_name: confluence ports: - "15 ...
红米AC2100刷pandavan及设置无线中继
获取SSH权限
打开本地浏览器输入192.168.31.1并登陆。
右上角选择固件升级, 升级到有漏洞版本2.0.7( 文件名:miwifi_rm2100_firmware_d6234_2.0.7.bin)
刷完重启后重新输入192.168.31.1登陆管理页,此时的浏览器地址栏如下(注意stock=后面的值每个人是不一样的):
http://192.168.31.1/cgi-bin/luci/;stok=ODJ893023kd2344224kdF/web/home#router
将stok=ODJ893023kd2344224kdF显示的值 复制替换到如下链接对应位置并浏览器打开:http://192.168.31.1/cgi-bin/luci/;stok=你浏览器显示的值/api/misystem/set_config_iotdev?bssid=Xiaomi&user_id=longdike&ssid=-h%3B%20nvram%20set%20ssh_en%3D1%3B%20nvram%20commit%3B%20sed%20-i%20's ...
spring中的设计模式
本文结合spingboot的源码描述一下spring中运用到的几种点典型的设计模式。
工厂模式本身也能产生bean, 例如其中一个实现类:```AbstractFactoryBean```,123456789101112131415getObject()方法源码如下:```java @Override public final T getObject() throws Exception { //单例从缓存中获取或者暴露引用(用来解决循环引用) if (isSingleton()) { return (this.initialized ? this.singletonInstance : getEarlySingletonInstance()); } else { //创建实例 return createInstance(); } }
其最终创建实例的方法是createInstance, 该方法由其子类工厂去实现, 具体的子类有如下几种:
例如mybatis的SqlSes ...