JAVA基础面试题

1、说说String、StringBuffer、StringBuilder的区别“
答:
       String 字符串常量
  StringBuffer 字符串变量(线程安全)
  StringBuilder 字符串变量(非线程安全)
       执行速度方面的比较:StringBuilder >  StringBuffer  >  String
       String是不可变的对象,每次对String对象操作时相当于创建了新的String对象,然后将指针指向新的 String 对象,原来的对象就会变为垃圾被GC回收掉,执行效率低。
基本原则:如果要操作少量的数据,用String ;单线程操作大量数据,用StringBuilder ;多线程操作大量数据,用StringBuffer。


2、看过哪些源码?Object类里有哪些方法?hashcode、equals和==之间的区别“

答:

Object类是一个特殊的类,是所有类的父类,如果一个类没有用extends明确指出继承于某个类,那么它默认继承Object类。这里主要总结Object类中的三个常用方法:toString()、equals()、hashCode()。

(1)取得对象信息的方法:toString()

该方法在打印对象时被调用,将对象信息变为字符串返回,默认输出对象地址。

(2)对象相等判断方法:equals()
该方法用于比较对象是否相等,而且此方法必须被重写,默认比较的是地址。

(3)对象签名:hashCode()

该方法用来返回其所在对象的物理地址(哈希码值),常会和equals方法同时重写,确保相等的两个对象拥有相等的.hashCode。

(4)wait()在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。   

(5)notify()唤醒在此对象监视器上等待的单个线程。notifyAll()唤醒在此对象监视器上等待的所有线程。


①如果是基本类型比较,那么只能用==来比较,不能用equals 

②对于基本类型的包装类型,比如Boolean、Character、Byte、Shot、Integer、Long、Float、Double等的引用变量,==是比较地址的,而equals是比较内容的。


3、classloader加载机制,是否可以自己定义一个java.lang.String类,为什么?”

JAVA自带3类加载器:根加载器(Bootstrap)扩展类加载器(Extension)应用类加载器(AppClassloader)

当这三者中的某个ClassLoader要加载一个类时,会先委托它的父类加载器尝试加载,一直往上,如果最顶级的父类加载器没有找到该类,那么委托者则亲自到特定的地方加载,如果没找到,那么就抛出异常ClassNotFoundException.



答案是否定的。我们不能实现。为什么呢?我看很多网上解释是说双亲委托机制解决这个问题,其实不是非常的准确。因为双亲委托机制是可以打破的,你完全可以自己写一个classLoader来加载自己写的java.lang.String类,但是你会发现也不会加载成功,具体就是因为针对java.*开头的类,jvm的实现中已经保证了必须由bootstrp来加载。


4、你知道哪几种创建线程类的方法(其实有好多,框架答出来肯定加分)“
1)继承Thread类创建线程
2)实现Runnable接口创建线程
3)使用Callable和Future创建线程

5、数组与链表的相同点和不同点,为什么?“

答:

      都是数据结构的一种,可以用来存储数据。

        数组是申请的一块连续的内存空间,并且是在编译阶段就要确定空间大小的,同时在运行阶段是不允许改变的,所以它不能够随着需要的改变而增加或减少空间大小,所以当数据量大的时候,有可能超出了已申请好的数组上限,产生数据越界,或者是数据量很小,对于没有使用的数组空间,造成内存浪费。
       链表则是动态申请的内存空间,并不像数组一样需要事先申请好大小,链表是现用现申请就OK,根据需求动态的申请或删除内存空间,对于的是增加或删除数据,所以比数组要灵活。
再从物理存储即内存分配上分析,
       数组是连续的内存,对于访问数据,可以通过下标直接读取,时间复杂度为O(1),而添加删除数据就比较麻烦,需要移动操作数所在位置后的所有数据,时间复杂度为O(N)。
       链表是物理上非连续的内存空间,对于访问数据,需要从头遍历整个链表直到找到要访问的数据,没有数组有效,但是在添加和删除数据方面,只需要知道操作位置的指针,可以很方便地实现增删,较数组比较灵活有效率。
      所以综合以上,对于快速访问数据,不经常有添加删除操作的时候选择数组实现,而对于经常添加删除数据,对于访问没有很高要求的时候选择链表。


6、简述一下List、Set、Map的区别 

答:

List和Set继承自Collection接口。

List特点:元素有放入顺序,元素可重复 
Map特点:元素按键值对存储,无放入顺序 
Set特点:元素无放入顺序,元素不可重复(注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的) 
List接口有三个实现类:LinkedList,ArrayList,Vector 
LinkedList:底层基于链表实现,链表内存是散乱的,每一个元素存储本身内存地址的同时还存储下一个元素的地址。链表增删快,查找慢 
ArrayList和Vector的区别:ArrayList是非线程安全的,效率高;Vector是基于线程安全的,效率低 
Set接口有两个实现类:HashSet(底层由HashMap实现),LinkedHashSet 
SortedSet接口有一个实现类:TreeSet(底层由平衡二叉树实现) 
Query接口有一个实现类:LinkList 
Map接口有三个实现类:HashMap,HashTable,LinkeHashMap 
 HashMap非线程安全,高效,支持null;HashTable线程安全,低效,不支持null 
SortedMap有一个实现类:TreeMap 


7、HashMap 、Hashtable和 HashSet的区别?哪个key可以为空?HashMap的内部实现机制,Hash是怎样实现的,什么时候ReHash

答:

1)Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类。HashSet是Set接口的实现类,里面的元素都是无序的.

2)HashSet以对象作为元素,而HashMap以(key-value)的一组对象作为元素,且HashSet拒绝接受重复的对象。

3)HashTable不允许null值操作(key 和value均不能为null),HashMap中key可以为null。可以有一个或多个键所对应的值为null。当get()方法返回null值时,可能是 HashMap中没有该键,也可能使该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。

4)与HashMap的主要的不同是HashTable是同步的(synchronize);在多线程访问时,不需要为他的方法实现同步,而HashMap必须为之提供外同步。

5)哈希值的计算方法不同,Hashtable直接使用的是对象的hashCode,而HashMap则是在对象的hashCode的基础上还进行了一些变化。


8、说出ArrayList,Vector, LinkedList的存储性能和特性“

答:

ArrayList 和Vector他们底层的实现都是一样的,都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢。

Vector中的方法由于添加了synchronized修饰,因此Vector是线程安全的容器,但性能上较ArrayList差,因此已经是Java中的遗留容器。

LinkedList使用双向链表实现存储(将内存中零散的内存单元通过附加的引用关联起来,形成一个可以按序号索引的线性结构,这种链式存储方式与数组的连续存储方式相比,内存的利用率更高),按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

      

9、对象序列化机制    Java 的序列化做什么用的 序列化id会出现哪些问题?”

答:

对象序列化的目标:将对象保存到磁盘中,或允许在网络中直接传输对象。
对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久的保存在磁盘上,通过网络将这种二进制流传输到另一个网络节点。其他程序一旦获得了这种二进制流,都可以将这种二进制流恢复成原来的Java对象。


10、TCP、UDP,握手协议?

答:

TCP提供的是面向连接、可靠的数据流传输。当客户端和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能顺序地从一端传到另一端。

UDP提供的是非面向连接的、不可靠的数据流传输。,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。UDP在传输数据前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,不保证数据按顺序传递,故而传输速度很快。

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。完成三次握手,客户端与服务器开始传送数据。

11、JAVA中的Synchronize是什么?

12、int和Integer的区别?

1)Integer是int的包装类,int则是java的一种基本数据类型 

2)Integer变量必须实例化后才能使用,而int变量不需要 
3)Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值 

4)Integer的默认值是null,int的默认值是0

13、JAVA的三大特性。

封装、继承、多态。

1)封装: 
概念:隐藏对象的成员变量和方法,只对外提供公共的访问方式 
优点:将变化隔离、便于使用、提高复用性、提高安全性 
2)继承: 
优点:提高代码复用性,同时继承是多态的前提 
注意:子类所有的构造函数都会默认访问父类中的空参数的构造函数,默认第一行有super(),若无空参数构造函数,需要在子类中指定
3)多态:顾名思义同种引用不同的实现 
环境:父类或接口的引用变量可以指向子类或具体实现类的实例对象 
优点:提高程序的扩展性 

弊端:父类引用指向子类对象时,虽然提高了扩展性,但只能访问父类中具备的方法,不可以方法问子类中的方法。访问局限性。

14、进程与线程的区别。

进程是资源分配的最小单位,线程是资源调度的最小单位。进程管理被分配的资源中央处理器,有内存,打开的文件,映射的网络端口等等,线程只负责如何利用CPU去运行代码,不管资源的分配,一个进程的几个线程可以共享这些资源。

15、

1、常见的稳定的排序算法有:

(1)直接插入排序,(2)冒泡排序,(3)归并排序,(4)基数排序;
2、常见的不稳定的排序算法有:
(1)简单选择排序,(2)希尔排序,(3)快速排序,(4)堆排序。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值