• 有价值的面试问题


    有时会看到比较有趣的面试题记录在这个随笔里面

    一.private修饰的方法可以通过反射访问,那么private的意义是什么?

    答:简单来说,private并不是解决“安全”问题的。private想表达的不是“安全性”的意思,而是OOP的封装概念,是一种编译器可以帮助你的设计上的hint。这就像是一家没人的店挂了个牌子“闲人免进”,
    但你真要进去还是有各种办法可以办到。所以private,以及所有其他的access modifier都有一层隐含的含义:如果你按照遵守这套规则,开发者可以保证不问题(不考虑bug的情况下);否则,后果自负。
     
    二.Java类初始化顺序?

    答:父类--静态变量 → 父类--静态初始化块 → 子类--静态变量 → 子类--静态初始化块 → 子类main方法 → 父类--变量 → 父类--初始化块  → 父类--构造器  →子类--变量  →子类--初始化块  → 子类--构造器
    三.一个java文件有3个类,编译后有几个class文件?

    答:一个Java文件有几个class编译后就会有几个class文件。 参考博客:https://blog.csdn.net/loongstyle/article/details/82875140
    四.局部变量使用前需要显式地赋值,否则编译通过不了,为什么这么设计?

    答:局部变量不默认赋值的原因是因为怕编码者忘记赋值,导致系统出问题。
    五.写一个你认为最好的单例模式?
    
    答:
    public class Singleton {
    
        private static volatile Singleton singleton;
    
        private Singleton() {}
    
        public static Singleton getInstance() {
            if (singleton == null) {
                synchronized (Singleton.class) {
                    if (singleton == null) {
                        singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }
    }
    六.写一个死锁
    
    答:
    /** 
    * 一个简单的死锁类 
    * 当DeadLock类的对象flag==1时(td1),先锁定o1,睡眠500毫秒 
    * 而td1在睡眠的时候另一个flag==0的对象(td2)线程启动,先锁定o2,睡眠500毫秒 
    * td1睡眠结束后需要锁定o2才能继续执行,而此时o2已被td2锁定; 
    * td2睡眠结束后需要锁定o1才能继续执行,而此时o1已被td1锁定; 
    * td1、td2相互等待,都需要得到对方锁定的资源才能继续执行,从而死锁。 
    */ 
    public class DeadLock implements Runnable {  
        public int flag = 1;  
        //静态对象是类的所有对象共享的  
        private static Object o1 = new Object(), o2 = new Object();  
        @Override 
        public void run() {  
            System.out.println("flag=" + flag);  
            if (flag == 1) {  
                synchronized (o1) {  
                    try {  
                        Thread.sleep(500);  
                    } catch (Exception e) {  
                        e.printStackTrace();  
                    }  
                    synchronized (o2) {  
                        System.out.println("1");  
                    }  
                }  
            }  
            if (flag == 0) {  
                synchronized (o2) {  
                    try {  
                        Thread.sleep(500);  
                    } catch (Exception e) {  
                        e.printStackTrace();  
                    }  
                    synchronized (o1) {  
                        System.out.println("0");  
                    }  
                }  
            }  
        }  
       
        public static void main(String[] args) {  
               
            DeadLock td1 = new DeadLock();  
            DeadLock td2 = new DeadLock();  
            td1.flag = 1;  
            td2.flag = 0;  
            //td1,td2都处于可执行状态,但JVM线程调度先执行哪个线程是不确定的。  
            //td2的run()可能在td1的run()之前运行  
            new Thread(td1).start();  
            new Thread(td2).start();  
       
        }  
    }
    七.cpu 100%怎样定位?
    
    答:
    1.先用top定位最耗cpu的java进程 例如: 12430
    
    2.然后用top -p 12430 -H 定位到最耗cpu的线程 的ID 例如:12483
    
    3.把第二步定位的线程ID ,转成16进制,printf "%x
    " 12483  得到 :30c3
    
    4.从jstack 输出的线程快照中找到线程的对堆栈信息  jstack 12430 |grep 30c3 -A 60 |less
    八.String a = "ab"; String b = "a" + "b"; a == b 是否相等,为什么?
    
    答:不相等,String是引用类型,引用类型用==比较的是地址不是值。
    九.可以用for循环直接删除ArrayList的特定元素吗?可能会出现什么问题?怎样解决?
    
    答:不能,ArrayList的底层结构是数组类型,数组这种数据结构的特点是删除其中某个元素时,后面的所有元素索引都会前移,此时for循环的指针却会下移,因此会略过下一个元素,使用迭代器删除可以避免此问题






  • 相关阅读:
    转: jsp之c标签
    win10下乌龟git安装和使用
    使用Node.js+Socket.IO搭建WebSocket实时应用
    前端优化
    pyqt5环境搭建
    pandas分页读取excel
    PySpark之RDD操作
    PySpark环境搭建
    Django与Celery最佳实践
    Elasticsearch的安装与简单使用
  • 原文地址:https://www.cnblogs.com/jiuhaoyun/p/10308921.html
Copyright © 2020-2023  润新知