本文所有源码来自 JDK 1.8.0_181 HashMap简介 Map是Key-Value对映射的抽象接口,Map用于保存具有映射关系的数据。Map集合里有两组值,一组值用于保存Map里的key,另外一组值用于保存Map里的value,key和value都可以是任何引用类型的数据。key不允许重复,key和value之间存在单向一对一关系,通过key能找到相应的value。 HashMap是基于哈希表的Map接口的实现,以Key-Value的形式存在,即存储的对象是Entry(同时包含了Key和Value)。在HashMap中,根据hash算法来计算key-value的存储位置并进行快速存取。最多只允许一条Entry的键为Null,但允许多条Entry的值为Null。此外,HashMap是线程不安全的。 结构示意 当链表达到一定长度时会进行树化。 理想状态下哈希表的每个箱子中,元素的数量遵守泊松分布: 当负载因子为 0.75 时,上述公式中 λ 约等于 0.5,因此箱子中元素个数和概率的关系如 继续阅读 >>


李猛 18/08/24 15:25:44
引入 与很多高校一样,西安皇家邮电大学一直钟爱于正方教务管理系统。 前一段时间爬了学校的旧版的教务系统,旧版主页 想了解更多请点击这里:爬取学校教务系统获取学生信息 不知道学校是不是把装空调的拿去买新教务系统了,新教务系统主页 可以看出,学校用的仍然是正方教务系统,不过版本升级了,新教务系统是用Java写的后台,前端用了Bootstrap框架。与旧系统相比,界面美观大方,易用性也明显提高。 准备 模拟登陆前,我们首先要清楚需要提交那些数据。 打开F12,我们在访问主页时,除了加载了JS的HTML还向服务器发送了一个get请求。 直接访问它可以获取一个json: {"exponent":"AQAB","modulus":"AIMNm8zi5XkWLRDUy7w6bjypS+d8ng7an00UYH8UZMhUvrDAvpuifsFu+rU6dmMFQHpHGo9ZlyEy9GWy6ev3s8ro15869OIKo\/nwexEnb8AD0DO7NaV9jzDjqRj 继续阅读 >>


李猛 18/08/20 10:00:19
引入 前一段时间爬了学校的旧版的教务系统,想了解更多请点击这里:爬取学校教务系统获取学生信息 旧版教务系统主页 不知道学校是不是把装空调的拿去买新教务系统了,新教务系统主页 可以看出,学校用的仍然是正方教务系统,不过这是新的版本。新教务系统是后台是用Java写的,前端用了Bootstrap等,比就系统好看多了,易用性也明显提高。 准备 模拟登陆前,我们首先要清楚需要提交那些数据。 打开F12,我们在访问主页时,除了加载了JS的HTML还向服务器发送了一个get请求。 直接访问它可以获取一个json: {"exponent":"AQAB","modulus":"AIMNm8zi5XkWLRDUy7w6bjypS+d8ng7an00UYH8UZMhUvrDAvpuifsFu+rU6dmMFQHpHGo9ZlyEy9GWy6ev3s8ro15869OIKo\/nwexEnb8AD0DO7NaV9jzDjqRjEldAs5ct9pdjo7SxQccJYfSbFbwb6206w1q4 继续阅读 >>


李猛 18/08/18 17:59:04
一、问题描述 生产者消费者问题(Producer-consumer problem),也称有限缓冲问题(Bounded-buffer problem),是一个多线程同步问题的经典案例。生产者生成一定量的数据放到缓冲区中,然后重复此过程;与此同时,消费者也在缓冲区消耗这些数据。生产者和消费者之间必须保持同步,要保证生产者不会在缓冲区满时放入数据,消费者也不会在缓冲区空时消耗数据。不够完善的解决方法容易出现死锁的情况,此时进程都在等待唤醒。 示意图: 二、解决方法 思路 采用某种机制保护生产者和消费者之间的同步。有较高的效率,并且易于实现,代码的可控制性较好,属于常用的模式。 在生产者和消费者之间建立一个管道。管道缓冲区不易控制,被传输数据对象不易于封装等,实用性不强。 解决问题的核心    保证同一资源被多个线程并发访问时的完整性。常用的同步方法是采用信号或加锁机制,保证资源在任意时刻至多被一个线程访问。 Java能实现的几种方法 wait() / noti 继续阅读 >>


李猛 18/08/16 08:40:50
关于Java线程的状态网上的说法不一,有的说是6种状态,有的说是5中状态,索性就查看了一下Java源码。Thread类里面有一个枚举类,如下: public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; } 这个枚举类里面有6种类型,所以Java中的线程有6种状态。 关于各种状态的简单说明: NEW(初始):线程被创建后尚未启动。 RUNNABLE(运行):包括了操作系统线程状态中的Running和Ready,也就是处于此状态的线程可能正在运行,也可能正在等待系统资源,如等待CPU为它分配时间片。 BLOCKED(阻塞):线程阻塞于锁。 WAITING(等待):线程需要等待其他线程做出一些特定动作(通知或中断)。 TIME_WAITING(超时等待):该状态不同于WAITING,它可以在指定的时间内自行返回。 TERMINATED(终止):该线 继续阅读 >>


李猛 18/08/15 08:19:50
本以为JVM中有一个强大的垃圾收集器,能够实时监控资源并即时清除已经死掉的对象。事实上直到现在为止还没有万能的收集器,我们选择的只是对具体应用最合适的收集器,下面就简单说说集中收集器吧。 Serial 收集器 最基本、发展历史最悠久的收集器,在JDK 1.3.1之前是虚拟机新生代收集的唯一选择。它是一个单线程收集器,在它就行垃圾收集工作时,必须暂停其他所有的线程,直到它收集结束。 具有简单高效的优点(没有线程交互的开销),现在依然是虚拟机运行在Client模式下的默认新生代收集器。 ParNew 收集器 Serial收集器的多线程版本,除了多线程收集之外,与Serial相比并没有太多创新。除了Serial收集器外,目前只有ParNew收集器能与CMS收集器配合工作,是运行在Server模式下虚拟机中首选的新生代收集器。 在单CPU的环境下,ParNew收集器不会比Serial收集器有更好的效果,但是随着CPU数量的增加,对GC时系统资源的有效利用还是有很多好处的。 Parallel 继续阅读 >>


李猛 18/08/14 08:51:34
一、 对象已死嘛 引用计数法 给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被利用的。 引用计数法的实现简单,判定效率也高,但是它很难解决对象间相互循环引用的问题。 比如对象A和B都有字段instance,赋值令A.instance = B且B.instance = A,除此之外,这两个对象再无任何引用。实际上这两个对象已经不可能再被访问,但是它们因为互相引用着对方,导致它们的引用计数都不为0,于是引用计数法无法通知GC收集器回收它们。 可达性分析算法 通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则表明此对象是不可用的。 可作为GC Roots的对象包括下面几种: 虚拟机栈(栈帧中的本地变量表)中引用的对象 方法区中类静态属性、常量引用的对象 本地方法栈中JNI引用的对象 引用 继续阅读 >>


李猛 18/08/10 15:04:26
一、运行时的数据区域 程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。每个线程都有一个独立的程序计数器,彼此间计数器互不影响,独立存储,即是“线程私有”的内存。 在虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、跳转、循坏、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。 当线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果执行的是Native方法,这个计数器的值则为空,此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。 Native关键字说明其修饰的方法是一个原生态的方法,方法对应的实现不是在当前文件,而是在用其他语言(入C、C++等)实现的文件。Java语言本身不能对操作系统底层进行访问和操作,但可以通过JNI(Java Native In 继续阅读 >>


李猛 18/08/08 08:20:41
synchronized 同步方法 方法内的变量线程安全,实例变量非线程安全。调用关键字synchronized声明的方法一定是排队运行的,如果不是共享资源,那么根本就没有同步的需要。 关键字synchronized取得的锁都是对象锁,而不是把一段代码或方法(函数)当做锁。对于多线程访问同一对象,哪个对象先执行带synchronized关键字的方法,哪个线程就持有该方法所属对象的锁Lock,其他线程就只能等待;但是如果多个线程访问多个对象,则JVM会创建多个锁。 A线程先持有object对象的Lock锁,B线程可以以异步的方式调用object对象中的非synchronized类型的方法;但B线程如果在这时调用object对象中的synchronized类型的方法需要等待,也就是同步。 脏读是指在读取实例变量时,此值已经被其他线程更改过了。对于实例变量的getValue和setValue方法都要是同步的才能保证不出现脏读。 关键字synchronized拥有锁重入的功能,也就是在使用synchr 继续阅读 >>


李猛 18/08/06 19:22:51
上篇博文写到爬取教务系统获取信息时,登录时的验证码是手动输入的,所以就想试试能不能自别识别验证码并填充。查阅了很多信息,选取了Tesseract。 What is Tesseract ? Tesseract是能够运行在多种操作系统上的开源ORC(Optical Character Recognition , 光学字符识别)引擎,目前由Google维护,是最精确的开源ORC引擎之一。与Microsoft Office Document Imaging(MODI)相比,我们可以不断地训练,使图像转换文本的能力不断增强;如果团队深度需要,还能以它为模板,开发出符合自身需求的OCR引擎。 How to use Tesseract 1. 安装 ubuntu 下可以直接进行安装 sudo apt-get install tesseract-ocr 安装图像解析的包 sudo apt-get install libpng12-dev sudo apt-get install lib 继续阅读 >>


李猛 18/07/28 16:17:30