![](https://img-blog.csdnimg.cn/20201014180756916.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Java
文章平均质量分 72
Java基础学习,包括Java源码、多线程、网络编程等
wadreamer
这个作者很懒,什么都没留下…
展开
-
通过 Tomcat 获取 Websocket 的远程客户端 IP
因为 websocket 的连接只有 session,所以需要借助 tomcat 来获取远程的客户端 IP。程序如下所示:package com.maxvision.maxects.util;import javax.websocket.RemoteEndpoint;import javax.websocket.Session;import java.lang.reflect.Field;import java.net.InetSocketAddress;public class Web原创 2021-06-18 11:02:27 · 1216 阅读 · 0 评论 -
【LeetCode】11-Container With Most Water 盛最多的水(双指针法、缩减搜索空间思想)
【11】盛最多的水 - 双指针法、缩减搜索空间思想 给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 说明:你不能倾斜容器。 示例 1:输入:[1,8,6,2,5,4,8,3,7]输出:49 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水原创 2021-04-18 11:59:36 · 370 阅读 · 2 评论 -
【领你入门 Netty】服务端未收到客户端回复时的消息重发机制
一、应用场景 由于最近在做硬件通讯交互方面的项目,使用的是 Netty 作为中间件,存在以下两个应用场景: 1)业务平台通过 Netty 下发一条指令到终端设备,且终端设备需要上行指令确认,说明该终端设备收到该条指令。但是,存在网络抖动或终端设备突然失联等情况,此时,客户端并未收到该条指令。因此,期望服务端能够在指定时间间隔和重试次数的情况下重发未收到上行确认的指令。 2)周期性下发通讯指令,获得终端设备的近实时数据,如定位信息、终端状态等。二、解决方案 提出以下两种解决方案,若读者们有更原创 2021-04-09 16:40:59 · 2111 阅读 · 0 评论 -
【领你入门Netty】- Netty线程模型与入门程序详解
一、Netty 简介 Netty 是由 JBOSS 提供的一个 Java 开源框架。Netty 提供异步的、基于事件驱动的网络应用程序框架,用以快速开发高性能、高可靠性的网络 I/O 程序。它是一个基于 NIO 的网络编程框架,相比于 Java 原生的 NIO,它具有如下的优势:支持三种 I/O 模型同时支持三种 Reactor 模型。支持很多应用层的协议,提供了很多编解码器。能够很好地解决 TCP 长连接所带来的缺陷(粘包、半包等)。提供了应用层的 Keep Alive 机制。有更好的性能原创 2021-04-05 21:53:10 · 156 阅读 · 0 评论 -
java计算CRC8循环校验码,亲测可用!
public static int getCrc(byte[] data){ int CRC = 0; int genPoly = 0x8C; for(int i = 0; i < data.length; i++){ CRC ^= data[i]; // 保证 CRC 余码输出为 1 字节 CRC &= 0xff; for(int j = 0; j < 8; j++){ if((CRC & 0x01) != 0){ CRC = (CRC原创 2021-03-25 20:06:38 · 847 阅读 · 0 评论 -
接口开发的幂等性方案
一、接口幂等性1.1 接口幂等性定义 在HTTP/1.1中,对幂等性进行了定义。它描述了一次和多次请求某一个资源对于资源本身应该具有同样的结果(网络超时等问题除外),即仅第一次请求会对资源产生副作用,后续的多个请求对于同一个资源不会产生副作用。 这里的副作用是不会对结果产生破坏或者产生不可预料的结果。也就是说,其任意多次执行对资源本身所产生的影响均与第一次执行的影响相同。1.2 实现接口幂等性的优劣 以下情况若不保证接口幂等性,将会对系统产生不可预知的问题。前端重复提交表单:用户提交表单原创 2021-03-03 15:00:16 · 251 阅读 · 0 评论 -
CGLIB 常用的 API 详解
一、概述 本文主要讲解的是 CGLIB 的常用 API 及其使用方式。使用的 CGLIB 依赖如下所示:<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version></dependency> 首先创建接口 CglibSampleInterface 和类 CglibSam原创 2021-02-05 14:24:10 · 677 阅读 · 0 评论 -
Spring Boot 结合 Redis 实现接口访问限流
一、概述 本文主要通过 Redis 和 Lua 脚本的方式实现接口的访问限流,限流的方式可基于客户端的访问 IP 进行限流,也可以对访问接口的频率进行限流。主要的实现思路是通过在 Redis 中设置 key 的过期时间以及该接口对应的访问次数,若大于访问次数,则不允许再访问接口,可对页面进行重定向或给出提示信息,本文则简单地实现核心的逻辑。 项目结构如下图所示:二、实现过程2.1 项目依赖 <properties> <java.version>1原创 2021-02-04 14:34:21 · 400 阅读 · 0 评论 -
CGLIB 动态代理及其原理分析
一、简介 CGLIB,即 Code Generation Library,是一个强大的、高性能的代码生成库。它可以在运行期扩展 Java 类与实现 Java 接口(JDK 动态代理只能用于接口),它被许多 AOP 框架广泛地使用,如为 Spring AOP 提供方法的 interception(拦截),被 Hibernate 用来代理单端(多对一和一对一)关联(延迟提取集合使用的另一种机制)。本文使用的 CGLIB 依赖如下:<dependency> <groupId>原创 2021-02-01 15:29:52 · 5682 阅读 · 3 评论 -
java-深入理解锁升级、锁粗化、锁消除
一、简介 Java SE 1.6 为了减少获得锁和释放锁带来的性能消耗,引入了“偏向锁”和“轻量级锁”。因此,在 Java SE 1.6 一共有 4 种锁的状态,级别由低到高依次是:无锁、偏向锁、轻量级锁、重量级锁,并且四种状态会随着竞争的情况逐渐升级,而且是不可逆的过程,即不可降级,也就是说只能进行锁升级(从低级别到高级别),意味着偏向锁升级成轻量级锁后不能降级成偏向锁。这种锁升级却不能降级的策略,目的是为了提高获得锁和释放锁的效率。二、预备知识2.1 对象头 以 Hotspot 虚拟机为例,原创 2021-01-28 11:16:06 · 896 阅读 · 1 评论 -
深入理解静态代理与 JDK 动态代理
一、概述 静态代理和动态代理都是代理模式的实现方式之一,代理模式是一种常用的设计模式,在 Spring AOP 和 PRC 等诸多框架中均使用到了代理的思想,其目的是为其他对象提供一个代理来控制对某个对象的访问。代理类负责为委托类 (真实角色) 预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。基本的结构如下所示,主要包括三种角色:抽象角色:声明待实现的方法。抽象角色可以是接口或抽象类。委托类角色或真实角色:业务逻辑的具体执行者,实现抽象角色中所声明的方法。代理类角色:内部含原创 2021-01-18 17:03:55 · 219 阅读 · 0 评论 -
java-自动装箱和自动拆箱
一、简述 自动装箱和自动拆箱是两个相反的过程,自动装箱即将基本数据类型转换为对应的封装类,自动拆箱即将封装类转换为对应的基本数据类型。此外,装箱的过程会增加内存的消耗,影响性能,因为这个过程会创建对应的对象。 可进行自动装箱和自动拆箱的类型如下图所示:二、自动装箱和自动拆箱 采用如下示例说明自动装箱和自动拆箱的原理。public class Main { public static void main(String[] args) { Integer integer原创 2021-01-13 09:49:03 · 1367 阅读 · 1 评论 -
java-向上转型和向下转型
一、简述 Java 转型主要是用在继承和接口实现的场景,Java 转型可分为向上转型和向下转型,区别如下:向上转型:通过子类对象实例化父类对象,这属于自动转换。向下转型:通过父类对象实例化子类对象,这属于强制转换。 只要记住一句话即可,父类引用指向子类对象,即 <父类型> <引用变量名> = new <子类型>()。二、向上转型 子类引用的对象转换为父类类型称为向上转型。向上转型后的父类引用只能调用父类的属性,若子类重写了父类的方法,则通过父类引用调原创 2021-01-11 12:32:54 · 333 阅读 · 0 评论 -
面试必问:static 和 final 关键字
一、static 关键字 1) 静态变量与实例变量 静态变量:即类变量,该变量是属于类的,类的所有实例都共享该静态变量,可以通过类名.静态变量名来访问。此外,静态变量在内存中只存在一份。 实例变量:每创建一个实例就会产生一个实例变量,该实例变量的生命周期与实例相同。 2) 静态方法 静态方法在类加载前就已经存在,它不依赖于任何实例,且必须有方法体,即 static 和 abstract 不能同时使用。此外,静态方法只能访问所属类的静态变量和静态方法,静态方法中也不能存在 this 和 s原创 2021-01-10 11:00:36 · 125 阅读 · 0 评论 -
java常见注解
@Retention:用于描述注解的生命周期,表示需要在什么级别保存该注解,即保留的时间长短。@Retention(RetentionPolicy.SOURCE):注解仅存在于源码中,在class字节码文件中不包含。@Retention(RetentionPolicy.CLASS):默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得。@Retention(RetentionPolicy.RUNTIME):注解会在class字节码文件中存在,在运行时可以通过反射获取到。 @原创 2021-01-06 15:30:03 · 220 阅读 · 0 评论 -
线程池 Executor 和 ThreadPoolExecutor
一、线程池简述 线程池即线程的集合,线程池在系统启动时就创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务,使用线程池可以很好地提高性能。1.1 线程池的工作机制 在线程池的编程模式下,任务是提交给整个线程池,而不是直接提交给某个线程,线程池在拿到任务后,就在其内部寻找是否有空闲的线程,若有,则将任务交给某个空闲的线程。 此外,一个线程同时只能执行一个任务,但可以同时向一个线程原创 2021-01-02 11:27:20 · 365 阅读 · 0 评论 -
RSA 秘钥工具类详解
本文使用PKCS8EncodedKeySpec生成私钥,使用X509EncodedKeySpec生成公钥。此外,使用Base64进行解码和编码. 完整的文件:Rsa工具类一、使用 PKCS8EncodedKeySpec 生成私钥的加解密 1.1 加密public static String encryptByPrivateKey(String privateKeyText, String text) throws Exception { // 解码私钥字符串,得到私钥的 A原创 2020-10-19 09:24:48 · 1129 阅读 · 1 评论 -
超详细的java.lang.Object类源码解析,动手收藏起来吧
学习过Java的程序猿们都知道,Object是Java所有类的顶级父类,所有的类都继承自该类,包括数组都实现了该类中的方法。在Object的源码中也是这么写道 (tips:学习源码的过程,也是提升英语阅读能力的过程,本人会做该标注来表示某个词组的意思【外文】(译文)):/** * Class {@code Object} is the root of [the class hierarchy]...原创 2020-04-29 17:01:21 · 1365 阅读 · 0 评论 -
实现数组复制常用的5种方式及组合类的深复制(深拷贝)
在Java语言中,一般会采用下面的几种方法进行数组的复制。a) for循环逐一复制;b) System.arraycopy方法c) Arrays.copyOf方法d) 使用clone方法e) Arrays.copyOfRange方法接下来,我们看下这几种方法的源码和效率。一、for循环逐一复制。这种方式没啥好说的了,实现灵活,但效率低。二、System.arraycopy方法...原创 2020-04-27 12:41:09 · 2339 阅读 · 1 评论 -
java序列化和反序列化,面试必备
一、序列化、反序列化、使用场景、意义。序列化:将对象写入IO流中;反序列化:从IO流中恢复对象;意义:序列化机制允许将实现序列化的Java对象转换为字节序列,并将字节序列保存在磁盘中,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使地对象可以脱离程序的运行而独立存在。使用场景:所有在网络上传输的对象都必须是可序列化的。如:RMI (远程方法调用),传入的参数或返回的对象都是可序列化...原创 2020-04-26 17:04:19 · 7543 阅读 · 4 评论 -
Integer类的缓存机制
存在下述例子,判断其输出结果。public class Main{ public static void main(String[] agrs){ Integer a = 110; Integer b = 110; Integer c = 150; Integer d = 150; System.out.println("a == b: " + (a == b)); ...原创 2020-04-25 11:50:44 · 939 阅读 · 0 评论