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

    写一个死锁的程序

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

    守护线程

    • 守护线程和非守护线程的区别以及用法
  • 相关阅读:
    没人关注的角落是个好地方
    PICKIT3 WIN10 无法连接问题解决
    TM1650+msp430单片机 调试及遇到问题的总结
    即将会来日常更新stm32的学习过程
    Learn Arduino the hard way 1——点亮一个LED
    准备再次开始更新
    Tcl之Read files for synthesis
    Verilog之event
    Tcl之Math
    Digital design之Boolean Algebra
  • 原文地址:https://www.cnblogs.com/lanqie/p/8707237.html
Copyright © 2011-2022 走看看