楼主java渣渣一枚,面试了几家公司,现在整理出面试的问题,找出自己的不足。好了,废话不多说。开始
一、基础篇
1.面向对象的特征:封装、多态、继承、抽象。
1.1 封装:封装是吧过程是和数据包围起来,对数据访问只能通过已定义的界面。封装保证了模块具有较好的独立性,使程序维护更加方便
1.2 多态:多态是指不同的类的对象对同一消息作出反应。(所有的动物都继承动物类,都有吃的行为,但是吃的不一样)
1.3 继承:继承是一种联结类的层析模型,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。
1.4 抽象:(汽车的建造图纸是抽象类,由图纸造成的汽车,为对象)
2.final,finally,finalize的区别
final是修饰符,呗final修饰嘞类或方法,就意味着此类不能被重新,也不能被继承。因此,一个类,不能由final和abstract两个关键字修饰。被final修饰的变量必须在声明时给出变量的初始值,并且此便令只能读取。
finally是异常处理时提供finnally块来执行任何清楚操作,无论报不报异常,都会执行finally块中的语句
finalize是方法名,java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除之前做必要的清理工作。他是object中的方法,所以,所有类都继承它
3.int和Integer的区别
int是基本类型,Integer是int的包装类,int的初始值是0,Integer的初始值是null
Integer与new Integer不相等,因为new出来的对方放在堆内存红,Integer的对象脂肪放在常量池中
两个非new出来的Integer对象,如果数在-128到127之间,则是true,否则是false。Integer i2 = 128的时候,被翻译成:Integer i2 = Integer.valueOf(128);
int和Integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比。
4.重载和重写的区别
重写:发生在继承关系中,是子类的方法覆盖父类的方法,要求返回值方法名和参数相同。子类方法的访问级别不能低于父类相应发放的访问级别
重载:在同一个类中,方法名相同但是参数个数或者是参数类型不同
5.抽象类和接口的区别
1.抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
2.抽象类要被子类继承,接口要被类实现。
3.接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
4.接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
5.抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
6.抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果
7.抽象类里可以没有抽象方法
8.如果一个类里有抽象方法,那么这个类只能是抽象类
9.抽象方法要被实现,所以不能是静态的,也不能是私有的。
10.接口可继承接口,并可多继承接口,但类只能单继承。
6.说说反射的用途及实现
6.1.java反射机制可以动态的创建对象并代用其属性。反射的核心是JVM在运行时,才动态加载的类货调用方法或实行,他不需要事先知道运行的对象是谁
6.2.java发射框架有这些功能,在运行时判断任意一个对象所属嘞、在运行时构造任意一个类的对象、在运行时判断任意一个类所具有的成员变量和方法、在运行时调用任意一个对象的方法
7.HTTP 请求的 GET 与 POST 方式的区别
get:使用get方法时,查询字符串被附加在URL地址后面一起发送到服务器
get请求能被缓存、get请求会保存在浏览器中的浏览记录中、get请求的URL能够保存为浏览器的书签、get请求有长度限制、get请求只要用以数去数据、get方法可以在浏览器历史记录中查询到、点击刷新按钮,对get方法没有影响,post方法则数据会重新发送
8.session 与 cookie 区别
session保存在服务器端,关闭回话后,session就死掉。session可以存放任意的java对象,cookie只能存储String类型的对象
cookie保存在客户端,主要内容包括(名字、值、国企时间、路径、域),因为cookie存储在客户端,所以可以编辑伪造, 不是十分安全。session过多时会消耗服务器资源,影响系统速度。
9.equals 与 == 的区别
==比较的是栈内存中寻访的对象的堆内存的地址,用来判断是否指向的是同一个对象
equals比较的是两个对象的内容是否相等
子类继承父类程序执行顺序问题
首先第一部分执行的是父类的静态代码块—子类的静态代码块—主程序。这一部分都是执行一次,与建立多少对象没有关系。第二部分new了一个父类对象,并调用了方法。执行了它的非静态代码块—构造函数—一般方法。第三部分new了一个子类的对象,并调用了方法。执行顺序为父类的非静态代码块—父类的无参构造函数,然后是子类的非静态代码块—子类构造函数—子类的方法。
二、集合
集合这一块呢,大佬告诉我说,只要是把hashmap吃透,所有的都会了, 不过到现在还没看源码,所以先写一些自己会的东西吧
先来hashmap
hashmap的工作原理
hashmap是一个散列表,存储方式是key-value存储方式。
hashmap继承与AbstractMap,实现了Map,cloneable,serializable接口
hashmap是线程不安全的,在多线程的环境中,要用ConcurrentHashMap
然后再了解一下hash碰撞吧
两个不同的元素,通过hash函数得出的实际存储地址相同,即为hash碰撞。冲突解决方案有很多种:开放地址发、散列函数法链地址法,hashmap即采用了链地址法,即数组+链表的方式。
HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,如果定位到的数组位置不含链表(当前entry的next指向null),那么对于查找,添加等操作很快,仅需一次寻址即可;如果定位到的数组包含链表,对于添加操作,其时间复杂度为O(n),首先遍历链表,存在即覆盖,否则新增;对于查找操作来讲,仍需遍历链表,然后通过key对象的equals方法逐一比对查找。所以,性能考虑,HashMap中的链表出现越少,性能才会越好。(转载https://www.cnblogs.com/chengxiao/p/6059914.html)。
重写equals时,必须要重写hashcode。(equals相等的两个对象,hashcode一定相等,否则不一定相等)
Arraylist 与 LinkedList 区别
arrayList是基于动态数组的数据结构,linkedList是基于链表的数据结构
查询多用arrayList,因为LinkdList要移动指针(注:java虽然移除了指针的概念,但是还有用到指针的),新增和修改多用linkedList,因为ArrayList要移动数据
我遇到的集合就这么两个问题,其他的自己了解就OK了,小编就不在这一一列举了。
问的最多的要来了,框架。
Spring篇:
Spring是如何实现IOC和AOP的。(必问)
Spring IOC:控制反转,将类的创建和依赖关系写进xml文件中,由配置文件引入,实现了松耦合。(基于反射)
如类A要调用类B的方法,以前我们都是在类A中,通过自身new一个类B,然后在调用类B的方法,现在我们把new类B的事情交给spring来做,在我们调用的时候,容器会为我们实例化
Spring AOP:依赖注入,(基于代理)
面向切面编程,在我们的应用中,经常需要做一些事情,但是这些事情与核心业务无关,比如,要记录所有update*方法的执行时间时间,操作人等等信息,记录到日志,通过spring的AOP技术,就可以在不修改update*的代码的情况下完成该需求。
SpringMVC工作流程:
用户发送请求到前端控制器(DispatcherServlet)
前端控制器请求处理器映射器(handlerMapper),去查找处理器(handler)
找到后处理器映射器像前端发回执行链
前端控制器调用处理器适配器(handlerAdapter)去执行处理器
处理器适配器执行处理器
执行完以后,处理器适配器返回modelAndView
前端控制器请求试图解析器进行试图解析器
试图解析器向前端返回view
前端控制器对视图进行渲染
前端控制器向用户返回试图
Spring的beanFactory和factoryBean的区别
BeanFactory是IOC最基本的容器,负责生产和管理bean,它为其他具体的IOC容器提供了最基本的规范,,例如DefaultListableBeanFactroy,XMLBeanFactory,等具体的容器都实现了BeanFactory
FactroyBean是一个接口,当IOC容器中的Bean实现了FaxtoryBean后,通过getBean(String BeanName)获取到Bean对象并不是FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&