JDK

设计模式之代理模式

落爺英雄遲暮 提交于 2020-10-29 14:14:08
代理模式 通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用处理,或调用后处理。既(AOP微实现) ,AOP核心技术面向切面编程。 1、代理模式应用场景 SpringAOP、事物原理、日志打印、权限控制、远程调用、安全代理 可以隐蔽真实角色 2、代理的分类 静态代理(静态定义代理类) 动态代理(动态生成代理类) Jdk自带动态代理 Cglib 、javaassist(字节码操作库) 3、静态代理 由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。 1)、静态代理代码 public interface IUserDao { void save(); } public class UserDao implements IUserDao { public void save() { System.out.println("已经保存数据..."); } } 代理类 public class UserDaoProxy implements IUserDao { private IUserDao target; public UserDaoProxy(IUserDao iuserDao) { this.target = iuserDao; } public void save() {

Java 动态代理的原理

半世苍凉 提交于 2020-10-29 11:26:58
做开发的都知道,编程语言可以从运行时还是编译时检查分为动态类型和静态类型。对于Java来说,通常认为它是静态的强类型语言,但是因为Java提供反射的机制,也具备了部分动态类型语言的能力。这一节,我们就讲一讲Java的动态代理。 动态代理是一种用于运行时动态构建代理,动态处理代理方法调用的机制。它首先是一种机制。在设计模式中有一种模式叫做代理模式(Proxy Pattern),和动态代理类似,其中代理可以看作是对调用目标的一个包装,通过代理完成对目标对象的调用。这其实也是一种解耦。 实现动态代理的机制有很多,比如JDK自身提供的动态代理JDK Proxy(利用Java语言的反射机制),其他方式有ASM,CGLIB<基于ASM>,Javassit等。动态代理机制主要应用有面向切面AOP、拦截器、RPC调用、日志、事务等等。 我们先来探究JDK Proxy机制<基于反射>----通过接口。新版本也开始结合ASM机制。它涉及到最重要的类和接口就是Proxy和InvocationHandler。先熟悉他们一下。 Proxy这个类的作用就是用来动态创建一个代理对象的类,它最常用到的方法是newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) InvocationHandler接口只有一个方法

Autowire 和 Resource 注解的区别

微笑、不失礼 提交于 2020-10-29 11:04:37
大家都知道这两个注解可以实现bean的注入 @Autowired 这个是spring的注解    org.springframework.beans.factory.annotation.Autowired @Resource 这属于java自带的注解   javax.annotation.Resource @Autowired默认是按照类型来注入的,默认情况下要求依赖对象必须存在。 如果允许依赖对象为null,需设置required属性为false, 需要按名字注入的话可以跟@Qualifier搭配使用 @Resource是按照里面的name属性来注入的 如果没有指定name (java项目源码www.1b23.com) 当注解在字段上时,默认取name=字段名称装配。 当注解在setter方法上时,默认取name=属性名称装配。 当按照名称(by-name)装配未匹配时,按照类型(by-type)装配。 当显示指定name属性后,只能按照名称(by-name)装配。 @Resoure装配顺序 如果同时指定name和type属性,则找到唯一匹配的bean装配,未找到则抛异常; 如果指定name属性,则按照名称(by-name)装配,未找到则抛异常; 如果指定type属性,则按照类型(by-type)装配,未找到或者找到多个则抛异常; 既未指定name属性,又未指定type属性

一文探讨 RPC 框架中的服务线程隔离

北城以北 提交于 2020-10-29 08:54:23
Kirito 推荐语:最近秋招开始了,很多学生开始准备起了秋招,有很多人想知道进一些有名的互联网公司实习有什么要求,正好最近跟一位阿里春招的实习小伙子聊了一些 RPC 相关的知识点,于是我把这篇他的思考转发过来,给大家参考下,我觉得有这样的实力,进大厂实习应该是没有问题的。以下是原文: 自从春招实习之后,眼界真的就一下子开阔起来了,也感觉到了以前的自己好菜啊(虽然现在也是,笑~)。果然学习之路不能停! 微服务如今应当是一个优秀的程序员必须学习的一种架构思想,而RPC框架作为微服务的核心,不说读一遍源码吧,起码它的实现原理还是应该知道的。 然而目前的RPC服务框架,大多存在一个问题,就是当服务提供端Provider应用中,有的服务流量大,耗时长,导致线程池资源被这些服务占尽,从而影响同一应用中的其他服务正常提供。为此,这次博文主要介绍一下我对于这方面的思考。 前言 在进入正文之前,可以先看一下阿里中间件岛风大佬的这篇博文( 传送门 ),这篇博文复现了Dubbo应用中,线程池耗尽的场景。这其实在线上是十分普遍,解决方法无非是根据业务调整参数,或者引入其他的限流、资源隔离框架,例如Hystrix、Sentinel等,使得资源间互不干扰。其实本身Dubbo也可以对不同的服务配置不同的业务线程池(通过配置protocol)从而实现服务的资源隔离,但是这种方式的弊端在于,一旦服务增多

JVM 内存了解

点点圈 提交于 2020-10-29 08:39:40
说说JVM的内存布局? Java虚拟机主要包含几个区域: 堆:堆Java虚拟机中最大的一块内存,是线程共享的内存区域,基本上所有的对象实例数组都是在堆上分配空间。堆区细分为Yound区年轻代和Old区老年代,其中年轻代又分为Eden、S0、S1 3个部分,他们默认的比例是8:1:1的大小。 栈:栈是线程私有的内存区域,每个方法执行的时候都会在栈创建一个栈帧,方法的调用过程就对应着栈的入栈和出栈的过程。每个栈帧的结构又包含局部变量表、操作数栈、动态连接、方法返回地址。 局部变量表用于存储方法参数和局部变量。当第一个方法被调用的时候,他的参数会被传递至从0开始的连续的局部变量表中。 操作数栈用于一些字节码指令从局部变量表中传递至操作数栈,也用来准备方法调用的参数以及接收方法返回结果。 动态连接用于将符号引用表示的方法转换为实际方法的直接引用。 元数据:在Java1.7之前,包含方法区的概念,常量池就存在于方法区(永久代)中,而方法区本身是一个逻辑上的概念,在1.7之后则是把常量池移到了堆内,1.8之后移出了永久代的概念(方法区的概念仍然保留),实现方式则是现在的元数据。它包含类的元信息和运行时常量池。 Class文件就是类和接口的定义信息。 运行时常量池就是类和接口的常量池运行时的表现形式。 本地方法栈:主要用于执行本地native方法的区域 程序计数器:也是线程私有的区域

Jenkins高级篇之Pipeline

夙愿已清 提交于 2020-10-29 04:57:32
Jenkins高级篇之Pipeline 1、基础调试,配置正常,执行也正常。 2、配置springboot项目。 pipeline配置语句: pipeline { agent any stages { stage('Checkout') { steps { echo 'Checkout' checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '0064fe57-ebdf-4285-82e8-661e74b2bb8d', url: 'git@gitee.com:suno/springboot.git']]]) } } stage('Build') { steps { echo 'Building' sh ''' export JAVA_HOME=/usr/local/jdk1.8.0_161 /usr/local/apache-maven-3.5.4/bin/mvn clean package -Dmaven.test.skip=true ''' } } stage('Test') { steps

我还在生产玩 JDK7,JDK 15 却要来了!|新特性尝鲜

与世无争的帅哥 提交于 2020-10-29 04:47:05
自从 JDK9 之后,每年 3 月与 9 月 JDK 都会发布一个新的版本,而2020 年 9 月即将引来 JDK15。 恰巧 IDEA 每四五个月会升级一个较大的版本,每次升级之后都会支持最新版本 JDK 引入的新功能。 这几天升级了 IDEA,顺便体验了一下 JDK15 的新特性。 虽然我知道你们可能跟我一样JDK8 都还没用熟,但是无妨,看看新版本 JDK 来酸一下。 Text Blocks 最终定版 之前版本的 JDK,如果我们需要插入 HTML , XML , SQL 或 JSON 片段,非常麻烦,需要对里面符号进行各种转义。 所以我每次都会在其他编辑器将 HTML , XML 等编辑好,然后直接复制到 IDEA 中,IDEA 自动会对这些字符转义。 每次复制进去就变成上图的效果,如果上面字符再多点,阅读起来就会更难,并且难以维护。 所幸 IDEA 提供了一个 Inject Language 功能,我们可以在里面快速方便的编辑。 Java 开发者也关注到这个问题,他们在 JDK13 引入的一个新的预览特性「 Text Blocks 」,可以使用三引号将复杂的字符串赋值,从而让我们从各种转义中解脱出来,可以更加方便的编辑字符串。 这个功能在其他语言还是比较常见的,比如 Python 等。 Text Blocks 新功能在 JDK14 再次以预览功能引入,最终在 JDK15

JVM系列之:String.intern的性能

孤街醉人 提交于 2020-10-29 01:29:46
点击 上方的 蓝字 关注我吧 程序那些事 简介 String对象有个特殊的StringTable字符串常量池,为了减少Heap中生成的字符串的数量,推荐尽量直接使用String Table中的字符串常量池中的元素。 那么String.intern的性能怎么样呢?我们一起来看一下。 String.intern和G1字符串去重的区别 之前我们提到了,String.intern方法会返回字符串常量池中的字符串对象的引用。 而G1垃圾回收器的字符串去重的功能其实和String.intern有点不一样,G1是让两个字符串的底层指向同一个byte[]数组。 有图为证: 上图中的String1和String2指向的是同一个byte[]数组。 String.intern的性能 我们看下intern方法的定义: public native String intern () ; 大家可以看到这是一个native的方法。native底层肯定是C++实现的。 那么是不是native方法一定会比java方法快呢? 其实native方法有这样几个耗时点: native方法需要调用JDK-JVM接口,实际上是会浪费时间的。 性能会受到native方法中HashTable实现方法的制约,如果在高并发的情况下,native的HashTable的实现可能成为性能的制约因素。 举个例子 还是用JMH工具来进行性能分析

这 21 个刁钻的 HashMap 面试题,我把阿里面试官吊打了!

戏子无情 提交于 2020-10-28 21:00:58
程序员的成长之路 互联网/程序员/技术/资料共享 关注 阅读本文大概需要 8 分钟。 来自: cnblogs.com/Young111/p/11519952.html?utm_source=gold_browser_extension 1:HashMap 的数据结构? A:哈希表结构(链表散列:数组+链表)实现,结合数组和链表的优点。当链表长度超过 8 时,链表转换为红黑树。 transient Node < K , V >\ [\] table ; 2:HashMap 的工作原理? HashMap 底层是 hash 数组和单向链表实现,数组中的每个元素都是链表,由 Node 内部类(实现 Map.Entry接口)实现,HashMap 通过 put & get 方法存储和获取。 存储对象时,将 K/V 键值传给 put() 方法: ①、调用 hash(K) 方法计算 K 的 hash 值,然后结合数组长度,计算得数组下标; ②、调整数组大小(当容器中的元素个数大于 capacity * loadfactor 时,容器会进行扩容resize 为 2n); ③、i.如果 K 的 hash 值在 HashMap 中不存在,则执行插入,若存在,则发生碰撞; ii.如果 K 的 hash 值在 HashMap 中存在,且它们两者 equals 返回 true,则更新键值对; iii. 如果

1. 有关线程、并发的基本概念

白昼怎懂夜的黑 提交于 2020-10-28 20:04:19
什么是线程? 提到“线程”总免不了要和“进程”做比较,而我认为在Java并发编程中混淆的不是“线程”和“进程”的区别,而是“任务(Task)”。进程是表示资源分配的基本单位。而线程则是进程中执行运算的的最小单位,即执行处理机调度的基本单位。关于“线程”和“进程”的区别耳熟能详,说来说去就一句话:通常讲一个程序有一个进程,而一个进程可有多个线程。 但是“任务”是很容易忽略的一个概念。我们在实际编码中通常会看到这么一个包叫做xxx.xxx.task,包下是XxxTask等等以Task后缀结尾的类。而XxxTask类通常都是实现Runnable接口或者Thread类。严格来说,“任务”和并发编程没多大关系,就算是单线程结构化顺序编程中,我们也可以定义一个Task类,在类中执行我们想要完成的一系列操作。“任务”我认为是我们人为定义的一个概念,既抽象又具体,抽象在它指由软件完成的一个活动,它可以是一个线程,也可以是多个线程共同达到某一目的的操作,具体在于它是我们认为指定实实在在的操作,例如:定时获取天气任务(定时任务),下线任务......关键就在于不要认为一个任务对应的就是一个线程,也许它是多个线程,甚至在这个任务中是一个线程池,这个线程池处理这个我们定义的操作。 我产生“线程”和“任务”的疑惑就是在《Thinging in Java》这本书的“并发”章节中,它将线程直接定义为一个任务