![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Java后台
文章平均质量分 88
KDLin
这个作者很懒,什么都没留下…
展开
-
Java序列化攻击和最佳实践
85. 其他序列化优于Java序列化Java序列化机制很危险,在新编写的系统中,没有理由再使用Java序列化,应该使用其他序列化机制,例如跨平台的JSON序列化;尤其不要反序列化任何不信任的数据,因为容易遭受序列化攻击。原因在于,反序列化不被信任的数据,容易受到序列化攻击,例如远程代码执行(RCE),拒绝服务(DoS)等等。研究人员可以基于Java序列化机制开发出很多巧妙的攻击片段。例如:public class BombSerializable { public static void原创 2022-04-29 09:36:47 · 485 阅读 · 0 评论 -
深入理解Java序列化机制
默认序列化方法基本形式基本形式非常简单,要让类支持序列化,只需要实现Serializable接口即可,该接口是一个标记接口。序列化的类的所有实例域必须都是可序列化的,也就是说,实例域为引用类型,则该类型也必须实现Serializable。public class WriteObject { public static void main(String[] args) { try (ObjectOutputStream oos = new ObjectOutputStream(原创 2022-04-24 22:02:41 · 292 阅读 · 0 评论 -
Java并发中的种种正确的Tips
78. 同步访问共享的可变数据本条主要是指出内存可见性,Java内存模型,重排序等机制引起可变对象共享的问题,这些都是并发的基础理论知识。有时候这些错误不容易分析:// Broken! - How long would you expect this program to run?public class StopThread { private static boolean stopRequested; public static void main(String[] args)原创 2022-04-12 11:04:15 · 214 阅读 · 0 评论 -
你真的懂得Java异常的正确使用姿势吗?
引言异常机制我们再熟悉不过,在开发环境中,它非常有用。它能帮我们的程序从错锁中恢复,也能在程序奔溃的时候方便我们定位异常原因。但大家在生产环境中会不会有这种感觉:这个异常究竟应该catch处理掉呢,还是应该抛给调用方?底层抛出来的异常,究竟在哪一层处理比较好?应该抛出什么异常?尽管我们会想,属于用户责任就应该抛给用户,但这里的边界,实际开发中很难界定。本文来回答这个问题,并且会给出异常机制相关的最佳实践。回忆一下异常的知识。其中:Error是严重的错误,例如内存耗尽,栈溢出等等,它属于非受检异原创 2022-04-03 15:12:41 · 354 阅读 · 0 评论 -
VarHandle,可变句柄解析
JDK 9中新增的库,是java.util.concurrent.atomic和sun.misc.Unsafe操作的等价替代。VarHandle是通用的对象的域的引用句柄,提供原子的操作方法。直接看用法即可。// 对象域private volatile int state;private volatile Thread runner;private volatile WaitNode waiters;// 通用句柄private static final VarHandle STATE;pr原创 2022-01-03 12:40:32 · 521 阅读 · 0 评论 -
Timer类原理解析,任务延迟执行
APITimer类用于延迟任务的执行。schedule(TimerTask task, **long **delay),指定延迟时间schedule(TimerTask task, Date time),指定时间schedule(TimerTask task, **long **delay, **long **period),指定延迟时间和重复周期schedule(TimerTask task, Date firstTime, **long **period),指定初始时间和重复周期源码解读原创 2022-01-02 11:08:07 · 1289 阅读 · 0 评论 -
深入理解Java类加载机制,以及破坏双亲委派模型的实现方式
关于类加载器类加载器的使用//隐式加载User user=new User();//显式加载,并初始化Class clazz=Class.forName("com.test.java.User");//显式加载,但不初始化ClassLoader.getSystemClassLoader().loadClass("com.test.java.Parent了解类加载器的必要性开发人员大多数时候并不需要显示地使用类加载器,但了解整个机制对于了解类本身却很有用。遇到java.lang.Cla原创 2021-12-05 21:01:53 · 540 阅读 · 0 评论 -
Java进阶必备——学会阅读字节码
目标,学会阅读字节码!事实上整个执行过程都是操作数栈和局部变量表的交互过程。加载和存储指令加载到操作数栈中,为了效率,应对不同长度的需要,设计了不同长度的指令。类型常数指令范围int(boolean,byte,char,short)iconst[-1, 5]bipush[-128, 127]sipush[-32768, 32767]ldcany int valuelonglconst0, 1ldcany long valu原创 2021-12-02 15:14:51 · 397 阅读 · 0 评论 -
如何更好地编写Java方法
49. 检查参数的有效性编写方法和构造器的时候,要考虑参数的限制,把限制通过文档注明,并通过显示的方式来检查这些限制。否则,后果是什么明白为什么不好有时候比怎么做才好更重要。不检查参数的问题在于:方法可能在处理过程中失败,产生令人费解的结果。当然这是最显而易见的问题。更糟糕的是,方法返回了,但是结果是错误的。更糟糕的是,方法返回了正确结果,但是未来在某个时候,突然给你一个惊喜,而你完全找不到问题出在什么地方。这破坏了所谓的失败原子性(failure atomicity)最佳实践对于共有原创 2021-11-29 21:31:27 · 384 阅读 · 0 评论 -
垃圾回收器
背景知识指标与权衡吞吐量和暂停时间(垃圾收集时间,STW)是最重要的两个指标。从吞吐量公式来看,垃圾收集时间和吞吐量是互相权衡的。吞吐量=运行用户代码时间(运行用户代码时间+垃圾收集时间)吞吐量 = \frac{运行用户代码时间}{(运行用户代码时间+垃圾收集时间)}吞吐量=(运行用户代码时间+垃圾收集时间)运行用户代码时间对于交互式要求高的应用来说,例如客户端,一般要求高响应,即每次尽可能短的垃圾收集时间。对于高性能需求的应用来说,例如服务端,一般强调高吞吐里。垃圾收集器发展历史了解一下技原创 2021-11-25 18:02:52 · 335 阅读 · 0 评论 -
垃圾回收相关技术
垃圾收集的三大假设这是三个统计上的经验法则。弱分代假说,绝大多数对象都是朝生夕灭。强分代假说,熬过越多次GC过程的对象就越难以消亡跨代引用假说,跨代引用只占少数。这一条实际上是前两条的推论,因为大多数对象都是同生共死的,所以一般都会位于通过区域。这也是后期实现各种分代/分区收集算法的基础——正因为少数,所以开销不至于太大。垃圾回收算法回顾经典算法从缺点演进方面来梳理一下三种算法。标记清楚算法的缺点在于内存碎片,空闲列表的维护使得整体的效率处于中等。复制算法解决了该问题,复制算法在存活对原创 2021-11-25 17:59:20 · 412 阅读 · 0 评论 -
Lambda和Stream
42. Lambda优先于匿名类主要是非常简洁,也为函数式编程提供了一定的支持。在大部分情况下,Lambda代替匿名类还是比较舒服的,正因为如此,需要了解lambda的边界。一行最为理想,三行以上就不要用lambda了lambda只支持函数式接口,匿名类可以支持抽象类的匿名实例的创建lambda不能获得自身的引用,this指向外围类,匿名类可以lambda和匿名类都无法实现方便的序列化、反序列化,需要使用私有静态嵌套类代替演示一种比特定于常量的方法更简洁清晰的lambda实现。// E原创 2021-11-17 10:31:25 · 385 阅读 · 0 评论 -
Java Stream 底层原理
Stream API你可能没意识到Java对函数式编程的重视程度,看看Java 8加入函数式编程扩充多少功能就清楚了。Java 8之所以费这么大功夫引入函数式编程,原因有二:代码简洁函数式编程写出的代码简洁且意图明确,使用_stream_接口让你从此告别_for_循环。多核友好,Java函数式编程使得编写并行程序从未如此简单,你需要的全部就是调用一下parallel()方法。对_stream_的操作分为为两类,中间操作(intermediate operations)和结束操作(ter原创 2021-11-13 19:12:16 · 5032 阅读 · 1 评论 -
Java 泛型的原理以及泛型的补偿
繁琐的语法和泛型擦除原理Java泛型的语法有很多看起来毫无意义的规则和写法,例如:<? extends Fruit><T extends Fruit>(T[])new Object[size]// ...这些本质上都是由于Java泛型机制的实现原理——擦除。所谓的擦除:所有的泛型在编译之后都会被擦除,替换为它们的非泛型上界,例如List,其实实际的类型是ObjectJava的泛型指在编译之前多了额外的检查这看起来以一种很轻量优雅的方式实现的泛型,但实际上原创 2021-11-03 19:22:11 · 333 阅读 · 1 评论 -
泛型 -核心使用原则和原理
26. 不要使用原生类型Java的泛型比较受限。所有的泛型标记,都会在编译之后被完全擦除,变成其上界的类(很多时候是Object),而且Java的泛型也不是强制的,所以我们会情不自禁地想,为何不直接使用List?它不就等于List吗?答案是否定的。我们期望程序的错误尽可能在编译而不是在运行时发出警告。泛型,正好提供了很多这样的安全限制,它将很多错误从运行时移动到编译时,防止我们的程序在某天给我们惊喜。这我们非常好理解,如果使用了原生态类型,就是去了泛型在安全性和描述性方面的所有优势。List原创 2021-11-03 19:20:33 · 148 阅读 · 0 评论 -
类和接口相关
15. 使类可访问性最小化尽可能降低程序元素的可访问性,尤其注意引用可变对象,尽量降低可访问性(尽管有时不容易),以保证线程安全性。可变元素引用公有化合理方式是:// 维护一个不可变长的备份private static final Thing[] PRIVATE_VALUES = { ... };public static final List<Thing> VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VAL原创 2021-10-25 10:36:51 · 86 阅读 · 0 评论 -
SpringMVC系列文章 入门、进阶、源码解析
SpringMVC入门、进阶、源码解析目录springMVC_helloworld.md,运行起来!从servlet,xml,注解三种方式来编写helloword引入了springMVC前端控制器的概念springMVC_basic.md,基础知识详解了前端控制器的运行流程注解@RequestMapping的使用和参数;方法参数的传入传出深入理解RestFul设计风格springMVC_源码.md ,源码级别的学习,发现组件的源码都很类似,特别是视图解析、数据绑定、国际化、异常原创 2021-04-18 22:07:49 · 112 阅读 · 0 评论 -
springMVC和tomcat中请求拦截原理
web.xml都是继承tomcat中web.xmlDispatcherServlet配置/之后会拦截所有的请求,它和/*的区别是,/*优先级更高,/则优先级低。如何理解这个点。例如tomcat的xml中其实默认配置了两个servlet。<!-- The mapping for the default servlet --><servlet-mapping> <servlet-name>default</servlet-name> &...原创 2021-04-18 21:52:34 · 773 阅读 · 2 评论 -
springMVC 几个进阶功能
视图与视图解析器视图的作用是渲染模型数据,将模型里的数据以某种形式呈现给客户。常用的视图类。常用的视图解析器。每个视图解析器都实现了 Ordered 接口并开放出一个 order 属性,可以通过 order 属性指定解析器的优先顺序,order 越小优先级越高。实例一,JstlView视图与国际化springmvc-servlet.xml配置文件中配置解析器。一个是指定jstlView视图类。 一个是指定管理器,将国际化交予springMVC进行管理。 需..原创 2021-04-18 21:49:34 · 289 阅读 · 2 评论 -
springMVC 源码级别学习
DispatcherServlet核心逻辑DispatcherServlet处理逻辑如下。获得对应handler,即自定义的controller 获得对应的handler adapter 适配器调用用户自定义方法,返回model和view 处理和显示视图 跳转页面protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { H...原创 2021-04-18 21:48:12 · 90 阅读 · 0 评论 -
springMVC 基础知识
运行流程在springMVC中所有请求都会委托给DispatcherServlet进行处理,它需要完成以下任务。1)、客户端点击链接会发送 http://localhost:8080/hello 请求2)、来到tomcat服务器;3)、SpringMVC的前端控制器收到所有请求;4)、来看请求地址和@RequestMapping标注的哪个匹配,来找到到底使用那个类的哪个方法来处理5)、前端控制器找到了目标处理器类和目标方法,直接利用返回执行目标方法;6)、方法执行完成以后会有一个.原创 2021-04-18 21:46:26 · 115 阅读 · 0 评论 -
SpringMVC HelloWorld
概述从servlet到注解的hello world演进过程,了解这个过程主要因为原始的方法更加好理解原理。Servlet HelloWorld在项目src/main/java中实现一个servlet,我们可以看到,请求被xml中映射分析,发送到以下servlet中,然后在这里做业务处理,最后将返回结果,交给jsp视图去显示。//实现Servlet接口public class HelloServlet extends HttpServlet { @Override ...原创 2021-04-18 21:44:56 · 1750 阅读 · 0 评论