1.static关键字的含义,是否可以重写私有方法或静态方法,为什么?
1.static关键字:
简单:static关键字表明一个成员变量或者成员方法可以在没有所属的类的实例变量的情况下被访问。
详细:通常来说,当创建类时,就是在描述那个类的对象的外观与行为。除非用new创建那个对象,否则,实际上并未获得任何对象。执行new来创建对象的时候,数据存储空间才被分配,其方法才供外界调用。有两种情形用上述方法是无法解决的。一种情形是,只想为某特定域分配单一存储空间,而不去考虑究竟要创建多少个对象,甚至根本不需要创建任何对象。另一种情形是,希望某个方法不与包含他的类的任何对象关联在一起。也就是说,即使没有创建对象,也能够调用方法。简单来说,static的主要目的就是创建独立于具体对象的域变量与方法。
可见,static变量并不是所在类的某个具体对象所有,而是该类的所有对象所共有的,静态变量既能被对象调用,也能直接拿类来调用。除此之外,静态变量不能引用非静态方法,原因正如前面描述静态加载时机中说的那样,加载静态的时候,非静态的变量、方法等还不存在,当然就无法引用了。但是,非静态方法或类却能正常引用静态变量或方法。因为非静态总是在静态之后出现的。静态方法和静态变量一样,属于类所有,在类加载的同时执行,不属于某个具体的对象,所有对象均能调用。
2.不可以重写私有方法,因为私有方法不能被子类访问,所以无法重写;
3.静态方法不依赖类就可以访问。这就是它的用途啊,没有new对象可调用的方法。然而,重写是依赖对象的。重写父类的某一方法,而static不依赖类。
2.抽象类和接口有什么区别?
1.抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用。
2.一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类。
3.接口比抽象类更加抽象,因为抽象类中可以定义构造器,可以有抽象方法和具体方法,而接口中不能定义构造器而且其中的方法全部都是抽象方法。
4.抽象类中的成员可以是private、默认、protected、public的,而接口中的成员全都是public的。
5.抽象类中可以定义成员变量,而接口中定义的成员变量实际上都是常量。
6.有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法。
3.为什么java在实现equals必须要同时实现hashcode方法?
原文地址:why在重写equals时还必须重写hashcode方法 - 发表是最好的记忆 - 博客园
首先我们先来看下String类的源码:可以发现String是重写了Object类的equals方法的,并且也重写了hashcode方法
1、如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同;
2、如果两个对象的hashCode相同,它们并不一定相同(即用equals比较返回false)
自我的理解:
由于为了提高程序的效率才实现了hashcode方法,先进行hashcode的比较,如果不同,那没就不必在进行equals的比较了,这样就大大减少了equals比较的次数,这对比需要比较的数量很大的效率提高是很明显的,一个很好的例子就是在集合中的使用;
我们都知道java中的List集合是有序的,因此是可以重复的,而set集合是无序的,因此是不能重复的,那么怎么能保证不能被放入重复的元素呢,但靠equals方法一样比较的话,如果原来集合中以后又10000个元素了,那么放入10001个元素,难道要将前面的所有元素都进行比较,看看是否有重复,欧码噶的,这个效率可想而知,因此hashcode就应遇而生了,java就采用了hash表,利用哈希算法(也叫散列算法),就是将对象数据根据该对象的特征使用特定的算法将其定义到一个地址上,那么在后面定义进来的数据只要看对应的hashcode地址上是否有值,那么就用equals比较,如果没有则直接插入,只要就大大减少了equals的使用次数,执行效率就大大提高了。
继续上面的话题,为什么必须要重写hashcode方法,其实简单的说就是为了保证同一个对象,保证在equals相同的情况下hashcode值必定相同,如果重写了equals而未重写hashcode方法,可能就会出现两个没有关系的对象equals相同的(因为equal都是根据对象的特征进行重写的),但hashcode确实不相同的。
4.请描述statement和preparedStatement的区别?
与Statement相比,①PreparedStatement接口代表预编译的语句,它主要的优势在于可以减少SQL的编译错误并增加SQL的安全性(减少SQL注射攻击的可能性);②PreparedStatement中的SQL语句是可以带参数的,避免了用字符串连接拼接SQL语句的麻烦和不安全;③当批量处理SQL或频繁执行相同的查询时,PreparedStatement有明显的性能上的优势,由于数据库可以将编译优化后的SQL语句缓存起来,下次执行相同结构的语句时就会很快(不用再次编译和生成执行计划)
5.阐述ArrayList、Vector、LinkedList的存储性能和特性。
ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector中的方法由于添加了synchronized修饰,因此Vector是线程安全的容器,但性能上较ArrayList差,因此已经是Java中的遗留容器。LinkedList使用双向链表实现存储(将内存中零散的内存单元通过附加的引用关联起来,形成一个可以按序号索引的线性结构,这种链式存储方式与数组的连续存储方式相比,内存的利用率更高),按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。Vector属于遗留容器(Java早期的版本中提供的容器,除此之外,Hashtable、Dictionary、BitSet、Stack、Properties都是遗留容器),已经不推荐使用,但是由于ArrayList和LinkedListed都是非线程安全的,如果遇到多个线程操作同一个容器的场景,则可以通过工具类Collections中的synchronizedList方法将其转换成线程安全的容器后再使用(这是对装潢模式的应用,将已有对象传入另一个类的构造器中创建新的对象来增强实现)。
注:ArrayList和LinkedList的区别
ArrayList和LinkedList的大致区别如下:1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
上代码:
当我们在集合中装5万条数据,测试运行结果如下:
显然我们可以看出ArrayList更适合读取数据,linkedList更多的时候添加或删除数据。
ArrayList内部是使用可増长数组实现的,所以是用get和set方法是花费常数时间的,但是如果插入元素和删除元素,除非插入和删除的位置都在表末尾,否则代码开销会很大,因为里面需要数组的移动。LinkedList是使用双链表实现的,所以get会非常消耗资源,除非位置离头部很近。但是插入和删除元素花费常数时间。
6.阐述ArrayList和数组的区别
ArrayList可以算是Array的加强版,(对array有所取舍的加强)。
存储内容比较:
Array数组可以包含基本类型和对象类型,
ArrayList却只能包含对象类型。
但是需要注意的是:Array数组在存放的时候一定是同种类型的元素。ArrayList就不一定了,因为ArrayList可以存储Object。
空间大小比较:
它的空间大小是固定的,空间不够时也不能再次申请,所以需要事前确定合适的空间大小。
ArrayList的空间是动态增长的,如果空间不够,它会创建一个空间比原空间大一倍的新数组,然后将所有元素复制到新数组中,接着抛弃旧数组。而且,每次添加新的元素的时候都会检查内部数组的空间是否足够。(比较麻烦的地方)。
方法上的比较:
ArrayList作为Array的增强版,当然是在方法上比Array更多样化,比如添加全部addAll()、删除全部removeAll()、返回迭代器iterator()等。
适用场景:
如果想要保存一些在整个程序运行期间都会存在而且不变的数据,我们可以将它们放进一个全局数组里,但是如果我们单纯只是想要以数组的形式保存数据,而不对数据进行增加等操作,只是方便我们进行查找的话,那么,我们就选择ArrayList。而且还有一个地方是必须知道的,就是如果我们需要对元素进行频繁的移动或删除,或者是处理的是超大量的数据,那么,使用ArrayList就真的不是一个好的选择,因为它的效率很低,使用数组进行这样的动作就很麻烦,那么,我们可以考虑选择LinkedList。
7.final与finally的区别,为什么内部类访问的外部变量需要final来修饰
a.final是一个关键字,修饰变量那么变量初始化之后就不可改变,修饰类则不可以继承,修饰方法,那么方法就不可以被重写,而finally与try,catch语句块一起使用,始终执行。
b.当使用成员内部类时,它可以直接访问外类的变量(public、默认、private权限修饰符修饰的),不会出现问题;而在使用它访问局部变量时,Java8以前的版本会报错:从内部类中访问本地变量a,需要被声明为最终类型。这时候你在变量前面加个状态修饰符final,就能正常运行了。
我们知道,当方法调用完以后,方法就会被当作垃圾而被回收,可是局部内部类创建的对象在堆内存,它并不会立即消失,相反,它仍存在,并且仍在调用局部变量,这显然与局部变量已被销毁矛盾。这时候Java语言提供了一个巧妙的解决办法,用状态修饰符final修饰该变量,从而该变量成了常量,解决了这个问题。
8.fileReader和bufferedReader的执行速度
a.首先摘录一段在百度里面搜索到的关于缓冲区的作用以及效果描述:这么说吧,缓冲区的主要目的是加速的, 内存的缓冲区读写速度要远远快于硬盘,如果读一点从硬盘文件取一点,或者有一点内容就直接写到硬盘文件一点,速度会比较慢
举一个例子,只是为了好理解,实际情况并不完全一样,我要从某学生宿舍(相当于硬盘)开车接送98个学生到公司(相当于CPU)来进行面试.接一个学生过来,面试完送一个回去,再接另一个过来,速度会很慢
我在公司找两个10人房间(相当于缓冲区),一次接10个学生在等待面试房间(read缓存)里,面试一个,送进等待送回房间(write缓存),等待面试房间空了,自动再接10个.
同样的,等待送回房间满10人后自动一起送回去.......这样是不是快得多?
b.当BufferedReader在读取文本文件时,会先尽量从文件中读入字符数据并置入缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取,如果缓冲区数据不足,才会再从文件中读取。
FileReader : 字符流
BufferedReader : 也是字符流,但是在BufferedReader可以先把数据放到一个缓存区里,然后在进行处理,而且在BufferedReader 里有一个readLine()方法。
9.请描述一下ArrayBlockingQueue和LinkedBlockingQueue的区别和联系
详细的解释摘自ArrayBlockingQueue与LinkedBlockingQueue - 简书
队列中锁的实现不同
ArrayBlockingQueue实现的队列中的锁是没有分离的,即生产和消费用的是同一个锁;
LinkedBlockingQueue实现的队列中的锁是分离的,即生产用的是putLock,消费是takeLock
在生产或消费时操作不同
ArrayBlockingQueue实现的队列中在生产和消费的时候,是直接将枚举对象插入或移除的;
LinkedBlockingQueue实现的队列中在生产和消费的时候,需要把枚举对象转换为Node进行插入或移除,会影响性能
队列大小初始化方式不同
ArrayBlockingQueue实现的队列中必须指定队列的大小;
LinkedBlockingQueue实现的队列中可以不指定队列的大小,但是默认是Integer.MAX_VALUE
4.ArrayBlockingQueue采用的是数组,LinkedBlockingQueue采用的是单向链表
put take 实现原理:
里面有两个显式条件队列Condition 由ReentrantLock newConditon()得到
一个为notFull:没有满
另一个为notEmpty:不是空的
final Object[] items;缓冲队列
当put一个元素时先判断是不是满的如果是九调用notFull.await()阻塞到不是满的
添加成功之后调用notEmpty.singnal();通知消费者有产品可消费了,解除消费者阻塞
当take一个元素时先判断是不是空的如果是空的先调用notEmpty.await()阻塞,如果取得了元素(从items里面移除),就调用notFull.singnal()唤醒并阻塞的生产者。
10.你描述一下使用过的java.util.concurrent包下的类 以及使用场景
链接一下:java 并发 concurrent 包 - CSDN博客
11.SpringMVC中如何实现参数的解析
链接:SpringMVC之分析请求参数的解析过程(一) - 程序园
12.springMVC中IOC和AOP的理解
链接:Spring面试,IoC和AOP的理解 - Sandy_wu
13.session和cookie之间的区别和联系
1. 由于HTTP协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是Session.典型的场景比如购物车,当你点击下单按钮时,由于HTTP协议无状态,所以并不知道是哪个用户操作的,所以服务端要为特定的用户创建了特定的Session,用用于标识这个用户,并且跟踪用户,这样才知道购物车里面有几本书。这个Session是保存在服务端的,有一个唯一标识。在服务端保存Session的方法很多,内存、数据库、文件都有。集群的时候也要考虑Session的转移,在大型的网站,一般会有专门的Session服务器集群,用来保存用户会话,这个时候 Session 信息都是放在内存的,使用一些缓存服务比如Memcached之类的来放 Session。
2. 思考一下服务端如何识别特定的客户?这个时候Cookie就登场了。每次HTTP请求的时候,客户端都会发送相应的Cookie信息到服务端。实际上大多数的应用都是用 Cookie 来实现Session跟踪的,第一次创建Session的时候,服务端会在HTTP协议中告诉客户端,需要在 Cookie 里面记录一个Session ID,以后每次请求把这个会话ID发送到服务器,我就知道你是谁了。有人问,如果客户端的浏览器禁用了 Cookie 怎么办?一般这种情况下,会使用一种叫做URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数,服务端据此来识别用户。
3. Cookie其实还可以用在一些方便用户的场景下,设想你某次登陆过一个网站,下次登录的时候不想再次输入账号了,怎么办?这个信息可以写到Cookie里面,访问网站的时候,网站页面的脚本可以读取这个信息,就自动帮你把用户名给填了,能够方便一下用户。这也是Cookie名称的由来,给用户的一点甜头。
所以,总结一下:
Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中;
Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。
14.java的包装类和基本数据类型之间的区别
1、包装类是对象,拥有方法和字段,对象的调用都是通过引用对象的地址,基本类型不是
2、包装类型是引用的传递,基本类型是值的传递
3、声明方式不同,基本数据类型不需要new关键字,而包装类型需要new在堆内存中进行new来分配内存空间
4、存储位置不同,基本数据类型直接将值保存在值栈中,而包装类型是把对象放在堆中,然后通过对象的引用来调用他们
5、初始值不同,eg: int的初始值为 0 、 boolean的初始值为false 而包装类型的初始值为null
6、使用方式不同,基本数据类型直接赋值使用就好 ,而包装类型是在集合如 coolection Map时会使用
15.多线程中的wait和sleep的区别
sleep()和wait()方法的最大区别是:
sleep()睡眠时,保持对象锁,仍然占有;
而wait()睡眠时,释放对象锁。
16.linux中查看服务器日志的命令
tail -f -n 5 /var/log/syslog
这个是输出最近5行的日志命令
17.事务的四大特性
⑴ 原子性(Atomicity)
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
⑵ 一致性(Consistency)
一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。
⑶ 隔离性(Isolation)
隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。
关于事务的隔离性数据库提供了多种隔离级别,稍后会介绍到。
⑷ 持久性(Durability)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
18.linux 查看并杀死进程
ps -ef|grep java
kill xxx
killall -9 NAME
19.redis可以存放的数据类型都有?
String----------字符串
Hash------------字典
List-------------列表
Set--------------集合
Sorted Set------有序集合
关于redis常用的命令使用摘自:Redis常用数据类型介绍、使用场景及其操作命令 - lizhenghn - 博客园
20.java虚拟机中的内存模型?
关于详细的模型介绍摘自:jvm的内存分配总结 - 简书
21.String str2 = new String("ABC") 创建了几个对象,他和String str2 = "ABC"的区别?
详情摘自java中String new和直接赋值的区别 - CSDN博客
22.java集合关系,以及list,set,map关系区别
区别摘自:Java 面试高频提问知识点之:Set、List 和 Map 的区别 - Java开发社区 | CTOLib码库
23.hashMap和hashTable的区别?
1.hashMap去掉了HashTable 的contains方法,但是加上了containsValue()和containsKey()方法。
2.hashTable同步的,而HashMap是非同步的,效率上逼hashTable要高。
3.hashMap允许空键值,而hashTable不允许。
24.JVM中的永久代中会发生垃圾回收吗?
垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全垃圾回收。如果你仔细查看垃圾收集器的输出信息,就会发现永久代也是被回收的。这就是为什么正确的永久代大小对避免full gc是非常重要的原因。
25.在java中,对象什么时候可以被垃圾回收?
当对象对当前使用这个对象的应用程序变得不可触及的时候,这个对象就可以被回收了。
26.java中垃圾回收有什么目的?什么时候进行垃圾回收?
垃圾回收是在内存总存在没有引用的对象或者超过作用域的对象时进行。
垃圾回收的目的就是识别并且丢弃应用不再使用的对象来释放和重用资源。
27.hashMap的工作原理是什么?
Java总的hashMap是以键值对的形式来存储元素的。HashMap需要一个hash函数,他使用hashCode()和equals()方法来想集合或者集合添加和检索元素。当调用put()方法的时候,HashMap会计算key的hash值,然后把键值对存储在集合中合适的索引上。如果key已经存在了,value就会被更新成新值。HashMap的一些重要的特性是他的容量,负载银子河扩容极限。