面试--基础

最新Java面试题,常见面试题及答案汇总

https://blog.csdn.net/fangchao2011/article/details/89203535

继承,封装,多态?

封装:是对象和类概念的主要特性,把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

继承:子类继承父类,它就可以使用父类的所有功能,并在无需编写父类的情况下对这些功能进行扩展。

多态:多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。

简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。Fu f=new Zi();  多态的三个条件:一、要有继承;二、要有重写;三、父类引用指向子类对象  

抽象类和接口的区别?

抽象类中的方法可以是非抽象的;访问类型可以为public protected  或者默认的。

接口中的所有方法都必须是抽象的;接口中的方法定义默认为public abstract类型,但jdk1.8中接口中使用default,static修饰的默认方法和静态方法并且都有方法体。

抽象类中的静态变量的访问类型可以是任意的,接口中的静态成员变量类型默认为public static final。

抽象类可以有构造方法,接口中不能有构造方法。

一个类可以实现多个接口,但只能继承一个抽象类。

java中io流分为几种?

按照功能分为:输入流和输出流

按照类型分为:字节流和字符流

字节流和字符流的区别,字节流按8位传输以字节为单位输入输出数据,字符流按16位传输以字符为单位输入输出数据。

&和&&的区别?

&和&&都可以用作逻辑与的运算符,当运算符两边的表达式的结果都为true时,整个运算结果才为true 
&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,
&还可以用作位运算符,当&操作符两边的表达式不是boolean类型时, &表示按位与操作(只有两个数的二进制同时为1,结果才为1,否则为0)

重载和重写的区别?

重载实质就是在一个类中有多个具有不同参数个数或者参数类型或者参数顺序同名方法(返回类型可以随意,不能以返回类型作为重载函数的区分标准),是一个类中多态性的一种表现。

重写是父类与子类之间的多态性,子类重写父类的方法,子类函数的访问权限修饰符不能小于父类的。如需父类中原有的方法使用super关键字。

构造方法名必须和类名一致,所以构造方法不能被重写,但是可以被重载。

String类的常用方法?

length():返回字符串长度;split():分割字符串,返回一个分割后的字符数组。indexOf("i"):返回指定字符的索引;charAt(i):根据下标获取对应的字符;

equals():字符串比较;replace():字符串替换,然后返回一个新的字符串,注意:原本的字符串不变;trim():去掉字符串前面和后面的空格;

concat():拼接字符串 ;substring(i):从下标为i往后截取字符串(包括下标为i)。substring(begin,end):截取的字符串包含begin不含end

getBytes():返回字符串的 byte 类型数组;toUpperCase():将字符串转成大写字符;toLowerCase():将字符串转成小写字母;

String为什么是不可变的?Stringbuffer和StringBuilder

源码中String类中有一个char数组,并且这个char数组是被final修饰的。因为数组一旦创建长度不可变。

并且被final修饰的引用一旦指向某个对象之后,不可在指向其它对象,所以String是不可变的!

StringBuffer/StringBuilder都继承AbstractStringBuilder类,内部实际上是一个没有被final修饰char[ ]数组,

StringBuffer和StringBulider的初始化容量应该为16,当存满之后会进行扩容,底层调用了数组拷贝的方法:System.arraycopy()…扩容的,

所以StringBuffer/StringBuilder适用于字符串的频繁拼接操作,并且StringBuffer是线程安全的,StringBuilder是非线程安全的。

==和equals的区别?

==:如果比较的对象是基本数据类型,则比较的是数值是否一致;如果比较的是引用数据类型,则比较的是对象的地址值是否一致。

equals()方法不能用于比较基本数据类型的对象用于比较对象的时候返回值取决于重写实现。

对于String类 Date类 File类等 可重写equals() 方法用于比较对象的属性内容是否一致。

final,finally,finalize的区别?

final用于声明属性,方法,类,分别表示属性不可变,方法不可覆盖,类不可继承。

finally是异常处理结构语句的一部分,表示总是执行。

finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等.JVM不保证此方法总被调用。

补充:try -catch语句块中存在return语句,finally会不会执行。

不管有没有出现异常,或者try-catch中有return时,finally仍然会执行,先执行try-catch里面return之前(包括return 语句中的表达式计算),再执行finally块,

finally中最好不要有return,否则会提前退出,返回值不是try或catch中保存的返回值。

int 和integer有什么区别?

int是java提供的8种原始数据类型之一。java为每个原始数据类型提供了封装类,Integer就是java为int提供的封装类。

int的默认值为0,Integer的默认值为null,是引用类型,即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况,

 ①、无论如何,Integer与new Integer不会相等。不会经历拆箱过程,因为它们存放内存的位置不一样。

 ②、两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false。

 ③、两个都是new出来的,则为false。

 ④、int和integer(new或非new)比较,都为true,因为会把Integer自动拆箱为int,其实就是相当于两个int类型比较。

list和set和map的区别?

list:  是一个有序的容器,允许重复的对象,可以插入多个null元素

set:  是一个无序的容器,不允许重复的对象,只能插入一个null元素

list的常用实现类有ArrayList,LinkedList和Vector.ArrayList最流行,查询速度快支持随机访问。LinkedList更适用于经常从list中增加删除元素的场合。Vector表示底层数组,线程安全。

set的常用实现类有 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap实现的 HashSet;

LinkedHashset : 保证元素添加的自然顺序 ;TreeSet : 保证元素的自然顺序a-z排列 ;HashSet无序。

map不是collection的子接口或者实现类,map是一个接口。

map里可以有任意的null值但是只能有一个null键,map可能有相同的值但是键对象必须是唯一的。map的常用实现类是CurrentHashMap,HashMap,LinkedHashMap,HashTable,TreeTable.

ArrayList和LinkedList的区别?

最明显的区别是 ArrrayList底层的数据结构是数组,支持随机访问,而 LinkedList 的底层数据结构是双向循环链表,不支持随机访问。使用下标访问一个元素。

ArrayList 的时间复杂度是 O(1),而 LinkedList 是 O(n)

如何实现List和数组之间的转换?

List转换成为数组:调用ArrayList的toArray方法。

数组转换成为List:调用Arrays的asList方法。

Array和ArrayList的区别?

Array可以包含基本类型和对象类型,ArrayList只能包含对象类型

Array的大小是固定的,ArrayList的大小是动态的

Array数组只能通过数组下标来对指定位置的元素进行变更。

ArrayList在Array的基础上增加了很多的方法。比如add,addAll,remove,removeAll,contains,以及iterator等等多种丰富的功能方法。

使用场景:如果我们需要保存一些在整个程序运行期间都会存在而且不变的数据,我们可以使用Array。但是我们如果只是单纯想要以数组的形式保存数据,而不是对数组进行增加等操作,只是方便我们查找的话,那么选择ArrayList

并行和并发的区别?

并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生。

并行是在不同实体上的多个事件,并发是在同一实体上的多个事件。

Sleep和Wait的区别?

1、sleep是线程中的方法,但是wait是Object类中的方法。

2、sleep方法不会释放lock,但是wait会释放,而且会加入到等待队列中。

3    wait,notify和notifyAll只能在同步方法或者同步代码块里面使用,而sleep可以在任何地方使用

4    sleep必须指定时间,wait可以指定也可以不指定时间

run()和start()的区别?

线程的run()方法是由java虚拟机直接调用的,如果我们没有启动线程(没有调用线程的start()方法)而是在应用代码中直接调用run()方法,那么这个线程的run()方法其实运行在当前线程(即run()方法的调用方所在的线程)之中,而不是运行在其自身的线程中,从而违背了创建线程的初衷;

public class WelcomThread extends Thread {
//在该方法中实现线程的任务逻辑
public void run() {
//获取当前正在执行的线程名称
System.out.println(Thread.currentThread().getName());
}
}


public class TestDemo1 {
public static void main(String[] args) {
Thread welcome = new WelcomThread(); //创建线程(动态规划)
welcome.run(); //直接调用run()方法
System.out.println(Thread.currentThread().getName());
Thread welcome1 = new WelcomThread(); //创建线程
welcome1.start(); //启动线程
}
}

运行结果:main

                  main
                 Thread-1

数据库索引原理?

数据库索引是数据库管理系统中一个排序的数据结构,以协助快速查询或更新数据库表中数据。索引的实现通常使用BTree及其变种B+Tree

为什么使用索引?

数据库查询是数据库最主要的功能之一。而当数据量越来越大的时候,查询花费的时间会随之增长。索引可以加速数据的查询。因为索引是有序排列的,可以大大减少了存储引擎需要扫描的数据量 

举个例子来说,假设我们有一个数据库表EpUser,这个表分别有三个字段:name,age,address。假设表中有1000条记录。

假如没有使用索引,当我们查询名为“James”的雇员的时候,即调用:select name,age,address from Employee where name = 'James';

此时数据库不得不在Employee表中对这1000条记录一条一条的进行判断name字段是否为“James”。这也就是所谓的全表扫描。

如果在EpUser表上的name字段上创建索引,在我们查询时,会通过索引去查询名为“James”的雇员,这时查找名为“James”的记录时会快很多,因为该索引已经按照字母顺序排列,名字首字母为“J”的雇员都是排列在一起的。通过该索引,能获取到表中对应的记录。

为什么使用B-Tree索引?

一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上,因此索引查找过程会产生IO消耗,

相对于内存存取,IO存取的消耗要高几个数量级,所以评价一个数据结构作为索引的优劣最重要的指标就是在查找过程中磁盘I/O操作次数的渐进复杂度。

换句话说就是索引的结构组织要尽量减少查找过程中磁盘的存取次数。

SQL优化方法?

(1)负向条件查询不能使用索引,可以优化为in查询

    select from user where status != 0  (not in /not exist都不好);

    select from user where status in(2,3);

(2)如果业务大部分是单条查询,使用Hash索引性能更好

         因为B-tree索引的时间复杂度是O(log(n)) 而Hash索引的时间复杂度是O(1)

         select from user where login_name=?

(3)单列索引不存null值,复合索引不存全为null的值,如果列可以为null,可能会得到不符合预期的结果集。

          select  from user where name!='kun'

         如果name允许为null,索引不存null值,结果集中不会有这些记录,因此请使用not null 约束以及默认值。

(4)遵循符合索引最左前缀原则。最左前缀不是指SQL语句where顺序要和复合索引顺序一致

(5)使用枚举而不是字符串

(6)如果明确知道只有一条返回结果,limit 1能够提高效率

(7)不要使用select * 查询,只返回需要的列

(8)使用单表查询时,相同字段尽量不要用or,因为可能导致索引失效,用UNION代替。

          select  * from user where name='手机' or name ='电脑'(反面教材)

(9)索引不宜过多,根据实际情况决定,尽量不要超过10个。

(1) 表关联查询时务必遵循小表驱动大表原则

(2)分表,可根据业务字段尾数中的个位或十位或百位做表名达到分表的目的

(3)分库,可根据业务字段尾数中的个位或十位或百位做库名达到分库的目的

(4)表分区,类似于硬盘分区,可以将某个时间段的数据放在分区里,加快查询速度,可以配合分表+表分区结合使用

(5)使用非前导模糊查询

(6)在数据区分度大的字段上使用索引,一般能过滤80%的数据时就可以使用索引

(7)在属性上进行计算不能命中索引

神器EXPLAIN语句

explain显示了mysql如何使用索引来处理select语句及连接表。可以帮助选择更好的索引和写出更优化的查询语句

使用方法:在select语句前面加上explain就行

explain语句输出结果中各属性简介

table:显示这一行的数据是关于哪张表的

type:这是重要的列,显示连接使用了何种类型,从最好到最差的连接类型为const,eq_reg,ref,range,indexhe和all

possible_Keys:可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从where语句中选择一个合适的语句

key:实际引用的索引。如果为null,则没有使用索引。很少的情况下,mysql会选择优化不足的索引。

这种情况下,可以在select语句中使用use index(indexname)来强制使用一个索引或者用ignore index(indexname)来强制mysql忽略索引。

key_len:使用索引的长度。在不损失精确性的情况下,长度越短越好。

ref:显示索引的哪一列被使用了,如果可能的话,是一个常数

rows:mysql认为必须检查的用来返回请求数据的行数

extra:关于mysql如何解析查询的额外信息

      

 

 
我话讲完!谁赞成?谁反对?
原文地址:https://www.cnblogs.com/wffzk/p/13204647.html