java面试的知识点

Java基础

1 .String类为什么是final的?

主要是为了“效率” 和 “安全性” 的缘故。若 String允许被继承, 由于它的高度被使用率, 可能会降低程序的性能,所以String被定义
成final.
效率:String a = "aaa"; String b = "aaa";变量a,b指向同一个内存地址,在大量使用类似的字符串时能提高效率。
安全:同一个字符串实例可以被多个线程共享。String不可变便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。

2 .String a= “abc” String b = “abc” String c = new String(“abc”) String d = “ab” + “c” .他们之间用 == 比较的结果?

a==b true
a==c false
a==d true
b==c false
b==d true
c==d false

如果final String a= "ab";String b = "abc"; String d = a + "c";则:b==d true  去掉fianl b==d false
如果final String a= run()(run是一个函数return "ab");String b = "abc"; String d = a + "c";则:b==d false

注:String a = new String("abc")涉及到几个对象? 2String a = new String("abc")代码执行过程中创建了几个对象? 1个 a
   String a = new String("abc")类加载中创建了几个对象? 1个 abc

3.重载与重写的区别

重载的规则:
   1、在使用重载时只能通过相同的方法名、不同的参数形式实现。不同的参数类型可以是不同的参数类型,不同的参数个数,不同的参数顺序
(参数类型必须不一样);
   2、不能通过访问权限、返回类型、抛出的异常进行重载;
   3、方法的异常类型和数目不会对重载造成影响;

重写的规则:
   1、重写方法的参数列表必须完全与被重写的方法的相同,否则不能称其为重写而是重载.
   2、重写方法的访问修饰符一定要大于被重写方法的访问修饰符(public>protected>default>private)。
   3、重写的方法的返回值必须和被重写的方法的返回一致;
   4、重写的方法所抛出的异常必须和被重写方法的所抛出的异常一致,或者是其子类;
   5、被重写的方法不能为private,否则在其子类中只是新定义了一个方法,并没s有对其进行重写。
   6、静态方法不能被重写为非静态的方法(会编译出错)。

4 .抽象类和接口的区别

   抽象类特点:抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认
为public;抽象类不能用来创建对象;如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现
父类的抽象方法,则必须将子类也定义为为abstract类。

   接口特点:接口中的变量会被隐式地指定为public static final变量(并且只能是public static final变量,用private修饰会报编译错
误),而方法会被隐式地指定为public abstract方法且只能是public abstract方法(用其他关键字,比如privateprotectedstaticfinal等修饰会报编译错误),并且接口中所有的方法不能有
具体的实现

   区别:
   1.抽象类里可以有构造方法,而接口内不能有构造方法。
   2.抽象类中可以有普通成员变量,而接口中不能有普通成员变量。
   3.抽象类中可以包含非抽象的普通方法,而接口中所有的方法必须是抽象的,不能有非抽象的普通方法。
   4.抽象类中的抽象方法的访问类型可以是publicprotected和默认类型,但接口中的抽象方法只能是public类型的,并且默认即为
public abstract类型。
   5.抽象类中可以包含静态方法,接口内不能包含静态方法。
   6.抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static
类型,并且默认为public static类型。
   7.一个类可以实现多个接口,但只能继承一个抽象类。

5.hashtable和hashmap的区别

   1.继承不同,HaspMap继承AbstractMap,Hashtable继承Dictionary,但都实现Map接口
   public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
   public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable 

   2.Hashtable 中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要
使用HashMap的话就要自己增加同步处理了。HashMap可以使用Map<Object, Object> map1 = Collections.synchronizedMap(new HashMap<>())
达到同步效果。

   3.Hashtable中,keyvalue都不允许出现null值;在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为
null。当get()方法返回null值时,即可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法
来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。

   4.两个遍历方式的内部实现上不同。HashtableHashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。
   HashMap遍历的两种方法:
   AHashMap<String,String> map = new HashMap<>();
         Iterator<Entry<String, String>> es = map.entrySet().iterator();
         while(es.hasNext()){
             Entry<String,String> en = es.next();
             System.out.println(en.getKey()+"   "+en.getValue());
         }

   B:    HashMap<String,String> map = new HashMap<>();
         Iterator<String> set = map.keySet().iterator();
         while(set.hasNext()){
             String s = set.next();
             System.out.println(s+"   "+map.get(s));
         }

   5 .哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

   6 .Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是
old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。 

6.几个Java集合类


这里写图片描述

   1.HashSet:里面不能存放重复元素,而且采用散列的存储方法,所以没有顺序。
   2.HashMap(Hashtable)
   3.ArrayList:ArrayList是List的子类,它和HashSet想法,允许存放重复元素,因此有序。集合中元素被访问的顺序取决于集合的类型。如
果对ArrayList进行访问,迭代器将从索引0开始,每迭代一次,索引值加14.LinkedList:一种可以在任何位置进行高效地插入和删除操作的有序序列。允许null元素
   5.Stack:Stack继承自Vector,实现一个后进先出的堆栈。
   6.vetcor:Vector非常类似ArrayList,但是Vector是同步的。

比较:
   1.ArrayList与LinkedList:继承不同LinkedList继承AbstractSequentialList,ArrayList继承AbstractList;ArrayList基于动态数组数据
结构,LinkedList基于链表;对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
   2.ArrayList与Vector:都实现了List接口,Vector是线程安全的,ArrayList是非线程安全的,相对来说ArrayList的效率较高;两者的扩容
方式不同,ArrayList是默认扩充为原来的1.5倍,Vector是默认扩容为原来的2倍。

7.string、stringbuilder、stringbuffer区别

String:是对象不是原始类型.为不可变对象,一旦被创建,就不能修改它的值.对于已经存在的String对象的修改都是重新创建一个新的对象,
然后把新的值保存进去.String 是final类,即不能被继承.

StringBuffer:StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。所以在实际使用时,如果经常需要对一
个字符串进行修改,例如插入、删除等操作,使用StringBuffer要更加适合一些。是线程安全的

StringBulider:与StringBuffer大致相同,只是不是线程安全的,效率要高于StringBuffer

选择:
如果要操作少量的数据使用String;单线程操作字符串缓冲区下操作大量数据使用StringBuilder;多线程操作字符串缓冲区下操作大量数据
使用StringBuffer

8 .java异常

异常类结构层次图:

异常类结构层次图

所有的异常类都有一个共同的祖先类Throwable,包含两个子类Exception(异常)和Error(错误)。
Exception:是程序本身可以处理的异常。
Error:是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误表示代码运行时 JVM(Java 虚拟机)出现的问题。

java异常(包括RuntimeException和Error)可分为检查异常与非检查异常。
检查异常:正确的程序在运行中,很容易出现的、情理可容的异常状况。可查异常虽然是异常状况,但在一定程度上它的发生是可以预计的,而
且一旦发生这种异常状况,就必须采取某种方式进行处理。包括除RuntimeException及其子类的其他异常。
非检查异常:包括运行时异常(RuntimeException与其子类)和错误(Error)。

Exception分为运行时异常和非运行时异常。
运行时异常:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,
这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。
非运行时异常:是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,
程序就不能编译通过。

注:对于有多个catch子句的异常程序而言,应该尽量将捕获底层异常类的catch子句放在前面,同时尽量将捕获相对高层的异常类的catch子句
放在后面。否则,捕获底层异常类的catch子句将可能会被屏蔽。

9 .Object类的方法

equals():指示其他某个对象是否与此对象“相等”。
toString():返回该对象的字符串表示。
wait():  在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
notify():唤醒在此对象监视器上等待的单个线程。
notifyAll():唤醒在此对象监视器上等待的所有线程。
hashCode():返回该对象的哈希码值。
clone():创建并返回此对象的一个副本
getClass():返回此 Object 的运行时类。
finalise():当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

10 .hash表、hashCode()与equals()的重写

   1.hash算法(hash表的构造方法)
      a.直接定制法
      b.除留余数发
      c.折叠法
      d.平方取中法

   2.解决hash冲突的方法
      a.开放定址法
         关键字{231214235},表长14,hash函数key%11,则表中存储如下:
         地  址     0     1     2     3      4     5    6   7   8    9  10   11   12    13
       关键字           23    12    14     2     3    5
       
      b.链地址法
         用数组加链表存储

   3.重写equals()后必须重写hashCode()的原因
      hashCode相同,equals()可同可不同,hashCode()不同,equals()一定不同;反之,equals()相同,hashCode()一定相同,但equals()
不同,hashCode()可同可不同。如定义两个对象的属性值一样即相同时,重写equals()方法实现上述条件,但两个对象的存储地址不同,
hashCode()不重写,导致两个对象的hashCode()不同,则违背了equals()相同,hashCode()一定相同的规则。

    注:/*
    1.在程序执行期间,只要equals方法的比较操作用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法必须始终如一地
返回同一个整数。
    2.如果两个对象根据equals方法比较是相等的,那么调用两个对象的hashCode方法必须返回相同的整数结果。
    3.如果两个对象根据equals方法比较是不等的,则hashCode方法不一定得返回不同的整数。
        */


   4.重写(不重写hashCode结果为null)
    public class YuanMa {
    private String name;
    private String age;

    public YuanMa(String name,String age){
        this.age = age;
        this.name = name;
    }

    public static void main(String[] args) {  
        YuanMa yuan = new YuanMa("kkk", "12");
        System.out.println(yuan.hashCode());
        HashMap<YuanMa,String> map = new HashMap<YuanMa, String>();
        map.put(yuan, "1");
        System.out.println(map.get(yuan));
    }

    @Override
    public int hashCode() {
        return this.name.hashCode()+this.age.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if(this.getClass()!=obj.getClass()){
            return false;
        }

        if(this == obj){
            return true;
        }
        YuanMa yuan = (YuanMa)obj;
        return this.name.equals(yuan.name)&&this.age == yuan.age;
    }
}

11 .拆箱与装箱

   对于Byte,Short,Character,Integer,Long来说通过ValueOf方法创建对象时,如果数值在[-128,127]之间(Character是小于127),便返回
指向已经存在的对象的引用;否则创建一个新的对象。
   对于Boolean来说:
   public static Boolean valueOf(boolean b) {
       return (b ? TRUE : FALSE);
   }
   对于Double与Float来说:
   public static Double valueOf(double d) {
       return new Double(d);
   }
   public static Float valueOf(float f) {
       return new Float(f);
   }

12 .hashmap的实现原理,知识点

HashMap的内部实现机制,Hash是怎样实现的,什么时候ReHash:
http://www.cnblogs.com/schbook/p/3585159.html?utm_source=tuicool&utm_medium=referral
HashMap实现原理分析:
http://blog.csdn.net/vking_wang/article/details/14166593
HashMap的工作原理:
http://blog.csdn.net/zheng0518/article/details/45100025

13 .IO
      IO常见类:
        a.字符流:




        b.字节流:


InputStream、OutputStream、Writer、Reader都是抽象类。

递归读取文件加下的文件:
   public void startFile(String dirpath){
        File[] file = new File(dirpath).listFiles();
        for(File f : file){
            if(f.exists()&&f.isFile()){
                System.out.println(f.getName());
            }else{
                if(f.isDirectory()){
                    startFile(f.getAbsolutePath());
                }else{
                    System.out.println("读取错误!");
                }
            }
        }
    }

IO详解:
   http://www.cnblogs.com/dolphin0520/p/3791327.html

14 .线程池

三种常用的线程池:
   newCachedThreadPool:较适合没有固定大小并且比较快速就能完成的小任务,缓冲池容量大小为Integer.MAX_VALUE,线程空闲60s就自动销
                        毁,使用的是SynchronousQueue。
   newFixedThreadPool:自定义线程池大小,与线程池最大线程数数值相同,使用的LinkedBlockingQueue。
   newSingleThreadExecutor:单线程化的线程池,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行,使用的LinkedBlockingQueue。

ThreadPoolExecutor类(核心类)的构造函数(其他三个都调用了这个来初始化):
   public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
        BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);

线程池运行流程:
   1.当线程池中线程数(count)< corePoolSize时,创建线程放入池中运行处理任务;
   2.count >= corePoolSize时,将任务存放入缓存队列BlockingQueue<Runnable> workQueue中,有空闲线程时从队列中取出任务并处理;
   3.当缓存队列放置满时,扩充线程池处理任务直到达到maximumPoolSize的大小;
   4.count >= maximumPoolSize时,会调用 RejectedExecutionHandler handler来拒绝处理;
   5.count >= corePoolSize时,多余的线程会保持keepAliveTime的时间,如果没有任务来处理时,就销毁线程。

参考:
   http://www.cnblogs.com/dolphin0520/p/3932921.html
   http://blog.csdn.net/cutesource/article/details/6061229
   http://blog.csdn.net/xieyuooo/article/details/8718741

15 .在一个主线程中,要求有大量(很多很多)子线程执行完之后,主线程才执行完成:

单线程下:
   1.join()
   2.Future.get()
   3.阻塞队列BlockingQueue
多线程:
   1.join()
   2.Future.get()
   3.阻塞队列BlockingQueue
   4.CountDownLanch(推荐)

参考:
   http://www.jiacheo.org/blog/262


阻塞队列:
   支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等
待队列可用,常用于生产者和消费者的场景

常见阻塞队列:
   ArrayBlockingQueue:基于数组实现的一个阻塞队列,按照先进先出(FIFO)的原则对元素进行排序,创建ArrayBlockingQueue对象时必须
制定容量大小。有界的
   LinkedBlockingQueue:基于链表实现的一个阻塞队列,默认和最大长度为Integer.MAX_VALUE,按照先进先出(FIFO)的原则对元素进行排
序。有界的
   PriorityBlockingQueue :支持优先级排序的无界阻塞队列,按照元素的优先级对元素进行排序,按照优先级顺序出队,每次出队的元素都
是优先级最高的元素。无界的

put与offer,take与poll的区别:
   put方法用来向队尾存入元素,如果满则等待(阻塞),直至队列可用,offer也是用来向队尾存入元素,如果满则阻塞等待一定时间,时
间到期还未存入成功,则返回一个boolean值false否则返回truetake方法用来从队首取元素,如果空则等待(阻塞),直至队列中有元素,poll方法用来从队首取元素,如果空则等待一定的时间,当时间期限
达到时,如果取到,则返回null;否则返回取得的元素

参考:
   http://ifeve.com/java-blocking-queue/
   http://www.cnblogs.com/dolphin0520/p/3932906.html

计算机网络

1.http与https的区别,http包含的方法

https工作原理:
1.客户端发起HTTPS请求
2.服务端的配置(证书,即公匙与私匙)
3.传送证书(即公匙)
4.客户端解析证书(客户端TSL完成检验,用公匙对随机生成的值加密)
5.传送加密信息(即随机值,让服务器得到随机值)
6.服务段解密信息(解密得到随机值,对称加密)
7.传输加密后的信息(向客户端)
8.客户端解密信息(获取解密后的内容)


http包含的方法:
1.post:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立
或已有资源的修改。
2.get:请求指定的页面信息,并返回实体主体。
3.head:类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
4.put:从客户端向服务器传送的数据取代指定的文档的内容。
5.delete:请求服务器删除指定的页面。
6.connect:HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
7.option:允许客户端查看服务器的性能。
8.trace:回显服务器收到的请求,主要用于测试或诊断。

2.三次握手


这里写图片描述

第一次握手:客户端A发送同步位SYN=1,以及选择初始序列号seq=x,同时进入SYN-SEND状态;
第二次握手:服务端B收到客户端的请求保温后,发送报文SYN=1,ACK=1,确认序列号ack=x+1,以及选择自己的初始序列号seq=y,同时进入SYN-RECV状态。
第三次握手:客户端接收到服务端的确认后,发送报文ACK=1,序列号seq=x+1,确认序列号ack=y+1,客户端与服务器进入ESTAB-LISHEAD的状
态,完成三次握手。

3.四次挥手


这里写图片描述

注:第一趟连接是FIN=1,seq=u

第一次挥手:客户端A发送关闭tcp连接请求报文,Fin=1,序列号seq=u(u为前面已发送的数据的最后一个字节的序列号加1);
第二次挥手:服务端接收到客户端的请求保温后,并返回一个ACK,确认序列号为ack=u+1,自己的序列号ack=v(v为前面服务端B已发送的数据的最后一个字节加1),服务端B进入CLOSED-WAIT状态;
第三次挥手:客户端A接收到服务端B的确认消息后,断开与服务器B的连接,但服务器B依旧与客户端A相连,服务器B发送的消息客户端A依然能接受,服务器B发送报文ACK=1,Fin=1,自己的序列号seq=w(半关闭状态下可能又发送了一些数据),确认序列号ack=u+1。
第四次挥手:客户端A接收到报文后,发送确认报文ACK=1,自己的序列号seq=u+1,确认序列号ack=w+1,客户端A进入TIME-WAIT状态,经过两个最大报文生存时间后关闭连接。

TIME-WAIT与CLOSE-WAIT的含义:
CLOSE-WAIT:发起TCP连接关闭的一方称为client,被动关闭的一方称为server。被动关闭的server收到FIN后,但未发出ACK的TCP状态是

CLOSE_WAIT。
TIME-WAIT:发起socket主动关闭的一方,socket将进入TIME_WAIT状态。TIME_WAIT状态将持续2个MSL(Max Segment Lifetime),在Windows下默认
为4分钟,即240秒.

TIME-WAIT持续2个最大报文生存时间的原因:
1.保证TCP协议的全双工连接能够可靠关闭(确认服务端接收到报文FIN)
2.保证这次连接的重复数据段从网络中消失(避免新老连接使用同一个端口造成数据的混淆)

4.tcp与UDP的区别

1.基于连接与无连接;(tcp是面向连接的协议,udp是无连接的协议)
2.对系统资源的要求(TCP较多,UDP少);
3.UDP程序结构较简单;
4.流模式与数据报模式 ;
5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。

详解:http://www.cnblogs.com/bizhu/archive/2012/05/12/2497493.html

5.post与get的区别

1.原理不同:get方法的HTTP请求不会修改服务器信息,是安全方法;post方法可能会修改服务器上的资源的请求,是不安全的方法。
2.请求方式不同:get请求的数据会暴露在地址栏中,而post请求则不会,将请求放在http包的包体中。
3.安全性不同:post的安全性要比get的安全性高

Mysql数据库

1.索引的分类

1.普通索引
2.唯一索引
3.主键索引
4.组合索引

2.数据库事物特性

1.原子性:事物中的操作不可拆分,要么全部执行要么全部不执行。
2.隔离性:并发的事物相互隔离,不能相互干扰。
3.一致性:事物的执行不能破坏数据库的一致性,事务执行后,数据库应该从一个一致性的转台转换为另一个一致性的状态。
4.持久性:事物一旦提交,对数据的状态变更应该被永久保存。

3.数据库的隔离级别(Mysql)

1.脏读(提交未读):当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会
造成两个事务得到的数据不一致
2.不可重复读(提交已读):不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间
隔,被另一个事务修改并提交了。
3.幻读(可重复读):不可重复读保证了同一个事务里,查询的结果都是事务开始时的状态(一致性)。但是,如果另一个事务同时提交了新数
据,本事务再更新时,就会发现了这些新数据,貌似之前读到的数据是幻觉,这就是幻读。
4.串行化:所有事务只能一个接一个串行执行,不能并发。


串行化级别最高,执行效率最低,对并发性的影响最高,Mysql中默认隔离级别为可重复读(Repeatable read),各个级别解决的问题:
1.脏读:级别最低,什么都无法保证
2.不可重复读:可避免脏读
3.可重复读:可避免脏读,不可重复读
4.串行化:可避免脏读,不可重复读,可重复读

4.关系型数据库与非关系型(nosql)数据库的区别

1.nosql将数据存储于缓存之中,关系型数据库将数据存储在硬盘中,查询速度nosql较快。
2.nosql的存储格式是key,value形式、文档形式、图片形式等等,关系型数据库只支持基础类型。
3.关系型数据库具有固定的表结构,扩展性差。
4.nosql不提供关系数据库对事务的处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值