Java 语言对我来说即熟悉又陌生的语言,原来是特别喜欢Java,就觉得它是世界最好的语言。 设计的规范非常好,代码看起来非常完整,还有巨大的组件/jar库。 总之来说是非常强大。 随着几年没有接触过它,慢慢就忘记它了。 就好比一辆车,之前一直经常开觉得很顺手,现在重新开起发现当年的感觉比较难找到了。【重拾JAVA】
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c3fb74a0.jpg) 
	根据java的语法生成java文件/类文件,然后通过javac 工具,直接把java文件加载到JVM,然后生成字节码。 应用请求JRE环境,JRE把class执行结果返回给应用。
Java SE: CLI 请求JRE环境->调用/生成class文件->调用本地库->输出
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c4a3ce51.gif) 
	Java语言的解析器,可以把类文件编译生成class文件的过程。总的过程:1. 归类: 把执行的对象和变量/对象申请内存块,放到heap里面,把方法放到方法区域; 2.解析和执行过程:对于类文件,先编译,如果有存在空对象/空指针等报错会抛出人释放内存,执行完后垃圾回收内存;3. 调用本地系统的方法,如文件,I/O等方法,生成class 文件。
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c54a8dab.jpg) 
	![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5526132.jpg) 
					类加载的主要思路:对于引用的类,会先在classpath配置里面找找到就会加载,不然继续向上找,知道找到rt.jar,如果还不存在,这报错"ClassNotFoundException"
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c559264c.png) 
			总的来说:加载class文件->验证->分配内存空间->符号解析,变量、常量池->初始化可以使用了
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5655b6f.png) 
	Java 基础知识就是怎么根据Java API生成java类文件。 Java API包含了组件/工具如下图结构描述:
Java知识结构
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c56d46ec.jpg) 
			Java SE相关文档
对象里面包含了属性和方法,通过Main函数启动CLI 进程来执行对类文件的解析。
public class Bicycle {
    int speed = 1;
    int gear = 1;
    public void addSpeed(int value){
        this.speed += value;
    }
    public int getSpeed(){
        return this.speed;
    }
    public int getGear(){
        return this.gear;
    }
}
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello World!");
        Bicycle b = new Bicycle();
        b.addSpeed(3);
        b.addSpeed(4);
        System.out.println("Speed value :"+b.getSpeed());
        System.out.println("Gear value :"+b.getGear());
    }
}
复制代码
	public class RoadBicycle extends  Bicycle {
    private int road =1;
    public void setRoad(int val){
        this.road += val;
        //增加加速值
        this.road += this.getGear();
    }
    public int getRoad(){
        return this.road;
    }
}
复制代码
	public class Disk implements Circle{
    private int weight = 100;
    public void setWeight(){
        this.weight += 10;
    }
    public int getLength() {
        return this.weight/3;
    }
    public int getRadius() {
        return this.weight/2;
    }
}
复制代码
	public int[] getArray(){
        int [] anArray = new int [10];;
        for(int i=0; i<10; i++)
        {
            anArray[i] = i+10;
        }
        return anArray;
    }
复制代码
	public void invokeCalculator(){
    Calculator myApp = new Calculator();
    IntegerMath addition = (a, b) -> a + b;
    IntegerMath subtraction = (a, b) -> a - b;
    System.out.println("40 + 2 = " +
            myApp.operateBinary(40, 2, addition));
    System.out.println("20 - 10 = " +
            myApp.operateBinary(20, 10, subtraction));
}
复制代码
	注解是一种元数据形式,提供有关不属于程序本身的程序的数据。注解对他们注释的代码的操作没有直接的影响。
注解的作用:
注解可以声明字段,类,方法,属性等
@Target: 说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。
@Retention定义了该Annotation被保留的时间长短 : 1.SOURCE:在源文件中有效;2.CLASS:在class文件中有效;3.RUNTIME:在运行时有效
@Documented : 用于描述其它类型的annotation应该被作为被标注的程序成员的公共API
@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。
定义注解格式:
  public @interface 注解名 {定义体}
复制代码
	泛型的作用:在定义类,接口和方法时,泛型使类型(类和接口)成为参数。
常用的类型参数
E - Element (used extensively by the Java Collections Framework) K - Key N - Number T - Type V - Value S,U,V etc. - 2nd, 3rd, 4th types 复制代码
public class OrderedPair<K, V> implements Pair<K, V> {
    private K key;
    private V value;
    public OrderedPair(K key, V value) {
        this.key = key;
        this.value = value;
    }
    public K getKey()	{ return key; }
    public V getValue() { return value; }
}
public interface Pair<K, V> {
    public K getKey();
    public V getValue();
}
//泛型的处理
Pair<String, Integer> p1 = new OrderedPair<String, Integer>("Even", 8);
System.out.println("Generic  key :" + p1.getKey() + " , value :" + p1.getValue());
复制代码
	提供了一种包命名的方式
捕获异常,异常的处理一般在文件,I/O,数据库,这些地方存在各种不确定的情况,影响其中断。
// 捕获异常
try {
} catch (IndexOutOfBoundsException e) {
    System.err.println("IndexOutOfBoundsException: " + e.getMessage());
} catch (IOException e) {
    System.err.println("Caught IOException: " + e.getMessage());
}
//扔出异常
public Object pop() {
    Object obj;
    if (size == 0) {
        throw new EmptyStackException();
    }
    obj = objectAt(size - 1);
    setObjectAt(size - 1, null);
    size--;
    return obj;
}
复制代码
	I 表示输入流, O 表示输出流
I/O 流主要的方式
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5751285.jpg) 
			I/O采用很多设计模式,流是解决获取数据的加载到内存缓存区问题 , Writer主要是解决流的序列化/存储的问题
流的类型包括:
public boolean write(String sourceFileName, String targetFileName) throws  IOException{
        FileReader inputStream = null;
        FileWriter outputStream = null;
        try {
            System.out.println("Now sourceFile :" +sourceFileName + " , targetFileName: "+ targetFileName);
            inputStream = new FileReader(sourceFileName);
            outputStream = new FileWriter(targetFileName);
            int c;
            while ((c = inputStream.read()) != -1) {
                outputStream.write(c);
            }
           // return true;
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
            return  false;
        }
    }
复制代码
	在并发编程中,有两个基本的执行单元:进程和线程,一个进程有一个独立的执行环境。一个进程通常具有一套完整的私有基本运行时资源; 特别是每个进程都有自己的内存空间。所以处理大并发的事情,更多的是关系进程或者线程对服务器资源的压力。包括CPU, 内存等
现在启动的方式主要有两种,一种是实现Runable接口,另一种是继承Thread
// 每个线程都继承了Runnable方法,每个方法都考虑执行的效果
public class HelloRunnable implements Runnable {
    public void run() {
        System.out.println("Hello from a thread!");
    }
    public static void main(String args[]) {
        (new Thread(new HelloRunnable())).start();
    }
}
// 继承Thread的方式
public class HelloThread extends Thread {
    public void run() {
        System.out.println("Hello from a thread!");
    }
    public static void main(String args[]) {
        (new HelloThread()).start();
    }
}
复制代码
	这个存在问题就是如果出现一个资源获得了锁,另外一个资源确一直没有释放锁,就出现死锁的情况。 这样就需要考虑资源的sleep和必要的中断
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c57a3121.jpg) 
	public class Test {
     public static void main(String[] args) {   
         ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,
                 new ArrayBlockingQueue<Runnable>(5));
         for(int i=0;i <15 ; i++){
             MyTask myTask = new MyTask(i);
             executor.execute(myTask);
             System.out.println("线程池中线程数目:"+executor.getPoolSize()+",队列中等待执行的任务数目:"+
             executor.getQueue().size()+",已执行玩别的任务数目:"+executor.getCompletedTaskCount());
         }
         executor.shutdown();
     }
}
 
class MyTask implements Runnable {
    private int taskNum;
 
    public MyTask(int num) {
        this.taskNum = num;
    }
 
    @Override
    public void run() {
        System.out.println("正在执行task "+taskNum);
        try {
            Thread.currentThread().sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("task "+taskNum+"执行完毕");
    }
}
复制代码
	支持对系统的属性使用Key和value的方式crud。Properties继承了java.util.Hashtable, 可以使用其一些属性特性
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5812d37.gif) 
	主要是Java的工具包获取,Pattern.compile
Console console = System.console();
        if (console == null) {
            System.err.println("No console.");
            System.exit(1);
        }
        while (true) {
            Pattern pattern = 
            Pattern.compile(console.readLine("%nEnter your regex: "));
            Matcher matcher = 
            pattern.matcher(console.readLine("Enter input string to search: "));
            boolean found = false;
            while (matcher.find()) {
                console.format("I found the text" +
                    " /"%s/" starting at " +
                    "index %d and ending at index %d.%n",
                    matcher.group(),
                    matcher.start(),
                    matcher.end());
                found = true;
            }
            if(!found){
                console.format("No match found.%n");
            }
        }
复制代码
	集合拆分成三种方式:List(数组列表) ,Set(不允许有重复元素的集合) ,Map(key和value 集合).Queue也是其中的一种方式
数据结构
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5886fc7.jpg) 
			算法
主要使用LocalTime 获取时间的操作
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5918cb4.jpg) 
	DateTimeFormatter formatter =
                      DateTimeFormatter.ofPattern("MMM d yyyy");
    LocalDate date = LocalDate.parse(input, formatter);
    System.out.printf("%s%n", date);
复制代码
	反射机制本质就是根据地址块,如对象,类,方法的地址块去检查或者修改其行为。 主要的机制是java 虚拟机可以通过命名空间+类名对内存块的使用。 并且所有类/对象都有其自身的元数据包括public,private,属性等情况。
好的地方主要是可以外部调用,如调试,开发工具,Spring的根据类名获取对象,不好的地方主要是性能消耗大,并且可能会影响一些安全
通过运行时加载该类,然后找到这个类的方法和域(一般是解析字节码获得到类相关的元数据),生成列表信息,最后动态加载该类。
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c59a21e3.jpg) 
	网络一般真正处理是专注于讲应用层的数据传递到TCP 层,然后通过IP协议转换
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5a25f7d.jpg) 
	数据包的内容
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5a6e52f.jpg) 
			Socket 通信架构
Socket是解决数据两种,一种是发数据,一种是接受数据,都是通过ip+端口的绑定,服务端是通过循环监听客户端的Socket数据
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5acf586.jpg) 
	public void run() {  
        try {  
            BufferedReader br = new BufferedReader(new InputStreamReader(socket  
                    .getInputStream()));  
            while (true) {  
                String msg = br.readLine();  
                if ("exit".equalsIgnoreCase(msg))  
                    break;  
                System.out.println("("  
                        + socket.getInetAddress().getHostAddress() + ":"  
                        + socket.getPort() + "):" + msg);  
            }  
            br.close();  
            socket.close();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
复制代码
	Http一般有建立连接,发送请求和接受请求,最后关闭三个过程,如果很长时间才关闭通道,才关闭这算长连接,否则处理完就关闭,算短连接。
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5b3113f.png) 
	远程方法调用这种方式适合内部机器的通信,但是考虑到系统兼容性这种方式也不太好,最后一般会采用内部的http的通信或者采用webserivce的方式。 主要是通过注册了这个方法,然后远程根据方法的参数和规范,来调用。 应该也是采用RPC的规范来走的。
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5b9cc34.gif) 
	方便的是可以针对java语言搞分布式计算跟语言绑定,可以在虚拟机注册列表里面调用任何的注册服务,但是这个依赖性太强了。后期的protobuf方式就是对现有的替代了。 - 动态代码加载的优点: 通过注册类的方式来动态加载 - 可以调用远程接口和方法: 主要是通过RPC/TCP协议来处理 - 使用RMI创建分布式应用程序 :可以把 - 可以建立分布式应用: 计算引擎
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5c2f2ff.jpg) 
	)
主要是对于java的产品提供安全的认证,包括数字签名
JDBC 主要解决了,JAVA提供的数据库驱动API,这样只要导入了对应的驱动文件,就可以调用其服务哦。
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5c8b2ef.jpg) 
	public void connectToAndQueryDatabase(String username, String password) {
    Connection con = DriverManager.getConnection(
                         "jdbc:myDriver:myDatabase",
                         username,
                         password);
    Statement stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
    while (rs.next()) {
        int x = rs.getInt("a");
        String s = rs.getString("b");
        float f = rs.getFloat("c");
    }
}
复制代码
	开发工具: (在bin/子目录中)将帮助您开发,执行,调试和编写以Java编程语言编写的程序的工具和实用程序。有关更多信息,请参阅工具文档。
运行环境: (在jre/子目录中)由JDK使用的Java运行时环境(JRE)的实现。JRE包含一个Java虚拟机(JVM™),类库和其他支持执行用Java编程语言编写的程序的文件。
额外的库: (在lib/子目录中)开发工具所需的其他类库和支持文件。
Java DB: (在db/子目录中)Java DB,Oracle分布的Apache Derby关系数据库。有关更多信息,请参阅文档。
C文件头: (在include/子目录中)使用Java本地接口,JVM工具接口和Java平台的其他功能支持本地代码编程的头文件。
源代码:(In src.zip)构成Java核心API的所有类的Java编程语言源文件。使用:jar xvf src.zip
javac字节码编译器:
由以下文件组成的动态连接机制:
Java密码扩展:
Java EE: 应用(浏览器/其他Clent)发送http请求 -> 服务器(tomcat/nginx)-> Java CGI -> 请求JRE环境->调用/生成class文件->调用本地库->输出
是在前面RMI发展而来的。 支持满足企业级开发的方式。 但是标准一致很高,特别是EJB非常难上手,并且关联的东西非常多。最后,Spring 以j2EE标准基础上专门切入Bean管理也即是EJB的轻量版本(Model层),然后迅速占领J2EE的开发框架重要地位,并且慢慢的把controller(Struct)解决了。甚至对V层也有一定的组件和扩展。 就出现了Spring MVC 框架。最后为了解决EJB分布式开发部署的成本问题,开发了Spring Boot 满足开发的需求。
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5cf2acb.jpg) 
	主要是采用mvc的机制,最后通过Dao层去读取数据库
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5d5f033.png) 
	![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5dc66af.png) 
	![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5e20501.png) 
	![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5eca7b5.jpg) 
	![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5f567f9.jpg) 
	![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c5fb86ce.jpg) 
	Maven 本质是解决jar包的统一管理的问题,这样避免每个项目之前还要下载大量的jar,并且有的时候还需要去找jar很麻烦的。 之前有类似的网站可以下载到各种jar包你根据名字搜索就好,但是一个个下载不方便。 基于解决这类问题出现了maven. 其实每种语言都有类似的工具,如php 有Composer, python 有pip
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c6072718.png) 
	![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c60dd5d1.jpg) 
			Tomcat 是服务器主要的是监听某个端口的服务器,Tomcat会自动读取webapps 下的war文件。 而war文件Tomcat 会自动把java语言的代码根据j2EE的规范来生成war包。
对于多个应用的部署,本地可以使用{DOMAIN_NAME}/{app} 来管理多个项目,如果是线上,可以采用Nginx +Tomcat的方式,Nginx 负责分发,Tomcat负责启动多个服务来监听Nginx的服务。
idea 和 Tomcat 关系: idea 使用Tomcat 把web代码生成war包,然后浏览器可以通过tomcat解析和处理这个war
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c6192080.jpg) 
	![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c6234fa8.jpg) 
	github的wiki 有详细的解释
![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c63b6b43.png) 
	![[JAVA]面试知识点整理](http://www.liuhaihua.cn/wp-content/uploads/2019/09/20190831_5d6a9c6462a86.jpg) 
	解决方式:把maven 类文件重新配置下,对于存在冲突的库去掉,然后重新导入下
java.lang.NoSuchMethodError: org.springframework.util.ClassUtils.isPresent(Ljava/lang/String;Ljava/l 复制代码
nginx: [error] invalid PID number "" in "/usr/local/var/run/nginx.pid" 复制代码
## 解决 Mac 下配置环境变量在 ZSH 中无效的问题 在终端中输入: cat ~/.zshrc 以此来查看 .zshrc 文件, 找到里面的 “ # User configuration “ 部分. 可以看到当前 zsh 支持的所有本地已配置环境变量. ## 输入gradle home和path 目录 GRADLE_HOME=/usr/local/Cellar/gradle/4.4; export GRADLE_HOME export PATH=$PATH:$GRADLE_HOME/bin 复制代码
应该使用如下路径进行设置:/usr/local/Cellar/gradle/2.4/libexec ,问题的关键就是路径要有 libexec 复制代码