Java
情谊风月
溪云初起日沉阁,山雨欲来风满楼
展开
-
GC IN Java
CMS唯一组合方式young:ParNewold:CMS(失败时降为Serial)启动Parallel GC(parallel scavenge garbage collector)时默认启动ParallelOldGC,反之亦然。也可以显示禁用某一个,此时替换为Serial-XX:+UseParallelGC -XX:-UseParallelOldGC年轻代采用的都是复制算法,都...原创 2019-02-17 01:21:35 · 250 阅读 · 0 评论 -
约瑟夫环问题
问题描述:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号1的人开始报数,数到k的人出局;下一个人又从1开始报数,数到k的人出局。依此规律重复下去,直到只剩下一个人。求每次出局的人的编号及最后剩下的人的编号。解析:题目要求输出每次出局的人的编号,因此采用模拟法模拟过程。以5个人为例,从第一个人开始报数,数到3的人出局。过程如下:循环链表解法可以采用循环链表解决约瑟...原创 2018-10-20 23:58:12 · 964 阅读 · 0 评论 -
Java 创建对象的五种方式
对初学Java的人来说,这个问题可能有点奇怪,创建对象不就是通过 new 关键字,还有其它方式吗?事实上,Java中有五种方法可以用来创建对象,每种方法都有其用途: new 关键字,会调用构造方法 clone() 方法,不会调用构造方法 反序列化方式,不会调用构造方法 Class 对象的 newInstance() 方法,会调用构造方法 Constructor 对象的 ne...原创 2018-10-20 00:05:43 · 254 阅读 · 0 评论 -
可重入锁之 ReentrantLock
自Java 5之后,java.util.concurrent.locks 包中的 Lock 接口提供了一种新的方式来实现同步访问。Lock 接口提供了与 synchronized 类似的同步功能,但需要在使用时手动获取和释放锁。此外,Lock 接口更为灵活,提供了以下 synchronized 接口所不具备的特性: 超时获取锁:在指定时间内获取锁,超过时间仍未获得锁则返回 公平锁:可以...原创 2018-10-19 23:54:28 · 207 阅读 · 0 评论 -
双亲委派模型
Java 虚拟机中类加载的过程包括加载、验证、准备、解析、初始化五个阶段,其中验证、准备、解析三个阶段合起来又称为连接阶段。加载是类加载过程的第一个阶段,在加载阶段,虚拟机需要完成以下三件事情: 通过类的全限定名获取其定义的二进制字节流。 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。 在 Java 堆中生成一个代表这个类的 java.lang.Class 对象,作...原创 2018-10-15 23:56:57 · 485 阅读 · 1 评论 -
JVM 垃圾回收机制
垃圾回收(Garbage Collect,简称GC)是编程语言中提供的内存管理功能。在一些不具备GC的语言如 C++中,手动创建对象后需要在不使用该对象上手动释放它的内存空间,防止内存泄漏。另外一些语言如 Java、Python 等则无需手动管理内存,内置了垃圾回收机制,使开发人员从内存管理上解脱出来。在垃圾回收之前,首先要要找出死亡的对象,或者说仍旧存活的对象,存活对象的判定主要有如下两种算...原创 2018-10-14 12:22:32 · 224 阅读 · 0 评论 -
Java 并发工具类使用
java.util.concurrent 包从 JDK1.5 开始引入,目的是解决并发编程的线程安全问题,提供非常有用的并发工具类,包括 CountDownLatch、CyclicBarrier 与 Semaphore 等。在 concurrent 包下还有两个子包,一个是 atomic,包含一些原子类,可以解决原子性问题;另一个包是 locks,提供了并发包里线程安全的最为基础的工具——显示锁...原创 2018-10-14 12:10:29 · 268 阅读 · 0 评论 -
最大子序列和问题
最大子序列和是指,给定一组序列,如 [1,-3,2,4,5],求子序列之和的最大值,对于该序列来说,最大子序列之和为 2 + 4 + 5 = 11。这里的子序列要求是连续的,因此也可以称其为连续子数组最大和。有几种不同的方法求解最大子序列和问题,但它们的复杂度相差甚远,尤其在面对大量数据的时候。实际上,效率最高的算法非常简短,只需要几行代码,最主要的是理解它的思想。基本算法这是一种比较容...原创 2018-10-14 11:48:08 · 31842 阅读 · 6 评论 -
ThreadLocal 用途与使用场景
ThreadLocal,即线程变量,是一个以 ThreadLocal 对象为键、任意对象为值的存储结构。概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而 ThreadLocal 采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问;后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。ThreadLocal 类主要有如下方法: pr...原创 2018-10-14 11:12:52 · 7349 阅读 · 1 评论 -
Java 多线程通信
并发编程,一般指多线程编程,它可以充分利用计算机的计算资源,使得一个任务可以分为几个子模块同时执行,提高程序执行速度。然而,并不是启动越多线程,就能让程序执行越快,多线程同时带来了上下文切换、多线程间的通信与同步、死锁等问题。合理的利用多线程进行编程是一件有挑战性的事。Java自一开始就内置了对多线程的支持,在JDK1.5版本中引入了 java.util.concurrent 包,让 Java ...原创 2018-10-14 10:52:47 · 1342 阅读 · 0 评论 -
Java 新生代与老年代
Java 中的内存区域主要有堆和栈两部分。由于栈是线程私有,随着线程的结束而结束,因此垃圾回收主要在堆中进行,堆中几乎存放了 Java 中所有的对象实例。堆内存模型堆内存分为两大部分:新生代和老年代,比例关系为1:2。新生代又分为 Eden、ServivorFrom、ServivorTo 三个区域,比例为8:1:1。ServivorFrom 与 ServivorTo 又被称为幸存者区。...原创 2018-10-14 10:15:00 · 598 阅读 · 0 评论 -
Fork/Join 并行任务框架
如果现在要你编写计算 1! + 2! + 3! + 4! + … + 20! 的代码,你会怎么做?最自然的想法是从左边依次向右计算,不断迭代结果。毕竟对于人来说,一心二用还是比较难的,在同一时间只做一件事情是常见的场景。用代码来实现的话,示例如下:public class factorial { public static int compute(int n) { ...原创 2018-10-21 10:53:32 · 338 阅读 · 0 评论 -
原子性与可见性
Java 内存模型是围绕着原子性、可见性、有序性三个方面建立的,理解原子性与可见性有助于我们理解 Java 内存模型,加深对多线程编程的理解。原子性原子性指一个操作不能被打断,要么全部执行完毕,要么不执行。除了 long 和 double 型变量,java 内存模型确保访问任意类型变量所对应的内存单元都是原子的,包括引用类型的字段。long 和 double 类型的变量是64位。在32位...原创 2018-10-21 11:12:55 · 1149 阅读 · 0 评论 -
CPU缓存与伪共享(false sharing)
转载自云栖社区 - Java中的伪共享以及应对方案什么是伪共享CPU缓存系统中是以缓存行(cache line)为单位存储的。目前主流的CPU Cache 的 Cache Line 大小都是64Bytes。在多线程情况下,如果需要修改“共享同一个缓存行的变量”,就会无意中影响彼此的性能,这就是伪共享(False Sharing)。CPU的三级缓存由于CPU的速度远远大于内存速度,所以CPU...转载 2019-01-16 22:10:38 · 1124 阅读 · 0 评论 -
Linux下JDB断点调试&HSDB查看内存布局
JDK中提供了命令行下的断点调试工具:JDB。它可以调试正在运行或未运行的Java程序。现在我们编写一个Java程序public class Hello { private String s0 = "private"; public String s1 = "public"; public static String s2 = "static"; public static f..原创 2019-01-20 23:32:02 · 1786 阅读 · 0 评论 -
Metaspace 与 Compressed Class Space Size
Class MetadataJava classes have an internal representation within Java Hotspot VM and are referred to as class metadata. In previous releases of Java Hotspot VM, the class metadata was allocated in t...原创 2019-01-20 00:00:33 · 890 阅读 · 0 评论 -
Linux epoll 与多路复用
针对IO,总是涉及到阻塞、非阻塞、异步、同步以及select/poll和epoll的一些描述,那么这些东西到底是什么,有什么差异?一般来讲一个IO分为两个阶段:等待数据到达把数据从内核空间拷贝到用户空间现在假设一个进程/线程A,发出IO请求,有两种情况:立即返回由于数据未准备好,需要等待,让出CPU给别的线程,自己sleep第一种情况就是非阻塞,A为了知道数据是否准备好,需要...转载 2019-01-18 21:10:49 · 245 阅读 · 0 评论 -
SQL 、Java 与 Shell 中获取零点时间
在项目中我们可能需要统计昨日零点至今日零点的数据,这时需要根据当前时间计算零点时间。SQL (Vertica)SELECT extract(epoch from 'today');Java 获取零点时间// 今日零点LocalDateTime zeroTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);// 昨日零...原创 2018-11-18 13:54:58 · 1671 阅读 · 1 评论 -
NIO 通信示例
在之前的三篇文章中介绍了 NIO 的相关知识: Java NIO 缓冲区 Java NIO 通道 Java NIO 选择器Selector下面根据 NIO 的相关知识,编写一个 NIO 服务端与客户端通信的一个完整的比较简单的例子。程序的功能是客户端向服务器端发送 request time 请求,服务器接收到请求并验证正确后向客户端返回服务器时间。服务器:public cl...原创 2018-10-21 14:54:00 · 282 阅读 · 0 评论 -
NIO 2 Paths 与 Files 使用
Paths 类与 Files 类属于NIO 2的一部分,在 JDK 7 中引入,并在 JDK 8 中增加了一些适应新增特性(Stream等)的方法。这两个类一般配合起来使用,其中封装了许多操作文件的方法,相比之前的 File 类,更为简洁方便,也包含更细粒度的控制功能。关于 File 类存在的问题,可以参考这篇文章:Legacy File I/O CodePathPath 可以理解为定义的一...原创 2018-10-21 14:44:06 · 569 阅读 · 0 评论 -
Java NIO — 选择器(Selector)
SelectorJava NIO 的实现关键在于多路复用 I/O 技术,而多路复用的核心在于通过 Selector 以轮询的方式查找注册在其上的 Channel,当发现某个或者多个 Channel 处于就绪状态后,从阻塞状态返回就绪的 Channel 的选择键集合,进行后续I/O 操作。Selector 一般翻译为选择器,也可以翻译为多路复用器。Selector 需要结合通道 Channel ...原创 2018-10-21 13:28:01 · 365 阅读 · 0 评论 -
Java NIO — 通道(Channel)
NIO 中主要的三个概念为缓冲区、通道、选择器,它们之间的关系如下所示:此处要提醒的是,JDK 1.7 升级了 NIO 类库,升级后的 NIO 类库被称为 NIO2.0。在 NIO2.0 中,提供了异步文件I/O操作,同时提供了与 UNIX 网络编程事件驱动I/O对应的 AIO。在之前《Java NIO 缓冲区》一文中已经介绍过缓冲区的相关知识,本文主要介绍通道的使用。通道(Channe...原创 2018-10-21 12:44:12 · 380 阅读 · 0 评论 -
并发基础 CAS
CAS(Compare and Swap),译为比较并交换。 java.util.concurrent 包实现的基础正是 CAS,是乐观锁思想的运用。CAS 的基本思想:先进行操作,如果没有其他线程争用共享数据,操作成功;如果共享数据有争用,产生冲突,不断地重试,直到成功为止。这种乐观并发的策略需要硬件指令集的支持。这类指令常用的有: 测试并设置(Test and Set) 获取并增...原创 2018-10-21 11:52:48 · 238 阅读 · 0 评论 -
字符串匹配 KMP 算法
KMP算法是 BF(Brute Force) 算法的一种改进算法,是一种较为高效的字符串匹配算法。相比 BF 暴力匹配算法,KMP 算法的思想是利用已匹配的信息,使得能够不发生回溯,也就是当发生不匹配时,文本串(source)的位置不变,尽量向右移动模式串(target),如下图所示:前缀与后缀KMP 算法的核心是 next 数组的求解,而要理解 next 数组需要先理解前缀和后缀的概...原创 2018-10-14 09:33:38 · 299 阅读 · 0 评论 -
Java NIO 缓冲区
JDK 1.4 中引入的新输入输出 (NIO) 库提供了高速的、面向块的 I/O。Java中原有的面向流的 IO 已经以 NIO 为基础重新进行了实现,因此现在它也可以利用 NIO 的一些特性。NIO提供了对多路复用的支持,主要优势在于一个线程可以处理多个连接,减少线程切换带来的开销。通道和缓冲区是 NIO 中的核心对象,几乎在每一个 I/O 操作中都要使用它们。缓冲区在面向流的 I/O ...原创 2018-10-14 00:27:13 · 258 阅读 · 0 评论 -
Java 注解
Java内置注解注解(annotation)自 Java 1.5 开始引入,也被称为元数据。Java内置了几种注解(Java 注解深入理解) @Override:表示当前的方法定义将覆盖超类中的方法。注解目标为方法。源文件有效 @Deprecated:表示已被弃用,将在未来的某个版本移除。注解目标为类、成员变量、方法、方法参数、构造函数、局部变量和包。运行期有效 @Suppres...原创 2018-10-04 15:55:38 · 187 阅读 · 0 评论 -
Java 异常处理
Java异常分类Java中的异常都继承自Throwable类。Throwable分为两大类:Error与Exception。Error一般表示系统错误,如栈溢出、堆溢出等等,一般不用我们关心。Exception是程序本身可以捕获并且可以处理的异常,是我们需要重点关注的。上图列出了Java中常见的异常,仍有许多异常没有列出。比如IOException下就有几十种异常。Exception...原创 2018-10-04 14:27:25 · 230 阅读 · 0 评论 -
Java 对象序列化
对象序列化对象序列化就是将对象转化成特定的格式,使其可在网络中传输、存储在内存或者文件中。反序列化则是将对象从序列化数据中还原出来。对象序列化后的数据格式可以是二进制,可以是XML,也可以是JSON等任何格式。利用它可以实现轻量级持久性。一般情况下,只有当JVM运行时,所创建的对象才可能存在。但有时我们需要在程序停止运行时仍能存在并保存状态信息,这时就需要对象序列化。对象序列化的重点在于数据...原创 2018-10-04 12:42:37 · 195 阅读 · 0 评论 -
经典排序算法 — Java 实现
排序算法的好坏对于效率的影响十分显著。好的排序算法排序100万个整数可能只需要一秒(不考虑硬件因素),不好的排序算法可能需要一个小时甚至几个小时。常见的排序算法有冒泡排序、插入排序、堆排序、快速排序等,这些排序都属于基于比较的排序,因此这些算法的时间复杂度都不能突破O(NlogN)。还有另一类非基于比较的排序,包括基数排序、桶排序、计数排序。冒泡排序一般情况下效率比较低,在此不再赘述。插...原创 2018-10-04 11:57:08 · 415 阅读 · 0 评论 -
Java 8 日期API
Java 8 中的日期API 相比以前更为简洁,辨识度高,而且都是线程安全的。掌握常用的时间类方法有时可以节省许多额外的工作。关于各个类的介绍可以参考Java 8新特性(四):新的时间和日期API值得注意的是,LocalTime 、LocalDate与LocalDateTime类的构造器都是private,这里用了静态工厂方法(static factory methods) 。静态工厂方法相比传...原创 2018-10-03 17:40:06 · 210 阅读 · 0 评论 -
装饰器模式 — Java IO
Java IO中含有众多的类,对于刚接触的人来说往往摸不清头脑。其实只要理清了它们之间的层次关系,就容易理解很多。Java IO中涉及到装饰器模式(Decorator Pattern)与适配器模式(Adapter Pattern)。先上一张Java IO(字节流)系谱图(图片来源网络)。可以看到,输入和输出基本是高度对称的。上图并没有包括所有的IO类,随着Java版本的变化,可能有新...原创 2018-10-03 17:13:46 · 1086 阅读 · 0 评论 -
Java 集合框架与 HashSet 输出
Collection与Map备注: 图中只列出了主要容器,仍有一部分容器没有列出 EnumSet为抽象类,RegularEnumSet与JumboEnumSet是它仅有的两个子类 Collections下的 checked 容器、synchronized 容器与 unmodifiable 容器没有列出。Map下还有WeakHashMap子类没有列出。HashSet ...原创 2018-10-03 13:41:55 · 359 阅读 · 0 评论 -
Java 比较器 — Comparable 与 Comparator
自然排序与比较器排序自然排序,即按字典顺序排序(升序排序),是默认的排序方式。比如Arrays.sort()与Collections.sort(),如果我们不指定比较器,使用的就是自然排序,也就是按升序排序。如果想让元素降序排列或以我们指定的方式进行排序,就需要自定义比较器了,这可以通过Comparable或Comparator接口来实现。Comparable接口java.lang.Co...原创 2018-10-03 11:37:51 · 248 阅读 · 0 评论 -
Java 前期绑定与后期绑定
在java面向对象的三大特征封装、继承、多态中,多态对于刚接触的人来说往往较难理解。理解它的原理有助于我们更深一步的认识。我们知道,java中的多态表现为同一个行为具有多个不同表现形式,使得我们可以通过父类的引用指向子类的方法,比如下面这样:class Father { public void g() { System.out.println("father's g()...原创 2018-10-03 10:56:23 · 453 阅读 · 1 评论 -
HashMap 原理浅析
HashMap可以说是使用频率相当频繁的一类Java容器了,它主要用来存放键值对<key,value>数据,如“姓名”:“张三”、“年龄”:“18”等等。HashMap中可以存放null,但key是唯一的,value可以重复。当你将多个key相同的键值对存储进HashMap中时,只会显示最后放的键值对数据。HashMap是无序的,原创 2018-10-02 13:13:32 · 249 阅读 · 0 评论 -
TCP Socket 编程
套接字SocketSocket通常也称作套接字,网络上的两个程序通过一个双向链路实现数据的交换,这个双向链路的一端称为一个Socket,由IP地址和端口号唯一确定。应用程序通过套接字向网络发出请求或者应答网络请求。Socket是对TCP/IP协议的封装,其本身并不是协议,而是一个调用接口(API)。大多数的API提供者(如操作系统,JDK)往往会提供基于这种概念的接口。TCP/IP 中主要 ...原创 2018-10-04 16:17:45 · 349 阅读 · 0 评论 -
Java 中的代理(proxy)
代理模式是一种经典的设计模式,代理的意义在于生成代理对象,在服务提供方和使用方之间充当一个媒介,控制真实对象的访问。代理分为静态代理和动态代理两种。静态代理需要通过手动或工具生成代理类并编译,代理类和委托类的关系在编译期就已经确定。动态代理允许开发人员在运行时动态的创建出代理类及其对象。Spring AOP的主要技术基础就是java的动态代理机制。静态代理静态代理的实现需要一个接口(表...原创 2018-10-04 17:05:47 · 14595 阅读 · 4 评论 -
观察者模式
观察者模式,又叫发布-订阅(Publish/Subscribe)模式,它定义了对象之间一对多的依赖关系,当一个对象状态改变时,其他相关联的对象就会得到通知并被自动更新。例如,现有一组数据,分别画出柱状图、饼状图、折线图,当数据发生变化时,图形也需要同时进行相应的变化。如图所示,监听的对象叫观察者(Observer),被监听的对象叫被观察者(Observable,也称主题Subject)。...原创 2018-10-14 00:10:17 · 211 阅读 · 0 评论 -
最小堆解决 Top K 问题
Top K 问题指从一组数据中选出最大的K个数。常见的例子有:热门搜索前10,最常听的20首歌等。对于这类问题,可能我们会首先想到先对这组数据进行排序,再选取前K个数。虽然这能解决问题,但效率不高,因为我们只需要部分有序,它却对整体进行了排序。最小堆是解决Top K 问题的一个好的方法(如果我们需要选出K个最小的数,用的是最大堆)。Top K 实现步骤最小堆也叫小根堆,实际上是一个完全二...原创 2018-10-14 00:00:53 · 1041 阅读 · 0 评论 -
Java 优先级队列
队列(queue)是一种先入先出(FIFO)的数据结构。栈中的插入和移除数据项的命名一般都是Push、Pop,而队列至今没有标准化的命名。插入操作可以用add、offer、enque等命名,移除操作可以用poll、remove、deque等命令,查看队头操作可以用peek、remove等命令。在 Java 中,常见的队列操作以及它们的区别如下所示:插入offer向队列插入元素,在一...原创 2018-10-13 23:35:01 · 10379 阅读 · 0 评论