Java
文章平均质量分 75
打酱油的葫芦娃
一万年太久,只争朝夕!
展开
-
基于源码搞懂LinkedHashMap并通过其实现LRU算法
LinkedHashMap 是通过哈希表和双向链表来实现的,其基于双向链表来保证对哈希表迭代时的有序性。LinkedHashMap 继承自 HashMap,从而可以直接复用 HashMap 对哈希表的操作逻辑,其只需要额外维护1套双向链表的操作逻辑即可。public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>{ ......}节点LinkedHashMa原创 2022-05-07 17:24:08 · 3658 阅读 · 0 评论 -
基于源码深入了解Java的类加载机制(JDK8和JDK11双版本)
Java 虚拟机设计团队有意将类加载阶段中的"通过一个类的全限定名来获取描述该类的二进制字节流"这个动作放到 Java 虚拟机外部来实现,以便让应用程序自己来决定如何去获取所需的类,实现这个动作的代码称之为"类加载器 (Class Loader) "。由于 JDK9 引入了模块化新特性,所以 JDK9 前后的类加载实现也略有区别,本文将分开讲解。首先基于 JDK8 来讲解类加载机制。JDK8双亲委派模型java.lang.ClassLoader 抽象类的 loaderClass() 方法定义了类加原创 2022-04-09 16:59:49 · 7218 阅读 · 0 评论 -
数字的计算机表达--大小端和浮点数
大端和小端起源关于大端小端名词的由来,有一个有趣的故事,来自于Jonathan Swift的《格利佛游记》:Lilliput和Blefuscu这两个强国在过去的36个月中一直在苦战。战争的原因:大家都知道,吃鸡蛋的时候,原始的方法是打破鸡蛋较大的一端,可以那时的皇帝的祖父由于小时侯吃鸡蛋,按这种方法把手指弄破了,因此他的父亲,就下令,命令所有的子民吃鸡蛋的时候,必须先打破鸡蛋较小的一端,违令者重罚。然后老百姓对此法令极为反感,期间发生了多次叛乱,其中一个皇帝因此送命,另一个丢了王位,产生叛乱的原因就是另原创 2022-03-10 19:52:47 · 5554 阅读 · 0 评论 -
手撸RPC框架系列--Java简易版
RPC是Remote Procedure Call(远程过程调用)的简写,即实现调用远程计算机上的方法,就像调用本地方法一样。分布式环境下各个服务之间的协作,必然会用到RPC的思想。一般来讲,RPC框架会包含3部分:服务提供者(ServiceProvider)注册中心(RegistryCentre)服务消费者(ServiceComsumer)RPC整个过程可以概括如下:定义好统一的请求体(RpcRequest)和返回体(RpcResponse);定义好服务接口;服务提供者完成接口的实原创 2022-03-10 19:43:18 · 5075 阅读 · 0 评论 -
Unsafe类详解
Java 不能直接访问操作系统底层,而是通过本地方法来访问。Unsafe 类提供了硬件级别的原子操作。Unsafe 类在 sun.misc 包下,不属于 Java 标准。很多 Java 的基础类库,包括一些被广泛使用的高性能开发库都是基于 Unsafe 类开发,比如 Netty、Hadoop、Kafka 等。Unsafe 是用于在实质上扩展 Java 语言表达能力、便于在更高层(Java 层)代码里实现原本要在更低层(C 层)实现的核心库功能用的。这些功能包括裸内存的申请/释放/访问,低层硬件的.原创 2022-03-04 11:09:44 · 12769 阅读 · 0 评论 -
一文教会你JDK8的函数式编程
JDK8的1个新特性就是支持函数式接口(Functional Interface)。函数式接口就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为Lambda表达式。我们也可以自行定义函数式接口,如:@FunctionalInterfaceinterface GreetingService{ void sayMessage(String message);}然后通过Lambda表达式来定义接口实现(JAVA8之前一般使用匿名类来实现):public c原创 2022-02-23 11:31:49 · 6853 阅读 · 0 评论 -
一文搞懂原码、反码、补码
计算机底层均是以二进制表示的,数字也不例外,本文旨在探讨一下数字的原码、反码和补码。概念需要声明的是,本文涉及到的数字及运算均基于8位bit下的值。原码最高位为符号位,0代表正数,1代表负数,非符号位为该数字绝对值的二进制表示。如:127的原码为0111 1111-127的原码为1111 1111反码正数的反码与原码一致;负数的反码是对原码按位取反,只是最高位(符号位)不变。如:127的反码为0111 1111-127的反码为1000 0000补码正数的补码与原码一致;负.原创 2022-02-16 10:11:09 · 7359 阅读 · 0 评论 -
HashMap的数组大小为何设计成2的n次方?
今天工作有点累,就小水一篇吧。聊一聊HashMap的数组大小为何设计成2的n次方?先说答案:简化求余操作;减少扩容时元素移动的概率,提高resize操作的性能。HashMap底层是数组+链表来实现的,插入<K,V>时,首先是计算Key的hash值,然后和数组大小取余,余数是几就把该元素放到数组的哪个位置上。当数组大小len为2的n次方时,取余操作可简化为:hash & (len - 1)比如len=8,其二进制为:0000 1000len-1后:0000原创 2022-02-12 16:57:20 · 5860 阅读 · 0 评论 -
如何判断某个类是否有某个注解?
开发过程中,我们经常通过在类上打注解的方式来给它做标记,以便后期对其进行相应操作。比如Springboot在启动的时候,会对标有@Component注解的类进行加载和初始化。那么,如何判断某个类是否有某个注解呢?很多人会说,这还不简单,不就是利用反射检索该类的注解集合里有没有这个注解不就好了吗。但这样是不全面的,因为类可能继承自某个父类或者接口,而其父类或者接口上存在该注解。同时,该注解可能是个复合注解,即该注解也是被其他注解所注解的。所以,判断某个类是否有某个注解的完善流程应该包含4个方面:原创 2022-02-12 10:05:44 · 11158 阅读 · 0 评论 -
聊一聊I/O那些事儿
在Linux/Unix系统中,对于1次IO读取操作,数据并不会由磁盘/Socket直接拷贝到应用程序的缓存区(用户空间)。数据的流转顺序为:磁盘/Socket–>内核空间–>用户空间。所以,数据读取可以看成2个过程:Waiting for the data to be ready(等待数据到达内核缓冲区)Copying the data from the kernel to the process(从内核缓冲区拷贝数据到应用程序缓冲区)基础概念同步和异步同步和异步关注的是消息原创 2022-02-09 14:21:37 · 6061 阅读 · 0 评论 -
说说Session和Token的那些事儿
很多童鞋对Session和Token懵懵懂懂,今天我们聊一下Session和Token那些事儿。服务器端创建Session,并将SessionID回传给客户端。客户端收到SessionID,有4种方式处理:浏览器Cookie;LocalStorage;URL回写;隐藏表单字段。也就是说,Session不严格依赖Cookie。SessionID如果本身不携带或者无法反解析出会话的用户信息,服务端无法判定该SessionID是否是由自己发出的。此时,服务端需要存储所有用户的SessionI原创 2022-01-24 15:29:08 · 5702 阅读 · 0 评论 -
如何保证缓存一致性?
缓存可以提高数据查询的效率,较低数据库的压力,但使用缓存的过程中,需要注意缓存一致性问题。先更新缓存,再更新数据库假设2个并发线程A和B,均为写线程,其执行顺序如下:线程A更新缓存值为v1;线程B更新缓存值为v2;线程B更新数据库值为v2;线程A更新数据库值为v1。此时,数据库中存储的为值v1,而缓存中的值为v2,数据不一致。先删除缓存,再更新数据库假设2个并发线程,1个读线程A,1个写线程B,其执行顺序如下:线程B删除缓存;线程A读取缓存,发现无缓存;线程A继续读数据库,取出原创 2022-01-18 15:30:06 · 5428 阅读 · 0 评论 -
DelayQueue源码分析
DelayQueue是一个阻塞队列,其实现了BlockingQueue接口。public class DelayQueue<E extends Delayed> extends AbstractQueue<E>implements BlockingQueue<E> { }添加到延迟队列中的元素必须实现Delayed接口,该接口有2个方法:// 获取元素的延误时间long getDelay(TimeUnit unit);// 元素比较public in原创 2022-01-18 11:01:53 · 4893 阅读 · 0 评论 -
PriorityQueue源码解析
PriorityQueue为优先队列,其与普通的FIFO(先进先出)队列不同的地方是,优先队列每次出队的均是队列中优先级最高的元素。PriorityQueue使用最小(大)二叉堆来管理队列中的元素,元素的大小比较方法由用户指定的Comparator指定,每次出队元素为堆顶元素。最小二叉堆最小二叉堆满足如下约束:完全二叉树;所有非叶子节点的根节点value均小于其左、右子节点的value。如下图即为典型的最小二叉堆:入队最小二叉堆的元素添加过程如下:将待添加元素添加到二叉树的最后一个原创 2022-01-18 10:56:30 · 5601 阅读 · 0 评论 -
Java的垃圾收集器和内存分配策略
对象标记算法对象回收前,需要标记其"死活",常用的对象标记算法主要包括引用计数算法和可达性分析算法。引用强引用 (Strongly Reference)只要强引用还存在,垃圾收集器就永远不会回收掉被引用的对象;软引用 (Soft Reference)内存溢出时,进行回收,这次回收还没有足够的内存,才会抛出内存溢出异常;弱引用 (Weak Reference)只能生存到下一次垃圾收集发生为止。虚引用 (Phantom Reference)只是被回收时收到1个通知。引用计数原创 2020-11-09 10:08:41 · 4875 阅读 · 0 评论 -
MyBatis框架入门
1 概述1.1 简介开源免费框架,原名叫iBatis,2010年google code,2013年迁移到github,其是数据层访问框架,本质上是对JDBC的封装;其优点是不需要写实现类,只需要写需要执行的sql命令即可。1.2 环境搭建1.2.1 Jar包需要的Jar包:1.2.2 全局配置文件<?xml version="1.0" encoding="UTF-8"?&g...原创 2018-12-08 11:19:32 · 5041 阅读 · 0 评论 -
大数据环境搭建(Hadoop,Spark,Zookeeper,Hbase,Kafka)
本教程基于4台机器(预装有CentOS7 Linux系统)完成Hadoop集群及其相关组件的搭建,1个master,3个slave。1 Linux环境准备1.1 基础设置修改主机名hostnamectl set-hostname masterreboot依次将其他3台机器设置为slave1,slave2,slave3。修改IP地址vim /etc/sysconfig/ne...原创 2018-12-08 11:22:10 · 7473 阅读 · 2 评论 -
RestTemplate源码解读
引言SpringCloud的微服务均是以Http接口的形式来暴露自身服务的,因此在调用远程服务的时候必须使用HTTP客户端,可选的方案有JDK原生的URL Connection、Apache的Http Client、Netty的异步Http Client,Spring的RestTemplate和Fegin。今天主要介绍一下Spring的RestTemplate。源码跟读通过源码可以看到Re...原创 2019-04-25 14:11:18 · 5777 阅读 · 1 评论 -
Scala编程实战—数值
Scala所有的数值都是对象,包括Bytes、char、Double、Float、 Int、Long和Short。原创 2017-09-25 15:35:57 · 15627 阅读 · 0 评论 -
Scala编程实战—字符串
主要介绍Scala字符串的相关操作。原创 2017-09-25 11:50:48 · 15753 阅读 · 0 评论 -
Scala 映射和元组
Scala映射及数组基础原创 2017-09-20 14:35:42 · 15447 阅读 · 0 评论 -
Scala实战—连接oracle及mysql数据库
主要介绍在Scala中如何实现oracle及mysql的连接。原创 2017-08-08 11:36:42 · 17026 阅读 · 0 评论 -
Flink的分布式缓存
分布式缓存Flink提供了一个分布式缓存,类似于hadoop,可以使用户在并行函数中很方便的读取本地文件,并把它放在taskmanager节点中,防止task重复拉取。此缓存的工作机制如下:程序注册一个文件或者目录(本地或者远程文件系统,例如hdfs或者s3),通过ExecutionEnvironment注册缓存文件并为它起一个名称。当程序执行,Flink自动将文件或者目录复制到所有task...原创 2019-09-16 10:30:53 · 5092 阅读 · 1 评论 -
Java_Web —Tomcat安装配置及Servlet初探
Java的Web开发选用的中间件一般为tomcat(汤姆猫),其主要作用是为Servlet提供容器。原创 2017-09-25 09:21:14 · 15611 阅读 · 0 评论