Java程序是如何执行的?

本节从总体来看一下Java中的精髓.java

Java介绍

算法

Java和JDK的关系

JDK(Java Development Kit) Java开发工具包,它包括:编译器,Java运行环境(JRE, Java Runtime Environment), JVM(Java虚拟机),监控和诊断工具等,而Java则表示一种开发语言.数据库

Java程序是怎么执行的?

  1. 先把Java代码编译成字节码,也就是把 .java类型的文件编译成 .class类型的文件.这个过程的大体执行流程: Java源代码 -> 词法分析器 -> 语法分析器 -> 语义分析器 -> 字节码生成器  ->最终生成字节码,其中任何一个节点执行失败就会形成编译失败;
  2. 把class文件放置到Java虚拟机,这个虚拟机一般指的是Oracle官方自带的Hotspot JVM;
  3. Java虚拟机使用类加载器(Class Loader)装载class文件;
  4. 类加载完成以后,会进行字节码校验,字节码校验经过JVM解释器会把字节码翻译成机器码交由操做系统执行.但不是全部代码都是解释执行的,JVM对此作了优化, 好比, 以Hotspot虚拟机来讲, 它自己提供了JIT (Just In Time)也就是咱们一般所说的动态编译器,它可以在运行时将热点代码编译成机器码,这个时候字节码就变成了编译执行.

Java程序执行流程图以下:编程

Java虚拟机是如何断定热点代码的?

Java虚拟机断定热点代码的方式有两种:设计模式

  • 基于采样的热点断定

主要是虚拟机会周期性的检查各个线程的栈顶,若某个或某些方法常常出如今栈顶,那这个方法就是"热点方法".这种断定方式的优势是实现简单;缺点是很难精确一个方法的热度,容易受到线程阻塞或外界因素的影响.缓存

  • 基于计数器的热点断定

主要就是虚拟机给每个方法甚至代码块创建了一个计数器,统计方法的执行次数,超过了必定的阈值则标记此方法为热点方法.安全

Hotspot虚拟机使用的基于计数器的热点探测方法.它使用了两类计数器:方法调用计数器和回边计数器,当达到必定阈值时就会触发JIT编译.服务器

方法调用计数器: 在client模式下的阈值是1500次,Server 是10000次,能够经过虚拟机参数: -XX: CompileThreshold = N 对其进行设置.可是JVM还存在热度衰减, 时间段内调用方法的次数较少,计数器就减少.网络

回边计数器: 主要统计的是方法中循环体代码执行的次数.多线程


由上面的知识点咱们能够看出,要想作到对Java了如指掌,必需要好好学习Java虚拟机,那除了Java虚拟机外,还有哪些知识是咱们Java工程师必须掌握的知识呢?

1.Java基础中的核心内容

字符串和字符串常量池的深刻理解,Array的操做和排序算法,深克隆和浅克隆,各类IO操做,反射和动态代理(JDK自身动态代理和CGLIB)等。

2.集合

集合和String是编程中最经常使用的数据类型,关于集合的知识,主要包含:链表(LinkedList)、TreeSet、栈(Stack)、队列(双端、阻塞、非阻塞队列、延迟队列)、HashMap、TreeMap等,它们的使用和底层存储数据机构都是热门内容。

3.多线程

多线程使用和线程安全的知识,它包括:死锁、6种线程池的使用与差别、ThreadLocal、synchronized、Lock、JUC(java.util.concurrent包)、CAS (Compare and Swap)、ABA问题等。

4.热门框架

Spring、Spring MVC、MyBatis、SpringBoot

5.分布式编程

消息队列(RabbitMQ、Kafka)、Dubbo、Zookeeper、SpringCloud等。

6.数据库

MySQL经常使用引擎的掌握、MySQL前缀索引、回表查询、数据存储结构、最左匹配原则、MySQL的问题分析和排除方案、MySQL读写分离的实现原理以及MySQL的常见优化方案等。Redis的使用场景、缓存雪崩和缓存穿透的解决方案、Redis过时淘汰策略和主从复制的实现方案等。

7.Java虚拟机

虚拟机的组成、垃圾回收算法、各类垃圾回收器的区别、Java虚拟机分析工具的掌握、垃圾回收器经常使用的调优参数等。

8.其余

经常使用算法的掌握、设计模式的理解、网络知识和常见Linux命令的掌握等。


相关题目 

1.Java语言都有哪些特色?

答:Java语言包含如下特色。

  • 面向对象,程序容易理解,开发简单,方便;
  • 跨平台,可运行在不一样服务器类型上,好比:Linux、Windows、Mac等;
  • 执行性能好,运行效率高;
  • 提供大量API扩展,语言强大;
  • 有多线程支持,增长了响应和实时交互能力;
  • 安全性好,自带验证机制,确保程序的可靠性和安全性。
2.Java跨平台实现的原理是什么?

答:要了解Java跨平台实现原理以前,必须先要了解Java的执行过程,Java的执行过程以下:

Java执行流程:Java源代码(.java)-> 编译 -> Java字节码(.class)->经过JVM(Java虚拟机)运行Java程序。每种类型的服务器都会运行一个JVM,Java程序只须要生成JVM能够执行的代码便可,JVM底层屏蔽了不一样服务器类型之间的差别,从而能够在不一样类型的服务器上运行一套Java程序。

3.JDK、JRE、JVM有哪些区别?

答:了解了JDK、JRE、JVM的定义也就明白了它们之间的区别,以下所述。

JDK:Java Development Kit (Java开发工具包)的简称,提供了Java的开发环境和运行环境;

JRE:Java Runtime Environment (Java运行环境)的简称,为Java的运行提供了所需环境;

JVM:Java Virtual Machine (Java虚拟机)的简称,是一种用于计算设备的规范,他是一个虚构出来的计算机,是经过在实际的计算机上仿真模拟各类计算机功能来实现的,简单来讲就是全部的Java程序都是运行在JVM(Java虚拟机)上的。

整体来讲,JDK提供了一整套的Java运行和开发环境,一般使用对象为Java的开发者,固然JDK也包含了JRE;而JRE为Java运行的最小运行单元,通常安装在Java服务器上,因此JDK和JRE能够从用途上进行理解和区分。JVM不一样于JDK和JRE,JVM是Java程序运行的载体,Java程序只有经过JVM才能正常的运行。

4.Java中如何获取明天此刻的时间?

答:JDK8以前使用Calendar.add()方法获取,代码以下:

Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE,1);
System.out.println(calendar.getTime());

JDK8有两种获取明天时间的方法。

方法一,使用  LocalDateTime.plusDays() 方法获取,代码以下:

        LocalDateTime today = LocalDateTime.now();
        LocalDateTime tomorrow = today.plusDays(1);
        System.out.println(tomorrow);

 方法二,使用 LocalDateTime.minusDays() 方法获取,代码以下:

        LocalDateTime today = LocalDateTime.now();
        LocalDateTime tomorrow = today.minusDays(-1);
        System.out.println(tomorrow);

minusDays()方法未当前时间减去n天,传负值就至关于当前时间加n天。

5.Java中如何跳出多重嵌套循环?

答:Java中跳出嵌套循环得两种方式:

  • 方法一:定义一个标号,使用break加标号得方式
  • 方法二:使用全局变量终止循环

方法一,示例代码:

        myfor: for (int i = 0; i < 100; i++) {
            for (int j = 0; j < 100 ; j++) {
                System.out.println("J:" + j);
                if (j == 10){
                    // 跳出多重循环
                    break myfor;
                }
            }
        }

方法二,示例代码:

        boolean flag = true;
        for (int i = 0; i < 100 && flag; i++) {
            for (int j = 0; j < 100; j++) {
                System.out.println("J:" + j);
                if(j == 10){
                    // 跳出多重循环
                    flag = false;
                    break;
                }
            }
        }
6.char变量能不能存储一个中文汉字?为何?

答:char变量能够存贮一个汉字,由于Java中默认使用的编码是Unicode,一个char类型占2个字节(16bit),因此放一个中文是没问题的。

7.Java中会存在内存泄漏吗?请简单描述一下。

答:一个再也不被程序使用的对象或变量一直被占据在内存中就形成了内存泄漏。

Java中得内存泄漏的常见情景以下:

  • 长生命周期对象持有短生命的引用,好比,缓存系统,咱们加载了一个对象放在缓存中,而后一直不使用这个缓存,因为缓存的对象一直被缓存引用得不到释放,就形成了内存泄漏。
  • 各类链接未调用关闭方法,好比数据库Connection链接,未显性地关闭,就会形成内存泄漏。
  • 内部类持有外部类,若是一个外部类的实例对象的方法返回了一个内部类的实例对象,这个内部类对象被长期引用了,即便那个外部类实例对象再也不被使用,但因为内部类持有外部类的实例对象,这个外部类对象将不会被垃圾回收,这也会形成内存泄漏;
  • 改变哈希值,当一个对象被存储进HashSet集合中之后,就不能修改这个对象中的那些参与计算哈希值的字段了,不然对象修改后的哈希值与最初存储进HashSet集合中的哈希值就不一样了,在这种状况下,即便在contains方法使用该对象的当前引用做为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也将致使没法从HashSet集合中单独删除当前对象,形成内存泄露。
相关文章
相关标签/搜索