zoukankan      html  css  js  c++  java
  • Java核心技术---学习笔记【更新中....】

    -----------------------------面试补充---------------------------------------

    Java内存结构:堆,栈,方法区

    Java后台开发面试知识汇总:https://uploadfiles.nowcoder.com/images/20180914/826546_1536916757441_FF474C03D9D513A3519773CB35561940

    全局变量:堆

    静态变量:方法区

    临时变量:栈

    堆大小由1/3新生代和2/3老生代构成,新生代又细分成一块eden和2块survivor区域

    垃圾回收算法共4钟:MS(标记清除),CP(复制),MC(标记整理)GC(分代收集)【最常见】

    垃圾收集器:Serial,parnew(Serial多线程版本),Parallel,G1

    参考链接: https://blog.csdn.net/yrwan95/article/details/82829186

    Java保证线程安全:

    • 原子性:互斥访问
    • 可见性:volatile线程对内存的修改能被其他线程看到
    • 有序性:一个线程观察其他线程指令的执行顺序

    --------------------------------------------------------------------------------

    一:对Java平台理解,“Java是解释执行”,这句话正确吗?:

    Java平台特点:
    1.跨平台,即书写一次,到处运行
    2.垃圾回收,即通过GC回收分配内存,程序员不用担心内存分配问题
    
    Java包括:
    JRE运行环境(包括JVM和Java类库,JVM提供JIT编译器,JIT就是编译执行)
    JDK(JRE超集,包含了更多东西,比如编译器,诊断工具等)

    二:请对比Exception和Error,另外,运行时异常与一般异常有什么区别?NoClassDefFoundError和ClassNotFoundException有什么区别?

    Exception和Error都继承Throwable类
    Exception即可预料的错误,要被try,catch捕获
    Error即不太可能出现的错误(OutMemoryError),不用try,catch捕获
    
    Exception分为检查异常(需显示捕获)与不检查异常(运行异常,捕获与否看实际情况)
    
    ClassNotFoundException:检查异常,找不到class报错(比如连接jdbc时候驱动放错位置)
    NoClassDefFoundError:编译成功后找不到class报错(比如没有new 某个实例)

    三:谈谈final、fnally、 fnalize有什么不同?

    final:表示修饰的类不可继承,方法不可重写,变量不可修改
    finallytry,catch,finally后面代码一定会执行
    finalize:垃圾回收用到
                    //finally不会被执行的特例
            try {
                System.exit(1);
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            } finally {
                System.out.println("Test fianlly");
            }        

    四:强引用、软引用、弱引用、幻象引用有什么区别?具体使用场景是什么?

    强引用:普通new对象(str在栈,String对象实例在堆),不会被jvm回收
    软应用(与引用队列一起使用):jvm认为内存不足会回收(类似缓存)
    弱引用(与引用队列一起使用):GC发现即回收
    幻象引用(虚引用,与引用队列一起使用):不能访问对象.

    五:Java的字符串,String、StringBufer、StringBuilder有什么区别?

    String:字符串常量
    StringBuffer:字符串变量(线程安全)
    StringBuilder:字符串变量(非线程安全)
    (String改变内容就要新生成一个String对象,消耗内存,而Stringffer是用来字符串拼接用的,更换值不用新生成对象,StringBuilder是Java1.5新增,与StringBuffer没有本质区别,但是取消了线程安全,减少了开支,所以优先级是如下这样)
    StringBuilder>StringBuffer>String
     1 package Test;
     2 
     3 import java.util.Scanner;
     4 
     5 /**
     6 * @author Empirefree 胡宇乔:
     7 * @version 创建时间:2020年3月20日 上午9:30:15
     8 */
     9 public class Main {
    10     public static void main(String[] args) {
    11         StringBuilder stringBuilder = new StringBuilder("牛逼哄哄");
    12         stringBuilder.append("陈牛逼哄哄");
    13         stringBuilder.append("余牛逼哄哄");
    14         stringBuilder.insert(0, "黄牛逼哄哄");
    15         
    16         stringBuilder.delete(0, 1);
    17         stringBuilder.replace(0, 1, " Q");
    18         String str = stringBuilder.toString();
    19         System.out.println(stringBuilder);
    20         System.out.println(str);
    21         
    22     }
    23 }

    六:谈谈Java反射机制,动态代理是基于什么原理?

    反射机制:正射:new对象,反射广泛应用于框架,Java基础功能,赋予程序运行时自省能力,可以利用反射直接操作类和对象
    
    动态代理:方便运行时的动态构建代理,即原理就是反射机制,例子有AOP编程,

    七:int和Integer有什么区别?谈谈Integer的值缓存范围。

    int:原始数据类型
    Integer:是int的包装类,可以在字符串,int转换等,自动装箱,自动拆箱

    八:对比Vector、ArrayList、LinkedList有何区别?

    vector:线程安全的动态数组
    ArrayList:非线程安全的动态数组
    LinkedList:非线程安全双向链表

    九:对比Hashtable、HashMap、TreeMap有什么不同?

    Hashtable:哈希表
    HashMap:更广泛的哈希表,但是非同步,get,put时间复杂度是O(1)
    TreeMap:底层是红黑树,get,put时间复杂度是O(log(n))

    十:如何保证容器是线程安全的?ConcurrentHashMap如何实现高效地线程安全?

    利用同步容器实现(如Hashtable【只是给put,get加上synchronized,不能并发】)还有同步包装器(如Collection.synchronized)
    后来采用并发容器(ConcurrentHashMap基于分离锁的并发实现),线程安全队列等

    十一:Java提供了哪些IO方式? NIO如何实现多路复用? 

    早期传统的java.io包,提供了一些IO功能
    后来引入NIO,NIO2,BIO方式,NIO是同步非阻塞IO,即Channel准备好后/处理完后(同步),线程才会进行处理(不会傻傻等待,即非阻塞)
    多路复用由Channel,Selector,Buffer构成,主要过程是每个SelectChannel向Select注册,然后Select进行选择,避免大量客户连接时,频繁切换线程
     1 package testio;
     2 /**
     3 * @author Empirefree 胡宇乔:
     4 * @version 创建时间:2020年3月29日 下午7:46:01
     5 */
     6 
     7 import java.io.BufferedReader;
     8 import java.io.IOException;
     9 import java.io.InputStreamReader;
    10 import java.io.PrintWriter;
    11 import java.net.InetAddress;
    12 import java.net.ServerSocket;
    13 import java.net.Socket;
    14 import java.util.concurrent.ExecutorService;
    15 import java.util.concurrent.Executors;
    16 
    17 public class DemoServer extends Thread {
    18 
    19      private ServerSocket serverSocket;  
    20      public int getPort() {  
    21          return  serverSocket.getLocalPort();  
    22      }  
    23      public void run() {  
    24          try {
    25              serverSocket = new ServerSocket(0);  
    26              ExecutorService executor = Executors.newFixedThreadPool(8);    //新建立线程池
    27              while (true) {  
    28                  Socket socket = serverSocket.accept();  
    29                  RequesHandler requesHandler = new RequesHandler(socket);  
    30 //                 requesHandler.start();  
    31                  executor.execute(requesHandler);    //存储client线程
    32                  }  
    33              } catch (IOException e) {  
    34                  e.printStackTrace(); 
    35           } finally {  
    36               if (serverSocket != null) {  
    37                   try {    
    38                       serverSocket.close();  
    39                   } catch (IOException e) { 
    40                           e.printStackTrace();  
    41                 };  
    42                 }  
    43          }
    44      }
    45      public static void main(String[] args) throws IOException {
    46         DemoServer server = new DemoServer();
    47         server.start();
    48          try (Socket client = new Socket(InetAddress.getLocalHost(), server.getPort())) {  
    49              BufferedReader buferedReader = new BufferedReader(new InputStreamReader(client.getInputStream()));  
    50              buferedReader.lines().forEach(s -> System.out.println(s));  
    51          }
    52     }
    53      
    54     class RequesHandler extends Thread{
    55          private Socket socket;
    56          public RequesHandler(Socket socket) {
    57             // TODO Auto-generated constructor stub
    58              this.socket = socket;
    59         }
    60          
    61          @Override
    62         public void run() {
    63             // TODO Auto-generated method stub
    64              try (PrintWriter out = new PrintWriter(socket.getOutputStream());){
    65                 out.println("Hello, NIO");
    66                 out.flush();
    67             } catch (Exception e) {
    68                 // TODO: handle exception
    69                 e.printStackTrace();
    70             }
    71         }
    72     }
    73      
    74 }
    普通线程与线程池
     1 package testio;
     2 
     3 import java.util.concurrent.ExecutorService;
     4 import java.util.concurrent.Executors;
     5 
     6 /**
     7 * @author Empirefree 胡宇乔:
     8 * @version 创建时间:2020年3月29日 下午7:57:21
     9 */
    10 class Empirefree extends Thread{
    11     @Override
    12     public void run() {
    13         // TODO Auto-generated method stub
    14         System.out.println(Thread.currentThread().getName() + "正在执行中....");
    15     }
    16 }
    17 
    18 public class Demothreadpool {
    19     
    20     //测试下threadpool
    21     public static void main(String[] args) {
    22         ExecutorService pool = Executors.newFixedThreadPool(2);    //固定,Cache是可变线程池
    23         Thread t1 = new Empirefree();
    24         Thread t2 = new Empirefree();
    25         Thread t3 = new Empirefree();
    26         Thread t4 = new Empirefree();
    27         Thread t5 = new Empirefree();
    28         pool.execute(t1);
    29         pool.execute(t2);
    30         pool.execute(t3);
    31         pool.execute(t4);
    32         pool.execute(t5);
    33         //关闭线程池
    34         pool.shutdown();
    35         
    36         
    37         System.out.println("----------------------");
    38         Father father = new Son();
    39         father.name();    //先调用父类构造,再调用子类构造,只能使用父类继承过来的函数,继承的函数是子类的....
    40         System.out.println("----------------------");
    41         Son son = new Son();
    42         son.name();
    43         son.test();
    44     }
    45 }
    46 
    47 class Father{
    48     public Father() {
    49         // TODO Auto-generated constructor stub
    50         System.out.println("父类.....");
    51     }
    52     public void name() {
    53         System.out.println("陈牛逼哄哄....");
    54     }
    55 }
    56 class Son extends Father{
    57     public Son() {
    58         // TODO Auto-generated constructor stub
    59         System.out.println("子类 ....");
    60     }
    61     public void name() {
    62         System.out.println("余牛逼哄哄....");
    63     }
    64     public void test() {
    65         System.out.println("你能调用这个方法吗?....");
    66     }
    67 }
    线程池与父子类

    十二:Java有几种文件拷贝方式?哪一种最高效

    常见的java.io中FIleInputStream读取,
    然后还有java.nio中的transferTo或transferFrom(速度快,更加利用了现代操作系统的底层机制,避免了不必要copy和上下万切换)
    package runoob;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.nio.channels.FileChannel;
    
    /**
    * @author Empirefree 胡宇乔:
    * @version 创建时间:2020年3月30日 下午9:16:08
    */
    public class StreamFileIo {
        public static void main(String[] args) throws IOException{
            File source = new File("./test.txt");
            File dest = new File("./newtest.txt");
            try(FileChannel sourceChannel = new FileInputStream(source).getChannel();
                FileChannel targetChannel = new FileOutputStream(dest).getChannel();
                    ){
                for(long count = sourceChannel.size(); count > 0;){
                    long transferred = sourceChannel.transferTo(sourceChannel.position(), count, targetChannel);
                    sourceChannel.position(sourceChannel.position() + transferred);
                    count -= transferred;
                            
                }
            }
        }
    }

    十三:接口和抽象类有什么区别?

    接口:不能实例化,是抽象方法的集合,不能有非常量成员,要么是抽象方法,要么是静态方法
    (抽象方法,父类不知道实现某个功能,定义给抽象方法,给不同子类去定义)
    
    抽象类:不能实例化,也是为了代码重用,共用方法或者成员变量就合成抽象类

    十四:谈谈你知道的设计模式?请手动实现单例模式,Spring等框架中使用了哪些模式?

    创建型模式:工厂模式,单例模式等
    结构性型模式:桥接模式,适配器模式
    行为型模式:策略模式,访问者模式
    
    
    单例模式
    public class Singleton{
            private static Singleton instace;
            private Singleton(){}
            private static Singleton getInstace(){
             if(instace == null) instace = new singleton(); 
             return instace;
            }  
    
    }
    
    Spring中的模式
    BeanFactor和ApplicationContext应用了工厂模式
    AOP:代理模式,适配器模式等
    Bean创建:提供的单例和原型等模式。

    十五: synchronized和ReentrantLock有什么区别?有人说synchronized最慢,这话靠谱吗?

    synchronized:java内建的同步机制,保证了线程的互斥访问
    
    ReentrantLock:再入锁,需要unlock()方法释放,不然就会一直占有该锁,然后可以定义条件,控制公平性

    不靠谱,synchronized早期在不同场景下性能不一样,但是后来不断改进后性能优化了

    十六:synchronized底层如何实现?什么是锁的升级、降级?

    synchroinzed:由一对monitorenter/monitorexit指令实现
    
    升级、降级:就是jvm优化synchronized运行的机制当jvm检查到不同的竞争状况时,就会自动切换到适合的锁。
    
    没有竞争->默认是偏斜锁
    有另外线程试图锁定某个偏斜过的对象->轻量级锁(轻量级锁依赖CAS获得锁失败->重量级锁)

    十七:一个线程两次调用start()方法会出现什么情况?谈谈线程的生命周期和状态转移。

    抛出出IllegalThreadStateException运行时异常
    
    列出6种(线程是系统调度的最小单位)
    new(新建), runnable(就绪),blocked(阻塞),waiting(等待),timed_wait(计时等待),terminated(计时等待)

    十八:什么情况下Java程序会产生死锁?如何定位、修复?

    死锁:一种特定的程序状态,两个或多个线程之前,互相持有对方资源而不肯释放而造成永久阻塞状态
    
    jstack(查看线程),jmap(查看内存),jstat(性能分析)
  • 相关阅读:
    spring04
    kepp running 团队视频分析初步总结
    spring03
    第六周学习进度博客
    spring02
    spring初级java 应用。搭建环境。基本语法
    给定一个整数数组 nums 和一个目标值 target,求nums和为target的两个数的下表
    团队项目-运动App
    第五周学习进度博客
    java编写规范
  • 原文地址:https://www.cnblogs.com/meditation5201314/p/12529717.html
Copyright © 2011-2022 走看看