zoukankan      html  css  js  c++  java
  • java知识点1

    本系列文章源自大神--纯洁的微笑的博客 http://www.cnblogs.com/ityouknow/

    基础篇

    JVM

    JVM内存结构

    • 堆、栈、方法区、直接内存、堆和栈区别

    内存结构图

    控制参数


    -Xms设置堆的最小空间大小。
    -Xmx设置堆的最大空间大小。
    -XX:NewSize设置新生代最小空间大小。
    -XX:MaxNewSize设置新生代最大空间大小。
    -XX:PermSize设置永久代最小空间大小。
    -XX:MaxPermSize设置永久代最大空间大小。
    -Xss设置每个线程的堆栈大小。
    -XX:NewRatio设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
    -XX:SurvivorRatio年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5

    堆和栈区别

    Java内存模型

    • 内存可见性、重排序、顺序一致性、volatile、锁、final

    垃圾回收

    • 内存分配策略、垃圾收集器(G1)、GC算法、GC参数、对象存活的判定

    http://www.cnblogs.com/ityouknow/p/5614961.html
    http://www.cnblogs.com/ityouknow/p/7550068.html
    http://www.cnblogs.com/lirenzuo/tag/JVM/

    JVM参数及调优

    Java对象模型

    • oop-klass、对象头

    HotSpot

    • 即时编译器、编译优化

    类加载机制

    • classLoader、类加载过程、双亲委派(破坏双亲委派)、模块化(jboss modules、osgi、jigsaw)

    加载的过程包括了加载、验证、准备、解析、初始化五个阶段

    加载的例子:

    public class Hello {
    
        static {
            System.out.println("静态代码块");
        }
    
        public Hello() {
            System.out.println("构造方法");
        }
    }
    
    public class AppTest {
        public static void main(String[] args) throws ClassNotFoundException {
            ClassLoader classLoader = AppTest.class.getClassLoader();
            System.out.println(classLoader);
            System.out.println(classLoader.getParent());
            //1.初始化时不执行静态块
            classLoader.loadClass("com.xh.dubbo.demon.Hello");
            //2.初始化时不执行静态块
            Class.forName("com.xh.dubbo.demon.Hello", false, classLoader);
            //3.初始化时执行静态块
            Class.forName("com.xh.dubbo.demon.Hello");
        }
    }
    

    结果:

    sun.misc.Launcher$AppClassLoader@1d44bcfa
    sun.misc.Launcher$ExtClassLoader@2b193f2d
    静态代码块
    

    初始化:

    初始化,为类的静态变量赋予正确的初始值,JVM负责对类进行初始化,主要对类变量进行初始化。在Java中对类变量进行初始值设定有两种方式:

    ①声明类变量是指定初始值
    ②使用静态代码块为类变量指定初始值

    JVM初始化步骤

    1、假如这个类还没有被加载和连接,则程序先加载并连接该类
    2、假如该类的直接父类还没有被初始化,则先初始化其直接父类
    3、假如类中有初始化语句,则系统依次执行这些初始化语句

    类初始化时机:只有当对类的主动使用的时候才会导致类的初始化,类的主动使用包括以下六种:

    – 创建类的实例,也就是new的方式
    – 访问某个类或接口的静态变量,或者对该静态变量赋值
    – 调用类的静态方法
    – 反射(如Class.forName(“com.shengsiyuan.Test”))
    – 初始化某个类的子类,则其父类也会被初始化
    – Java虚拟机启动时被标明为启动类的类(Java Test),直接使用java.exe命令来运行某个主类
    例子:

    public class A {
    
        static {
            System.out.println("A静态代码块");
        }
    
        public A() {
            System.out.println("A构造方法");
        }
    }
    
    public class B extends A{
    
        static {
            System.out.println("B静态代码块");
        }
    
        public B() {
            System.out.println("B构造方法");
        }
    }
    
    new B();
    

    结果:

    A静态代码块
    B静态代码块
    A构造方法
    B构造方法
    

    虚拟机性能监控与故障处理工具

    • jps, jstack, jmap、jstat, jconsole, jinfo, jhat, javap, btrace、TProfiler

    参考:https://blog.csdn.net/yuxin6866/article/details/77718748

    S0C:年轻代中第一个survivor(幸存区)的容量 (kb)
    S1C:年轻代中第二个survivor(幸存区)的容量 (kb)
    S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (kb)
    S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (kb)
    EC:年轻代中Eden(伊甸园)的容量 (kb)
    EU:年轻代中Eden(伊甸园)目前已使用空间 (kb)
    OC:Old代的容量 (kb)
    OU:Old代目前已使用空间 (kb)
    PC:Perm(持久代)的容量 (kb)
    PU:Perm(持久代)目前已使用空间 (kb)
    YGC:从应用程序启动到采样时年轻代中gc次数
    YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
    FGC:从应用程序启动到采样时old代(全gc)gc次数
    FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)
    GCT:从应用程序启动到采样时gc用的总时间(s)
    NGCMN:年轻代(young)中初始化(最小)的大小 (kb)
    NGCMX:年轻代(young)的最大容量 (kb)
    NGC:年轻代(young)中当前的容量 (kb)
    OGCMN:old代中初始化(最小)的大小 (kb)
    OGCMX:old代的最大容量 (kb)
    OGC:old代当前新生成的容量 (kb)
    PGCMN:perm代中初始化(最小)的大小 (kb)
    PGCMX:perm代的最大容量 (kb)
    PGC:perm代当前新生成的容量 (kb)
    S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
    S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
    E:年轻代中Eden(伊甸园)已使用的占当前容量百分比
    O:old代已使用的占当前容量百分比
    P:perm代已使用的占当前容量百分比
    S0CMX:年轻代中第一个survivor(幸存区)的最大容量 (kb)
    S1CMX :年轻代中第二个survivor(幸存区)的最大容量 (kb)
    ECMX:年轻代中Eden(伊甸园)的最大容量 (kb)
    DSS:当前需要survivor(幸存区)的容量 (kb)(Eden区已满)
    TT: 持有次数限制
    MTT : 最大持有次数限制
    
    • jstat -gcutil pid
    • jstat -gc pid
    • jstat -gccapacity pid
    • jstat -gcnew pid
    • jstat -gcnewcapacity pid
    • jstat -gcold pid
    • jstat -gcoldcapacity pid
    • jstat -gcpermcapacity pid
    • jstat -class pid
    • jstat -compiler pid
    • jstat -printcompilation pid

    gc日志分析

    • 启用日志
    -XX:+PrintGCDateStamps
    -XX:+PrintGCDetails
    -Xloggc:./mygc.log
    

    /mygc.log这个路径在项目下,当然也可以写绝对路径

    • 分析日志

    利用在线分析工具http://gceasy.io
    上传打包好的日志文件

    编译与反编译

    • javac 、javap 、jad

    java源码(AppTest.java)

    package com.xh.dubbo.demon;
    
    /**
     * Unit test for simple App.
     */
    public class AppTest {
    
        public static void main(String[] args) {
            System.out.println("hello");
        }
    }
    

    javac 编译

    javac -d . AppTest.java 
    

    得到com/xh/dubbo/demon/AppTest.class,-d主要是指定目录

    运行

    java com.xh.dubbo.demon.AppTest
    

    反编译查看字节码

    javap -c com/xh/dubbo/demon/AppTest.class 
    
    Compiled from "AppTest.java"
    public class com.xh.dubbo.demon.AppTest {
      public com.xh.dubbo.demon.AppTest();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return
    
      public static void main(java.lang.String[]);
        Code:
           0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
           3: ldc           #3                  // String hello
           5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
           8: return
    }
    

    反编译查看源码

    jad com/xh/dubbo/demon/AppTest.class
    

    生成AppTest.jad 文件,内容如下:

    // Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
    // Jad home page: http://www.geocities.com/kpdus/jad.html
    // Decompiler options: packimports(3) 
    // Source File Name:   AppTest.java
    
    package com.xh.dubbo.demon;
    
    import java.io.PrintStream;
    
    public class AppTest
    {
    
        public AppTest()
        {
        }
    
        public static void main(String args[])
        {
            System.out.println("hello");
        }
    }
    

    Java基础知识

    阅读源代码

    • String、Integer、Long、Enum、BigDecimal、ThreadLocal、ClassLoader & URLClassLoader、ArrayList & LinkedList、 HashMap & TreeMap&LinkedHashMap &CouncurrentHashMap、HashSet & LinkedHashSet & TreeSet

    Java中各种变量类型

    熟悉Java String的使用,熟悉String的各种函数

    • JDK 6和JDK 7中substring的原理及区别、
    • replaceFirst、replaceAll、replace区别、
    • String对“+”的重载、
    • String.valueOf和Integer.toString的区别、
    • 字符串的不可变性

    自动拆装箱

    • Integer的缓存机制

    熟悉Java中各种关键字

    • transient、instanceof、volatile、synchronized、final、static、const 原理及用法。

    final:

    · 对基本数据类型来说,对于类变量(static)和全局变量,如果不显式地对其赋值而直接使用,则系统会为其赋予默认的零值,而对于局部变量来说,在使用前必须显式地为其赋值,否则编译时不通过。
    · 对于同时被static和final修饰的常量,必须在声明的时候就为其显式地赋值,否则编译时不通过;而只被final修饰的常量则既可以在声明时显式地为其赋值,也可以在类初始化时显式地为其赋值,总之,在使用前必须为其显式地赋值,系统不会为其赋予默认零值。

            public static final String a = "a";
            public final String b;
            public final String c = "c";
        
            public static final String[] a_array = null;
            public final String[] b_array;
        
            public AppTest(String b) {
                this.b = b;
                b_array = new String[0];
            }
    

    集合类

    • 常用集合类的使用
    • ArrayList和LinkedList和Vector的区别
    • SynchronizedList和Vector的区别
    • HashMap、HashTable、ConcurrentHashMap区别
    • Java 8中stream相关用法
    • apache集合处理工具类的使用
    • 不同版本的JDK中HashMap的实现的区别以及原因

    枚举

    • 枚举的用法、枚举与单例、Enum类
        public enum Color {  
          RED, GREEN, BLANK, YELLOW  
        }  
    
    
    public enum Color {  
        RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);  
        // 成员变量  
        private String name;  
        private int index;  
        // 构造方法  
        private Color(String name, int index) {  
            this.name = name;  
            this.index = index;  
        }  
        // 普通方法  
        public static String getName(int index) {  
            for (Color c : Color.values()) {  
                if (c.getIndex() == index) {  
                    return c.name;  
                }  
            }  
            return null;  
        }  
    }
    
    

    Java IO&Java NIO,并学会使用

    • bio、nio和aio的区别、三种IO的用法与原理、netty

    Java反射与javassist

    • 反射与工厂模式、 java.lang.reflect..

    Java序列化

    • 什么是序列化与反序列化、为什么序列化
    • 序列化底层原理
    • 序列化与单例模式
    • protobuf
    • 为什么说序列化并不安全

    注解

    • 元注解、自定义注解、Java中常用注解使用、注解与反射的结合

    参考:http://www.importnew.com/17413.html,http://www.importnew.com/10294.html

    J2SE5.0版本在 java.lang.annotation提供了四种元注解,专门注解其他的注解:
    @Documented –注解是否将包含在JavaDoc中
    @Retention –什么时候使用该注解
    @Target? –注解用于什么地方
    @Inherited – 是否允许子类继承该注解
    @Documented–一个简单的Annotations标记注解,表示是否将注解信息添加在java文档中。
    @Retention– 定义该注解的生命周期。
    RetentionPolicy.SOURCE – 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
    RetentionPolicy.CLASS – 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
    RetentionPolicy.RUNTIME– 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
    @Target – 表示该注解用于什么地方。如果不明确指出,该注解可以放在任何地方。以下是一些可用的参数。需要说明的是:属性的注解是兼容的,如果你想给7个属性都添加注解,仅仅排除一个属性,那么你需要在定义target包含所有的属性。
    ElementType.TYPE:用于描述类、接口或enum声明
    ElementType.FIELD:用于描述实例变量
    ElementType.METHOD
    ElementType.PARAMETER
    ElementType.CONSTRUCTOR
    ElementType.LOCAL_VARIABLE
    ElementType.ANNOTATION_TYPE 另一个注释
    ElementType.PACKAGE 用于记录java文件的package信息
    @Inherited – 定义该注释和子类的关系

    package com.journaldev.annotations;
     
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
     
    @Documented
    @Target(ElementType.METHOD)
    @Inherited
    @Retention(RetentionPolicy.RUNTIME)
        public @interface MethodInfo{
        String author() default 'Pankaj';
        String date();
        int revision() default 1;
        String comments();
    }
    
    
    package com.journaldev.annotations;
     
    import java.io.FileNotFoundException;
    import java.util.ArrayList;
    import java.util.List;
     
    public class AnnotationExample {
     
    public static void main(String[] args) {
    }
     
    @Override
    @MethodInfo(author = 'Pankaj', comments = 'Main method', date = 'Nov 17 2012', revision = 1)
    public String toString() {
        return 'Overriden toString method';
    }
     
    @Deprecated
    @MethodInfo(comments = 'deprecated method', date = 'Nov 17 2012')
    public static void oldMethod() {
        System.out.println('old method, don't use it.');
    }
     
    @SuppressWarnings({ 'unchecked', 'deprecation' })
    @MethodInfo(author = 'Pankaj', comments = 'Main method', date = 'Nov 17 2012', revision = 10)
    public static void genericsTest() throws FileNotFoundException {
        List l = new ArrayList();
        l.add('abc');
        oldMethod();
    }
     
    }
    
    
    package com.journaldev.annotations;
     
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Method;
     
    public class AnnotationParsing {
     
    public static void main(String[] args) {
        try {
        for (Method method : AnnotationParsing.class
            .getClassLoader()
            .loadClass(('com.journaldev.annotations.AnnotationExample'))
            .getMethods()) {
            // checks if MethodInfo annotation is present for the method
            if (method.isAnnotationPresent(com.journaldev.annotations.MethodInfo.class)) {
                try {
            // iterates all the annotations available in the method
                    for (Annotation anno : method.getDeclaredAnnotations()) {
                        System.out.println('Annotation in Method ''+ method + '' : ' + anno);
                        }
                    MethodInfo methodAnno = method.getAnnotation(MethodInfo.class);
                    if (methodAnno.revision() == 1) {
                        System.out.println('Method with revision no 1 = '+ method);
                        }
     
                } catch (Throwable ex) {
                        ex.printStackTrace();
                        }
            }
        }
        } catch (SecurityException | ClassNotFoundException e) {
                e.printStackTrace();
             }
        }
     
    }
    

    结果:

    Annotation in Method 'public java.lang.String com.journaldev.annotations.AnnotationExample.toString()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=Main method, date=Nov 17 2012)
    Method with revision no 1 = public java.lang.String com.journaldev.annotations.AnnotationExample.toString()
    Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @java.lang.Deprecated()
    Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=deprecated method, date=Nov 17 2012)
    Method with revision no 1 = public static void com.journaldev.annotations.AnnotationExample.oldMethod()
    Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.genericsTest() throws java.io.FileNotFoundException' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=10, comments=Main method, date=Nov 17 2012)
    
    

    JMS

    • 什么是Java消息服务、JMS消息传送模型

    JMX

    • java.lang.management..、 javax.management..

    泛型

    • 泛型与继承
    package com.xh.dubbo.demon;
    
    /**
     * Unit test for simple App.
     */
    public class AppTest<T> {
    
        //静态泛型方法
        public static <T> T hello(T t) {
            return t;
        }
    
        public static void main(String[] args) {
            Generic<String> generic_str = new Generic<String>("hello ");
            Generic<Integer> generic_int = new Generic<Integer>(123);
            Generic<Number> generic_num = new Generic<Number>(333);
    
    
            test4Generic(generic_num);
            test4Generic(generic_int);
            test4Generic(generic_str);//编译期报错:(com.xh.dubbo.demon.Generic<? extends java.lang.Number>)in AppTest cannot be applied to (com.xh.dubbo.demon.Generic<java.lang.String>)
    
    
        }
    
        private static void test4Generic(Generic<? extends Number> generic) {
        }
    
    }
    
    //泛型类
    class Generic<T> {
        private T t;
    
        public Generic(T t) {
            this.t = t;
        }
    
        public T get() {
            return this.t;
        }
    
        //泛型方法
        public <T> T genericMethod1(T t1) {
            return (T) this.get();
        }
    
        //泛型方法
        public <E> E genericMethod2(E e1) {
            return (E) this.get();
        }
    }
    
    //泛型接口
    interface IGeneric<T> {
        void add(T t);
    }
    
    
    • 类型擦除

    • T和? 对比

    
        /**
         * ? 在参数中约束
         *
         * @param animals1
         * @param animals2
         */
        static void test_1(List<? extends Animal> animals1, List<? super Dog> animals2) {
    
        }
    
        /**
         * ? 不能在返回值前面约束
         */
        static <?extends Animal> void test_2() {
    
        }
    
        /**
         * T 不能在参数中约束
         *
         * @param animals1
         * @param animals2
         */
        static void test1(List<T extends Animal> animals1, List<T super Animal> animals2) {
    
        }
    
        /**
         * T 可以在返回值前面约束
         *
         * @param t
         * @param <T>
         */
        static <T extends Animal & Serializable> void test2(T t) {
    
        }
    
    

    Java泛型只存在于源码中,在编译后的字节码文件中,就已经被替换为原来的原生类型了,并且在相应的地方插入了强制转型代码。对于运行期的java语言来说,ArrayList<int>和ArrayList<String>就是同一个类.

    单元测试

    • junit、mock、mockito、内存数据库(h2)

    正则表达式

    • java.lang.util.regex..

    常用的Java工具库

    • commons.lang, commons... guava-libraries netty

    什么是API&SPI

    原文:https://blog.csdn.net/e5945/article/details/24050127

         先描述下API(Application Programming Interface )。在java中,我们使用java提供的很多类、类的方法、数据结构来编写我们的应用程序,最终完成我们需求的程序功能,这里的类、方法、数据结构即是jdk提供的api。api的意义,其实就是这些提供给你完成某项功能的类、接口或者方法。
         而SPI(Service Provider Interface)是指一些提供给你继承、扩展,完成自定义功能的类、接口或者方法。
         API直接为你提供了功能,你使用API就能完成任务。
         SPI是一种回调的思想,回调是指我们在使用api时,我们可以向api传入一个类或者方法,api在合适的时间调用类或者方法。SPI是在一些通用的标准中,为标准的实现产商提供的扩展点。标准在上层提供API,API内部使用了SPI,当API被客户使用时,会动态得从当前运行的classpath中寻找该SPI的实现,然后使用该SPI的实现来完成API的功能。
         SPI的实现方式是:提供实现的实现类打包成Jar文件,这个Jar文件里面必须有META-INF目录,其下又有services目录,其下有一个文本文件,文件名即为SPI接口的全名,文件的内容该jar包中提供的SPI接口的实现类名。
         举一个著名的例子:
         mysql的驱动包提供了java.sql.Driver这个SPI的实现,实现类是com.mysql.jdbc.Driver,在mysql-connector-java-5.1.6.jar中,我们可以看到有一个META-INF/services目录,目录下有一个文件名为java.sql.Driver的文件,其中的内容是com.mysql.jdbc.Driver。 
         在运行DriverManager.getDriver并传入参数“com.mysql.jdbc.Driver”时,DriverManager会从mysql-connector-java-5.1.6.jar中找到com.mysql.jdbc.Driver并实例化返回一个com.mysql.jdbc.Driver的实例。
    

    异常

    • 异常类型、正确处理异常、自定义异常

    时间处理

    • 时区、时令、Java中时间API

    编码方式

    • 解决乱码问题、常用编码方式

    Java并发编程

    什么是线程,与进程的区别

    阅读源代码,并学会使用

    • Thread、Runnable、Callable、ReentrantLock、ReentrantReadWriteLock、Atomic、Semaphore、CountDownLatch、、ConcurrentHashMap、Executors

    线程池

    线程安全

    • 死锁、死锁如何排查、Java线程调度、线程安全和内存模型的关系

    • CAS、乐观锁与悲观锁、数据库相关锁机制、分布式锁、偏向锁、轻量级锁、重量级锁、monitor、锁优化、锁消除、锁粗化、自旋锁、可重入锁、阻塞锁、死锁

    死锁

    volatile

    • happens-before、编译器指令重排和CPU指令重

    synchronized

    • synchronized是如何实现的?
    • synchronized和lock之间关系
    • 不使用synchronized如何实现一个线程安全的单例

    sleep 和 wait

    wait 和 notify

    notify 和 notifyAll

    ThreadLocal

    写一个死锁的程序

    写代码来解决生产者消费者问题

    守护线程

    • 守护线程和非守护线程的区别以及用法
  • 相关阅读:
    Windows JScript 在 游览器 中运行 调试 Shell 文件系统
    autohotkey 符号链接 软连接 symbolink
    软链接 硬链接 测试
    SolidWorks 修改 基准面 标准坐标系
    手机 路径 WebDAV 映射 驱动器
    Win10上手机路径
    explorer 命令行
    单位公司 网络 封锁 屏蔽 深信 AC
    cobbler自动化部署原理篇
    Docker四种网络模式
  • 原文地址:https://www.cnblogs.com/lanqie/p/8707237.html
Copyright © 2011-2022 走看看