MO_or查漏补缺之Java基础篇

java_se.png

1. == 和 equals() 的区别是什么?

== 的做用:
  • 基本数据类型:判断值是否相等
  • 引用数据类型:判断引用地址是否相等,String类型要单独讨论
equals() 的做用:
  • 在Object中和 == 同样是判断引用地址是否相等

equals object.png

  • 在String中是判断其字符串值是否相等

equals string.png

内存模型

建立三个String对象,以下图所示
String内存模型.pnghtml

  1. str1经过new会在堆建立一个字符串对象
  2. str2直接建立也会在堆建立一个字符串对象
  3. str3直接建立,但并不会在堆建立一个字符串对象,而是直接指向str2在堆的字符串对象。由于没有经过new建立的String对象,会先在字符串池中去找是否已有值相等的String对象,如有则将栈指针指向堆中已有的String对象,若没有才会在堆中建立新的String对象

2. 两个对象的hashCode()相同,则equals()必定为true,对吗?为何?

hashCode():是根据内存地址按hash算法得出的一个正数java

若equals()为true,hashCode()也为true
若hashCode()为true,equals()不必定为true,由于可能存在hash冲突(几率较低)算法

那么hashCode在实际应用中有什么做用呢?

以HashSet为例确保添加的元素是不重复的:编程

  • 重写hashCode()与equals()方法
  • 先判断hash值是否相等,若不等,则元素不重复
  • 若hash值相等,再判断equlas()值是否相等,如值不等则元素不重复
那么为何要使用hashCode呢?

若是在存储的时候逐个equals()比较,效率较低,哈希算法提升了去重复的效率,下降了使用equals()方法的次数设计模式

3. String类的经常使用方法?

判断功能
boolean equals(Object obj)
boolean equalsIgnoreCase(String str)
boolean isEmpty()
boolean contains(String str)
boolean startsWith(String str)
boolean endsWith(String str)
获取功能
int length()
char charAt(int index)
int indexOf(int ch)
int indexOf(String str)
int indexOf(int ch,int fromIndex)
int indexOf(String str,int fromIndex)
String substring(int start)
String substring(int start,int end)
转换功能
byte[] getBytes()
char[] toCharArray()
static String valueOf(char[] chs)
static String valueOf(int i)
String toLowerCase()
String toUpperCase()
String concat(String str)
其它功能
  • 替换功能
String replace(char old,char new)
String replace(String old,String new)
  • 去除字符串两空格
String trim()
  • 按字典顺序比较两个字符串
int compareTo(String str)
int compareToIgnoreCase(String str)

4. final的做用?

修饰类

表示该类不能被继承,请谨慎使用,若非该类已十分明确不会被继承或出于安全方面考虑,并不建议设计为final类安全

修饰方法

表示该方法不能被子类重写(覆盖),但可以被重载,即在子类中能够建立多个与final方法方法名相同,但参数不一样的方法
注意若父类中final方法的访问修饰符为private,那么子类是不会直接继承父类的final方法的,那么这时在子类中建立相同的方法名与参数是不会有final冲突的服务器

修饰变量

final修饰变量是较为常见的,也是这里须要重点学习的部分
final修饰变量表示该变量仅能被赋值一次,赋值后值再也不改变架构

  • 当为基本数据类型时,表示其初始化后就不能再被更改
  • 当为引用数据类型时,表示其初始化后就不能再指向其它对象,但被指向的对象是能够更改的,其本质是同样的即保证栈中的地址是没法更改的
  • 当为成员变量时,必需要显示初始化,即声明变量时就初始化,或声明变量时未初始化,但在该成员变量的类中全部构造方法(无参、有参)中赋初值
  • 当为参数时,表示该参数只读,只能读取使用,但不能被更改

5. IO流分几种?

按数据类型分:
  • 字节流:InputStream、OutputStream,任何数据类型都能支持
  • 字符流:Reader、Writer,非纯文本格式数据可能会致使文件格式破坏
按数据流向分:
  • 输入流:读取文件数据
  • 输出流:将数据写入文件中
按功能分:
  • 字节流:FileInputStream、FileOutputStream,直接和源数据进行输入输出
  • 处理流:在字节流的基础上进行了功能的扩展或增强,又分为如下两种并发

    • 转换流:InputStreamReader、OutputStreamWriter,字节流转字符流,字符流转字节流
    • 缓冲流:BufferedInputStream,BufferedOutputStream   BufferedReader,BufferedReader,可对节点流经行包装,使读写更快

扩展:关于缓冲流,这里涉及到了设计模式中的装饰者模式,其做用即基于已有功能基础上,提供加强的功能异步

其实现思路以下:

  1. 子类继承父类
  2. 子类中声明一个父类类型的成员变量
  3. 经过子类中的带参构造方法接收外部传递的父类类型参数,并赋值给子类的父类成员类型成员变量
  4. 在实现功能时,调用外部传递的父类类型参数实现原有功能,本身实现加强功能

6. BIO、NIO、AIO有什么区别?

先结合生活场景简单介绍下同步、异步、阻塞、非阻塞,以银行取款为例:

  • 同步:本身到银行取款
  • 异步:委托别人(将各类须要的资料给别人)帮本身到银行取款,期间本身能够作别的,而后等别人取好给本身
  • 阻塞:在ATM排队取款,只能站着等
  • 非阻塞:在银行取个号,坐椅子上玩本身的,等广播叫号到本身了就去,没到号不能插队,也能够不断问大堂经理到本身没,若是说没到就不能去
BIO(Blocking I/O)

同步且阻塞,服务器实现模式为一个链接一个线程,即客户端有链接请求时服务器端就须要启动一个线程进行处理,若是这个链接不作任何事情会形成没必要要的线程开销,固然能够经过线程池机制改善

BIO方式适用于链接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4之前的惟一选择,但程序直观简单易理解

NIO(Non-Blocking I/O)

同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的链接请求都会注册到多路复用器上,多路复用器轮询到链接有I/O请求时才启动一个线程进行处理

NIO方式适用于链接数目多且链接比较短(轻操做)的架构,好比聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持

AIO(Asynchronous I/O)

异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理

AIO方式使用于链接数目多且链接比较长(重操做)的架构,好比相册服务器,充分调用OS参与并发操做,编程比较复杂,JDK7开始支持

扩展:Netty为何使用NIO而不是AIO?

Netty不看重Windows上的使用,在Linux系统上,AIO的底层实现仍使用EPOLL,没有很好实现AIO,所以在性能上没有明显的优点,并且被JDK封装了一层不容易深度优化

参考:为何Netty使用NIO而不是AIO?

7. Files的经常使用方法?

Files.read()    读取文件
Files.write()   写入文件
Files.exists()  检测文件路径是否存在
Files.createFile()  建立文件
Files.createDirectory() 建立文件夹
Files.delete()  删除文件或者目录
Files.copy()    复制文件
Files.move()    移动文件
Files.size()    查看文件个数

8. abstract的做用?

抽象类
  1. public abstract class ClassName{}
  2. 抽象类不能被实例化,只有非抽象子类能够被实例化
  3. 抽象类能够有本身的构造方法
  4. 抽象类不一样于接口,接口的接口方法是不容许实现的,但抽象类中普通方法能够被实现
  5. 抽象类不能用final关键字来形容,由于final修饰类表示该类不能被继承,但抽象类须要子类来实现抽象方法
  6. 抽象类中能够没有抽象方法,但只要有一个抽象方法,就必定是抽象类
  7. 继承了抽象类的子类必须所有重写抽象类的方法,只有子类也为抽象类时才能够不用所有重写
  8. 一个类只能单继承抽象类,但能够实现多个接口类
抽象方法
  1. 抽象方法相似与接口中的方法,是不容许在抽象类中实现的,只能由子类来实现
  2. 抽象方法的访问修饰符不能用private,由于private表示只有本类能够调用,而抽象方法须要子类来实现
  3. 抽象方法不能使用static关键字,由于static修饰方法,能够直接经过类名进行调用,但抽象类是不能实例化的
相关文章
相关标签/搜索