java面试题1

1.java的四个基本特性:

抽象:将一个类对象的共同特征总结出来构造类的过程,包括数据的抽象和行为的抽象,抽象只关注对象有哪些行为,并不关注行为的细节

封装:把数据和数据操作的方法绑定起来,对数据的访问只能通过已定义的接口,封装就是隐藏一切可隐藏的东西,只向外界提供最简单的额接口

继承:从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类,得到继承的类叫做派生类

多态:允许不同类型的对象对同一条信息作出不同的相应(具体实现方法:重载和重写)

2.面向对象和面向过程的区别?

面向过程就像一个细心的管家,事无巨细的考虑周到,而面向对象就像一个家用电器,你只需要知道他的功能,不需要知道他的工作原理

面向过程是一个以事件为中心的编程思想。就是分析问题所需的步骤,然后用函数把这些步骤实现,并按顺序调用,面向对象是以对象为中心的编程思想

3.重载和重写如何确定调用的是哪个函数?

重载:重载发生在不同的类中,同名的方法如果有不同的参数列表(参数的类型和参数个数或者两者都不同)则视为重载

重写:重写放生在父类和子类之间,重写要求子类被重写的方法与父类被重写的方法有相同的返回类型,比父类被重写的方法更好的访问,不能比父类被重写的方法生命更多的异常

4.面向对象的六个基本原则(单一职责,开放封闭,里氏代换,依赖倒置,合成聚合复用,接口隔离)

单一职责:一个类只有他该做的事情

开放封闭:软件实体应当对扩展开放,对修改封闭。要做到开闭有两个要点,抽象和封装

里氏代换:任何时候都可以用子类型替换掉父类型。子类一定是增加父类的能力而不是减少父类的能力

依赖倒置:高层次的模块不应依赖于底层是的模块,他们都应该依赖于抽象,抽象不应该依赖于具体实现,具体实现应该依赖与抽象

合成聚合复用:优先使用聚合和合成关系复用的代码

接口隔离:接口要小而专,决不能大而全

迪米特法则:又叫最小只是法则,一个对象应当对其他对象有尽可能少的了解

5.static和final

static

      修饰变量:静态变量随着类加载时被完全初始化,内存中只有一个,且JVM只会为他分配一次内存

      修饰方法:在类加载的时候就存在,不依赖任何实例,static方法必须实现,不能用abstract修饰

      修饰代码块:在类加载完成后就会执行代码块中的内容

      顺序:父类静态代码块,子类静态代码块,父类非静态代码,父类构造方法,子类非静态代码块,子类构造方法

final

      修饰变量:

            编译期常量,类加载过程完成初始化,编译后带入到任何计算式中,只能是基本类型

            运行时常量:基本数据类型或引用数据类型,引用不可变,单一用对象内容可变

      修饰方法:方法不能被继承

      修饰类:类不能被继承

      修饰形参:形参不可变

6.HashMap和HashTable的区别,HashMap中的key可以使任何对象或数据类型吗,HashTable线程安全吗

HashMap和HashTable的区别

      HashTable的方法是同步的,HashMap未经同步,所以多线程场合要手动同步HashMap

      HashTable不允许有空值,HashMap允许有空值

      两者遍历方式大同小异,HashTable仅比HashMap多了一个elements方法

      HashTable使用Enumeration,HashMap使用Iterator

      哈希值使用不同,HashTable直接使用对象的hashcode,而HashMap重新计算hash值,而且用于代替求模

      HashTable中hash数组默认大小是11,增加方式是old*2+1,HashMap中hash数组默认大小是16,而且一定是2的指数

7.HashMap和ConcurrentHashMap区别,ConcurrentHashMap怎么保证线程安全的

HashMap线程不安全,ConcurrentHashMap线程安全

ConcurrentHashMap保证线程安全的方法

      HashTable也是县城安全的,他实现线程安全的方法是将整个数据结构进行加锁,所有访问HashTable的线程都要竞争同一把锁

      对于concurrentHashMap来说它是将锁容器中的一部分数据进行锁操作,当线程访问相应数据的时候,只需找到相应的锁并且进行加锁,get的操作阶段是不加锁的,只有当读到null值得时候才会加锁重读,put方法首先定位到segment,然后再segment中进行插入操作

8.String,StringBuffer,StringBuilder以及对String不变性的理解

String,StringBuffer,StringBuilder

      都是final类,都不允许被继承

      String长度是不可变的,StringBuffer和StringBuilder长度是可变的

     StringBuffer是线程安全的,StringBuilder是线程不安全的,两者中的方法基本上是相同的,StringBuffer在StringBuilder的方法上添加了synchronized修饰,保证线程安全

      如果一个String类型的字符串,在编译时就可以确定是一个字符串常量,则在编译完成后,字符串会自动拼接成一个常量

String不变性理解

      String类是被final进行修饰的,不能被继承

      在用+连接字符串时会创建新的字符串

9.String重写了Object的hashcode和toString方法吗?如果重写了equal不重写hashcode方法会出现什么问题

重写了

当equals方法被重写,通常有必要重写hashcode方法以维护hashcode的常规协定,该协定声明相对等的对象必须有相同的hashcode()

只重写了equals方法没有重写hashcode方法时会导致在存储散列集合是两个相同的uxiaing没有相同的hashcode,则在集合中将会存储两个值相同的对象,导致混淆

10.java序列化和反序列化

Java序列化定义

     将那些实现Serializable接口的对象转换为一个字节序列,并能在以后字节序列中完全恢复对象,序列化可以弥补不同操作系统之间的差异

如何实现序列化和反序列化

      实现序列化的方法

            实现Serializable接口

            为了保证安全性,可以使用transient关键字进行修饰不必序列化的属性

11.java实现多线程的方法和区别

实现多线程的方式

      继承thread类,重写run函数

      实现Runnable接口

      实现Callable接口

三种方式的区别

      实现Runnable接口可以避免java单继承特性而带来的局限;增加程序的健壮性,代码能够被多个线程共享,代码的数据是独立的

      继承thread类和实现runnable方法启动线程都是用start方法,然后jvm虚拟街将此方法放到就绪队列中,如果有处理机可用,则执行run方法

      实现callable接口要实现call方法,并且线程执行完毕后会有返回值,其他两种都是重写run方法,没有返回值

12.线程安全:不管多个线程怎样的执行顺序和优先级,或者wait,sleep等控制方式,如果一个类在多线程访问下运转一切正常,并且访问类不需要进行额外的同步处理或协调,那我们认为线程是安全的

如何保证线程安全:对变量使用volatile,对程序段进行加锁synchronized

13.多线程如何进行交互

Object中的方法wait,notify,notifyAll

14.多线程公用一个变量需要注意什么

当我们在线程对象中定义一个全局变量,run方法会修改该变量时,如果有多个线程同时使用该对象,那么会造成全局变量被修改

volatile变量每次被线程访问时,都强迫线程从内存中重读该变量的最新值,而当该变量发生修改变化时,也会强迫线程将最新的值刷新回主内存中

15.什么是线程池,如果让你设计一个动态大小的线程池,如何设计,应该有哪些方法?

就是实现创建若干个可执行的线程放入池中,需要的时候从池中获取线程不用进行创建,使用完毕后不需要销毁而是直接放回池中,从而减少创建和销毁线程对象的开销

16.java是否有内存泄漏和内存溢出

内存泄漏:分配出去的内存无法回收(不再使用的对象或者变量仍然占用内存),在java中内存泄漏就是存在一些被分配的对象(可达的确是无用的)无法被gc回收

内存溢出:程序要求的内存超出了系统所能分配的内存(比如栈满还入栈,出现上溢,栈空还出栈,出现下溢)

静态集合类,使用set,vector,hashmap等集合时需要特别注意,当这些集合被定义为静态时,由于他们的生命周期和应用程序一样,可能会发生内存泄漏

监听器,在创建监听器时没有释放会导致内存泄漏

连接数据库没有释放链接,也有可能出现内存泄漏

17.JVM垃圾处理方法(标记清楚、复制、标记整理)

标记-清除算法

      标记阶段:先通过所有分界点,标记所有从根节点开始的对象,未被标记的称为垃圾对象

      清除阶段:清除所有未标记的对象

复制算法

      将原有的内存空间分为两块,每次只能使用其中的一块,在垃圾回收时,将在内存中的存活对象复制到未使用的内存块中,然后清除正在使用的内存块中的所有对象

标记-整理算法

       标记阶段:同标记-清除算法

       整理阶段:将所有存活的对象压缩到内存的一段,之后清理边界的所有空间

18.JVM如何GC,新生代老年代持久代都存储哪些东西,以及各个区的作用

新生代:在方法中new一个对象,在这个方法调用完毕后,对象就会被回收,这是一个典型的新生代对象

老年代:在新生代中经历了N次垃圾回收后仍然存活的对象就会被放到老年代中,而且大对象直接进入老年代

永久带:就是方法区

19.什么时候进行MinGC,FullGC

MinGC:

      新生代中垃圾收集动作,采用的是复制算法

      对于较大的对象,在MinGC时直接进入老年代

FullGC

      发生在老年代的垃圾回收动作,采用的是标记整理/清除算法

      因为老年代的对象几乎都是在survivor区熬过来的,不会那么容易死锁,因此FullGC发生的次数不会有MinorGC那么频繁,且Time(FullGC)>Time(MinorGC)

20.GC用的可达性分析算法中,那些对象可以作为GCRoots对象

java虚拟机栈中的对象

方法区中的静态成员

方法区中的常量引用对象

本地方法区中的引用对象

21.java虚拟机内存划分,每个区域功能

虚拟机栈:线程私有,栈内存为虚拟机执行java方法服务:方法被调用时创建栈帧->局部变量表->局部变量,对象引用

                  如果线程请求的栈深度超出了虚拟机所允许的深度,就会出现StackOverFlowError.-Xss规定了栈的空间

                  虚拟机栈可以动态扩展,如果扩展到无法申请足够的内存,会出现OOM

本地方法栈:线程私有,Java虚拟机栈是为虚拟机执行java方法服务的

                      Java虚拟机没有对本地方法栈和数据结构做强制规定

                       会抛出StackOverFlowError和OutOfMemoryError

java堆:被所有线程共享,在java虚拟机启动时创建,几乎所有对象实例都存放到堆中

              GC的管理的主要区域

               物理不连续,逻辑上连续,并可以动态扩展,无法扩展时抛出OutOfMemoryError异常

方法区:用于存储已被虚拟机加载的类信息,常量和静态变量

运行时常量池:受到方法区的限制,抛出OutOfMemory异常

程序计数器:线程私有,线程创建时创建,执行本地方法时其值为undefined

22.JVM线程死锁,如何判断是因为什么

常常需要在隔两分钟再收集一次thread dump,如果得到的输出相同,仍然是大量thread都在等待给同一个地址上锁,那么肯定是死锁

23.java如何对对象进行实例化?

先为对象分配空间,并按照属性类型进行初始化

父类属性进行初始化

父类构造函数初始化

子类属性初始化

子类构造函数初始化

24.Student s = new Student()在内存中做了哪些事情

加载student.class文件进内存

在栈内存为s开辟空间

在堆内存为学生对象开辟空间

对学生对象的成员变量进行默认初始化

对学生成员变量进行显式初始化

通过构造方法对学生对象的成员变量赋值

学生对象初始化完毕,把对象地址赋值给s变量

25.Servlet生存周期

servlet接口定义了3个方法,其中三个方法与Servlet生命周期相关

      void init(ServletConfig config) throws ServletException

      void service(ServletRequest req, ServletResponse resp) throws ServletException,IOException

      void destory()

26.jsp与sevlet的区别

Servlet是一类特殊的Java程序,它运行于服务器的JVM中,能够依靠服务器的支持向浏览器提供显示的内容,JSP实际上是Servlet的一种简易形式,JSP会被服务器处理成类似于Servlet的java程序,可以简化页面内容的生成。Servlet和jsp的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML分离开来,而JSP的情况是java和html组成一个扩展名为jsp的文件。即JSP注重于视图,servlet更侧重于逻辑

27.cookie和session的区别

session在服务器端,cookie在客户端

session的运行依赖sessionId,而sessionId是存在在cookie中的,也就是说如果浏览器禁用了cookie的话,session也会失效

session可以放在文件数据库或内存中

cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全性应该用session

session会在一定时间内保存到服务器中。当访问量增多,会比较占用你的服务器的性能,考虑到减轻服务器性能方面应该用cookie

单个cookie保存的数据不超过4K,很多浏览器都限制一个站点做多保存20个cookie

29.SpringIOC,AOP的理解以及实现原理?

SpringIOC

      ioc叫做控制反转,DI叫做依赖注入,是对IOC更简单的诠释,控制反转是把传统上用程序代码直接操作的对象的调用权交给容器,通过容器来实现对象组件的装配和管理,所谓的控制反转就是对组件对象控制权的转移,重程序代码本身转移到外部容器,由容器来创建对象并管理对象之间的依赖关系。DI是对IOC的更准确的描述

实现原理

      通过反转创建实例

      获取需要注入的接口实现类并将其赋值给该接口

30.类和对象

类是对象的抽象,对象是类的实例

类  对象 = new  类()

可以通过对象操作这个类里的方法

类是一个抽象的概念,它不存在与现实的时间或者空间里,类只是为所有对象定义一个抽象的属性与行为

对象是类的一个具体。它是实实在在存在的一个东西

类是一个静态的概念,类本身不携带任何数据,当没有为类创建对象时,类本身不存在与内存空间中

对象是一个动态的概念,每个对象都存在有别于其他对象的数据自己的属性和行为。对象的属性可以随着他自己的行为而发生改变

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值