java面试题

    技术2022-07-14  81

    java面试题

    最近要面试,自己准备一下面试题一、String 为什么用final修饰二、Hashmap的理解三、ArrayList和LinkedList各自实现和区别四、Java中的队列都有哪些,有什么区别五、Mybatis六、反射中,Class.forName和classloader的区别七、string、stringbuilder、stringbuffer区别八、异常的结构,运行时异常和非运行时异常,各举个例子九、 session和cookie的区别十、 垃圾回收机制十一、 垃圾收集器十二、 sql优化十三、 线程按顺序打印abcabc十四、接口与抽象类的区别十五、单例模式

    最近要面试,自己准备一下面试题

    一、String 为什么用final修饰

    (1)为了实现字符串池 (2)为了线程安全 (3)为了实现string的hashcode的不可变性 解答: final仅仅代表引用地址不可变,没有说数组不可变(但是private保证了),当保证了string不可变之后,字符串池才可以实现,才可以保证效率,这样不同字符串变量都指向同一个字符串。

    二、Hashmap的理解

    (1)hashmap(线程不安全,但是效率快,可以允许为null),hashtable(线程安全,但是ConcurrentHashMap(相比较由于有一个分段锁,技术把一段一段数据分开并配锁,访问一段线程占用锁,其他数据都可以访问)),treemap(根据记录键排序,如果需要排序映射必须实现cpmparable的接口或者是传入构造器comparator),linkedhashmap(迭代器按照顺序遍历,先得到的都是先插入的记录)都是继承map (2)内部实现:hashmap有一个叫哈希桶数组(node [] table(键值对)),在hashmap用哈希表存储(用于解决冲突),链地址法,数据被hash后,得到数组下标,再把数组放到对应下标元素的链表上,系统先对键进行hashcode得到对应的值后,再进行(高位运算和取模运算)来进行存储,有时候会发送hash碰撞,这个时候就是扩容机制跟好的hash算法解决。 (3)扩容机制:node [] table 默认长度为16 ,负载因子为0.75,而hashmap能容纳的最大个数为两个的乘积,当大于这个值则扩容之前的两倍 (4)hashmap的put方法:一、先对键值对的table[i]判断是否为空或null,如果不是则扩容,二、如果是则对key进行hash,如果table[i]=null直接添加并判断此时的数量是否大于最大容量,是则扩容,三、如果table[i]不等于空,则判断table[i]第一个值进行hashcode和equal的判断,如果一致覆盖value值,如果不同再判断是否等于红黑树,如果是直接插入树中,不是则判断链的长度,大于8则转为红黑树 插入,不是则链表插入,遍历过程如果key一致覆盖value

    三、ArrayList和LinkedList各自实现和区别

    1、ArayList底层是数组,查询快,增删慢,LinkedList是元素列表,插入,添加,删除操作速度更快

    四、Java中的队列都有哪些,有什么区别

    1、Rabbit MQ:消峰及限流,解耦,异步,数据分发,分布式事务 2、先与Rabbit创建一个TCP连接,然后通过认证就是连接用户跟密码,连接了就会有一个信道,然后所有的命令都是听那个歌这个通道完成。 3、有两种连接方法: (一)创建Rabbit连接:setUaername,setPassword,setPort,setHost等 (二)应用类使用 1、创建通道:声明队列设定名称,持久化,独占模式,断开是否删除, 2、发送内容:交换机,队列名称,其他属性 3、发送消息:(1)生产者和broker建立TCP连接和通道,(2)生产者通过通道发送消息给broker,再由交换机建消息转发,(3)由交换机转发到指定的队列 4、接收消息:(1)消费者和broker建立TCP连接和通道,(2)消费者监听指定队列,消息到达默认推送给消费者,消费者接收。 (三)nginx

    五、Mybatis

    一、1、创建SqlSessionFactory,2、通过SqlSessionFactory创建SqlSession,3、通过SqlSession执行数据库操作,4、调用session.commot提交事务,5、调用session.close 二、与hibernate的区别 1、mybatis入门简单,可以自动绑定数据库的查询的功能,2、进行sql优化,减少查询字段,3、底层的sql语句还需要自己写 2、hibernate:功能强大,O/R映射能力强,可以减少代码的书写,门槛较高,需考虑性能与对象模型取得平衡

    六、反射中,Class.forName和classloader的区别

    先对类加载器的步骤说明(1、装载(:导入二进制的数据),2、链接(校验数据准确性,准备给静态变量初始化空间,解析符合引用改直接引用),3、初始化:激活静态变量的数据 1、Class.forname会调用Class.forname的方法,参数第二个会是true,就是必须初始化,目标的static模块中也已经被初始化了 2、ClassLoader.loadClass第二个参数则是false,说明静态块不会被初始化

    七、string、stringbuilder、stringbuffer区别

    1、sting是final修饰的不可变的变量 2、stringbuilder(线程不安全的),tostring方法返回的新的对象 3、stringbuffer(线程安全,多了个同步锁)tostring是通过对象缓存,减少元素复制的开销

    八、异常的结构,运行时异常和非运行时异常,各举个例子

    1、异常(excerption,可避免)和错误(error,不可避免) 2、异常有分为(checkexception,classNotFoundException,NoSuchMetodException,IOException)和(runningexception,nNUllpointerException,INdexOuntOfBoundExceptiom)

    九、 session和cookie的区别

    1、存储数据量方面:session能存储任意java对象,cookie只能存储String类型对象 2、cookie在客户端,session在服务端

    十、 垃圾回收机制

    1、引用计数器算法:引用加一,失效减一,当为零就是垃圾 2、可达性分析算法:通过GCROOT为对象一直往下查询,这种路径就较引用链,没有引用链连接为垃圾 3、标记-清除算法,复制算法,标记-整理算法,分代收集

    十一、 垃圾收集器

    1、Serial收集器,ParNew收集器,Parallel Scavenge收集器(控制吞吐量)2、Old Serial, Parallel Old,Cms

    十二、 sql优化

    1、避免对null进行判断 2、避免用or连接条件 3、in和not in也要少用 4、不用在where后面进行表达式操作 5、尽量使用数字型字段,不要用字符型设置只有数字的字段 6、exists可以代替in 7、不用写一些没有意义的查询 8、不用都要*,用具体字段

    十三、 线程按顺序打印abcabc

    public class ABC{ public static class ThreadPrinter implements Runnable{ private String name; private Object prev; private Object self; private ThreadPrinter(String name,Object prev,Object self){ this.name=name; this.prev=prev; this.self=self;

    } @Override public void run(){ int count=10; while(count>0){ synchronized(prev){ synchronized(self){ System.out.print(name); count–; self.notifyAll(); } try{ prev.wait(); }catch(InterruptedException e){ e.printStackTrace(); } } } } } public static void main(String[] args)throws Exception{ Object a=new Object(); Object b=new Object(); Object c=new Object(); ThreadPrinter pa=new ThreadPrinter(“A”,c,a); ThreadPrinter pb=new ThreadPrinter(“B”,a,b); ThreadPrinter pc=new ThreadPrinter(“C”,b,c); new Thread(pa).start(); Thread.sleep(10); new Thread(pb).start(); Thread.sleep(10); new Thread(pc).start(); Thread.sleep(10); } }

    十四、接口与抽象类的区别

    1、都不可以直接实例化 2、抽象类要被子类继承,接口要被类实现; 3、接口定义的变量只能是公告的静态变量,抽象类的变量是普通变量 4、抽象方法不能是静态或者私有 5、接口只能做方法声明,继承可以做方法声明,也可以方法实现。 6、接口多继承接口,类只能单根继承

    十五、单例模式

    public class Singletion{ private volatile static singletion; private Singletion(){}; public static Singletion getSingletion(){ if(singletionnull){ synchronized(Singletion.class){ if(singletionnull){ singletion=new Singletion(); } } } return singletion; } }

    Processed: 0.017, SQL: 9