JDK

如何读懂晦涩的 Class 文件

拟墨画扇 提交于 2020-12-05 21:17:20
Android开发者功能开发几乎都是面向 Java/Kotlin 语法编程,对于 class文件 的关注相对较少。 当你反编译 class文件 或程序编译期修改字节码亦做代码注入时,读懂字节码成为一道绕不开的槛。 文章主要描述如何快速读懂一个 class文件 。涉及到的 JVM 指令及字节码结构已做了整理,这部分知识平时用到的时候查一下便可,用多了自然记住了。即使你是一个新手,按照下面的思路整合,你也可以从 0 上手。 读完本篇文章你会收获: Class 文件结构长啥样 JVM 操作指令有哪些 如何从二进制流中读懂 Class 文件 举个栗子🌰 带你入门 编写一个简单的 java文件 。 使用 javac 编译 TestClass.java 输出 TestClass.Class ,得到的二进制流文件。可以通过工具查看其内容,在 MAC 平台上推荐使用 iHex-Hex Editor 以十六进制格式查看,大概长这个样子。 这看起来像 天书 ,无从下手。实际上任何编程产物最终都会演化成二进制,它必定是按照某种规则来申明对应逻辑。 Java 虚拟机为了能够解析这个文件,要求其内容必须严格按照格式来排版,这种结构格式便是 Class文件结构 。但是单单知道里面有哪些内容还不够,虚拟机还需要一套规则来操作这些内容,这些规则便是 字节码操作指令 。 要读懂这些 天书 ,先得了解 天书

拼多多、饿了么、蚂蚁金服Java面试题大集合

你。 提交于 2020-12-05 20:49:59
自己当初找工作时参加过众多一线互联网公司的Java研发面试,这段时间处于寒冬,然而前几天跳槽找工作,两天面了3家,已经拿了两个offer,觉得可以和大家分享下: 下面为拼多多、饿了么、蚂蚁金服、哈啰出行等公司给我留下较深印象的一些java面试题 private修饰的方法可以通过反射访问,那么private的意义是什么 Java类初始化顺序 对方法区和永久区的理解以及它们之间的关系 一个java文件有3个类,编译后有几个class文件 局部变量使用前需要显式地赋值,否则编译通过不了,为什么这么设计 ReadWriteLock读写之间互斥吗 Semaphore拿到执行权的线程之间是否互斥 写一个你认为最好的单例模式 B树和B+树是解决什么样的问题的,怎样演化过来,之间区别 写一个生产者消费者模式 写一个死锁 cpu 100%怎样定位 String a = "ab"; String b = "a" + "b"; a == b 是否相等,为什么 int a = 1; 是原子性操作吗 可以用for循环直接删除ArrayList的特定元素吗?可能会出现什么问题?怎样解决 新的任务提交到线程池,线程池是怎样处理 AQS和CAS原理 synchronized底层实现原理 volatile作用,指令重排相关 AOP和IOC原理 Spring怎样解决循环依赖的问题

偏向锁、轻量级锁、自旋锁、重量级锁

北城余情 提交于 2020-12-05 19:21:59
基础知识之一:锁的类型 乐观锁 乐观锁是一种乐观思想,即认为读多写少,遇到并发写的可能性低,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,采取在写时先读出当前版本号,然后加锁操作(比较跟上一次的版本号,如果一样则更新),如果失败则要重复读-比较-写的操作。 java中的乐观锁基本都是通过CAS操作实现的,CAS是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败。 悲观锁 悲观锁是就是悲观思想,即认为写多,遇到并发写的可能性高,每次去拿数据的时候都认为别人会修改,所以每次在读写数据的时候都会上锁,这样别人想读写这个数据就会block直到拿到锁。java中的悲观锁就是Synchronized, AQS 框架下的锁则是先尝试cas乐观锁去获取锁,获取不到,才会转换为悲观锁,如RetreenLock。 基础知识之二:java线程阻塞的代价 java的线程是映射到操作系统原生线程之上的,如果要阻塞或唤醒一个线程就需要操作系统介入,需要在户态与核心态之间切换,这种切换会消耗大量的系统资源,因为用户态与内核态都有各自专用的内存空间,专用的寄存器等,用户态切换至内核态需要传递给许多变量、参数给内核,内核也需要保护好用户态在切换时的一些寄存器值、变量等,以便内核态调用结束后切换回用户态继续工作。

synchronized实现原理及其优化-(自旋锁,偏向锁,轻量锁,重量锁)

你离开我真会死。 提交于 2020-12-05 18:41:22
1.synchronized概述:   synchronized修饰的方法或代码块相当于并发中的临界区,即在同一时刻jvm只允许一个线程进入执行。synchronized是通过锁机制实现同一时刻只允许一个线程来访问共享资源的。另外synchronized锁机制还可以保证线程并发运行的原子性,有序性,可见性。 2.synchronized的原理:   我们先通过反编译下面的代码来看看Synchronized是如何实现对代码进行同步的:   步骤:首先找到存放java文件的目录,在地址栏输入cmd进入命令行,然后执行javac test.java命令,形成class文件,接着执行javap -v test.class进行反编译。 【代码示例】:同步方法 1 class thread extends Thread{ 2 Object obj= new Object(); 3 @Override 4 public synchronized void run() { 5 System.out.println("run..." ); 6 } 7 } 8 public class test { 9 public static void main(String[] args) { 10 new thread().start(); 11 } 12 } 反编译结果:   从反编译的结果来看

高级并发编程系列十四(并发集合基础)

▼魔方 西西 提交于 2020-12-05 16:54:35
1.考考你 天气转冷了,但是我们分享的热情不变,它冷它的,我们分享我们的。今天这一篇,在高级并发编程这个系列中,我们准备进入并发集合这个小节了。 说到并发集合,结合你的经历,你能先想一想,应该包含哪些内容吗?或者说你期望知道哪些内容呢? 让我们一起来捋一捋吧: 集合基础应该要有,不过集合基础相信你大概都知道 ConcurrentHashMap,面试经常被问到,没有怎么能行 BlockingQueue,阻塞队列用得也很多,没有也不行 CopyOnWriteArrayList,用得不算多,但是写时复制的思想挺好,可以有 #考考你: 1.你在你的项目中,有直接用到并发集合的案例场景吗 2.如果有,你会如何考虑选择使用哪一个并发集合呢 2.案例 2.1.段子手的自白 如果你是刚入行不久的java程序员,你对java集合框架一定很熟悉,应该还特意把它背下来过,因为教你的人告诉你:集合框架很重要。不光这样,一定还告诉过你:这个东西面试的时候还有意无意的被经常问到。于是你会特别重视 如果你是一个工作了几年,就写了几年CRUD操作的业务开发工程师。平时不留意不怎么关心技术,那么不用说,你很有可能除了ArrayList、HashMap以外,其它都没什么印象了,有没有。 直到你对你现有的老板有了成见,然后想要换坑位的时候,你才会在网络上搜一搜:ArrayList与Vector的区别

探索synchronized偏向锁与重量锁区别-子路老师

荒凉一梦 提交于 2020-12-05 15:52:53
安装CentOS-8.1.1911-x86_64-dvd1.iso(见VirtualBox安装) 下载操作内核glibc库 下载jdk上传到linux 配置环境变量 export JAVA_HOME=/usr/local/software/jdk1.8.0_251 export CLASSPATH=${JAVA_HOME}/lib export PATH=$PATH:${JAVA_HOME}/bin 如果出现 vi /etc/profile修改正确值 输入export PATH=/usr/bin:/usr/sbin:/bin:/sbin:/usr/X11R6/bin 并进行source /etc/profile 更新 环境变量配置成功 yum -y install gcc 安装c编译环境 任意目录新建build tar -zxvf glibc-2.19.tar.gz -C ./build 解压到build文件夹下 操作系统加锁使用的pthread_mutex_lock()方法,我们再次方法中打印调用的线程Id,只要有线程调用os操作系统加锁都会被打印,找到对应的方法文件 添加打印语句 头部需要添加#include <stdio.h> fprintf(stderr,"tid=%lu\n",pthread_self()); 编译文件到/usr/lib: cd glibc-2.19/

001. kogito初体验-环境准备及HelloWorld运行

血红的双手。 提交于 2020-12-05 09:59:07
工作流引擎一直都没有纳入我的知识范围,所以我并没有玩过jbpm, activiti这种传统的工作流引擎。无奈业务永远都做不完,所以终于要对BPM下手了。 1. 环境准备 截止到2020年10月19日,kogito最新版本是Pre-release 0.17.0,正式版1.0还在beta阶段。中文资料还太少,学习主要是从官方文档下手。还好kogito提供了很多的示例来满足一个工作流小白对这个框架的初体验。 $ git clone https://github.com/kiegroup/kogito-examples.git 准备工作可没这么简单,你还需要 IDE: VSCODE(官方推荐)+ kogito插件 JDK 11,为了避免一些可能存在的麻烦,我使用了openjdk 当下最新的15版。 MAVEN 3.6.2 or later 2. 示例:hello-world 2.1 运行示例 example项目下第一个示例,定义了一个脚本流程,如下图所示。 我们为这个流程指定一个唯一的process-id叫作: // 流程说明 1. 开始 - 入参name 2. 脚本任务 - SayHello,java,System . out . println ( "Hello " + name ) ; 3. 脚本任务 - UpdateMessage,java,kcontext .

配置java环境变量

China☆狼群 提交于 2020-12-05 02:25:11
安装JDK 选择安装目录 安装过程中会出现两次 安装提示 。第一次是安装 jdk ,第二次是安装 jre 。建议两个都安装在同一个java文件夹中的不同文件夹中。(不能都安装在java文件夹的根目录下,jdk和jre安装在同一文件夹会出错) 如下图所示 1:安装jdk 随意选择目录 只需把默认安装目录 \java 之前的目录修改即可 2:安装jre→更改→ \java 之前目录和安装 jdk 目录相同即可 注:若无安装目录要求,可全默认设置。无需做任何修改,两次均直接点下一步。 安装完JDK后配置环境变量 计算机→属性→高级系统设置→高级→环境变量 系统变量→新建 JAVA_HOME 变量 。 变量值填写jdk的安装目录(本人是 E:\Java\jdk1.7.0) 系统变量→寻找 Path 变量→编辑 在变量值最后输入 %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; (注意原来Path的变量值末尾有没有;号,如果没有,先输入;号再输入上面的代码) 6 系统变量→新建 CLASSPATH 变量 变量值填写 .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar(注意最前面有一点) 系统变量配置完毕 7 检验是否配置成功 运行cmd 输入 java -version (java 和 -version 之间有空格) 若如图所示

Java的环境变量配置

£可爱£侵袭症+ 提交于 2020-12-05 02:04:08
第一步:下载jdk,进入Oracle官网( http://www.oracle.com/technetwork/java/javase/downloads/index.html )下载对应的jdk。这里以jdk1.8Windows64为例。 点击同意accept后下载。下载完成之后按照提示安装之后进行环境变量配置: 我的电脑-右击属性-高级系统设置-环境变量配置-系统环境变量 第一步:JAVA_HOME的配置。 变量名: JAVA_HOME 变量值: D:\Java\jdk1.7.0_80 第二步:PATH路经的配置。 变量名: PATH 变量值: ;%JAVA_HOME%\jre\bin; 第三步:CLASSPATH路经的配置。 变量名: CLASSPATH 变量值: .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar; 最后验证是否配置成功: 在终端Win+R输入cmd打开终端:输入 java java -version 来源: oschina 链接: https://my.oschina.net/u/4214815/blog/3107919

Java 14 发布了,不使用"class"也能定义类了?还顺手要干掉Lombok!

我们两清 提交于 2020-12-05 01:38:49
2020年3月17日发布,Java正式发布了JDK 14 ,目前已经可以开放下载。在JDK 14中,共有16个新特性,本文主要来介绍其中的一个特性:JEP 359: Records 官方吐槽最为致命 早在2019年2月份,Java 语言架构师 Brian Goetz,曾经写过一篇文章(http://cr.openjdk.java.net/~briangoetz/amber/datum.html ),详尽的说明了并吐槽了Java语言,他和很多程序员一样抱怨“Java太啰嗦”或有太多的“繁文缛节”,他提到:开发人员想要创建 纯数据载体 类(plain data carriers)通常都必须编写大量低价值、重复的、容易出错的代码。如:构造函数、getter/setter、equals()、hashCode()以及toString()等。 以至于很多人选择使用IDE的功能来自动生成这些代码。还有一些开发会选择使用一些第三方类库,如Lombok等来生成这些方法,从而会导致了令人吃惊的表现(surprising behavior)和糟糕的可调试性(poor debuggability)。 那么,Brian Goetz 大神提到的纯数据载体到底指的是什么呢。他举了一个简单的例子: final class Point { public final int x; public final int y