Java面试题

什么是面向对象?

对比面向过程,是两种不同的处理问题的角度 。
面向过程更注重事情的每一个步骤及顺序,面向对象更注重事情有哪些参与者(对象)、及各自需要做什么,通过指挥对象实现功能。面向对象实际是基于面向过程的。通俗一点来说,对象中的方法就是过程。
面向对象的三大特性:
封装 :封装的意义,在于明确标识出允许外部使用的所有成员函数和数据项,内部细节对外部调用透明,外部调用无需修改或者关心内部实现
继承 :继承基类的方法,并做出自己的改变和 / 或扩展。子类共性的方法或者属性直接使用父类的,而不需要自己再定义,只需扩展自己个性化的,是多态的前提
多态父类或接口定义的引用变量可以指向子类或具体实现类的实例对象
类和对象的关系?

类和对象的关系

客观存在的事物皆为对象 ,所以我们也常常说万物皆对象。

类的理解

  • 类是对现实生活中一类具有共同属性和行为的事物的抽象

  • 类是对象的数据类型,类是具有相同属性和行为的一组对象的集合

  • 简单理解:类就是对现实事物的一种描述

类的组成

  • 属性:指事物的特征,例如:手机事物(品牌,价格,尺寸)

  • 行为:指事物能执行的操作,例如:手机事物(打电话,发短信)

类和对象的关系

  • 类:类是对现实生活中一类具有共同属性和行为的事物的抽象

  • 对象:是能够看得到摸的着的真实存在的实体

  • 简单理解:类是对事物的一种描述,对象则为具体存在的事物,通过类来创建一个对象

成员变量和局部变量的区别

类中位置不同 成员变量(类中方法外)局部变量(方法内部或方法声明上)
内存中位置不同 成员变量(堆内存)局部变量(栈内存)
生命周期不同 成员变量(随着对象的存在而存在,随着对象的消失而消失)局部变量(随着方法的调用而 存在,醉着方法的调用完毕而消失)
初始化值不同 成员变量(有默认初始化值)局部变量(没有默认初始化值,必须先定义,赋值才能使用)

类的构造方法

格式:
1. 方法名需要跟类名相同, 大小写也要一致
2. 没有返回值类型, 连void都没有
3. 没有具体的返回值(不能由return带回具体的结果)
注意事项:
如果没有给一个类显示的创建一个构造方法,那么jvm会自动给他创建一个默认的无参构造方法,如果创建了一个带参构造方法,那么jvm就不会再提供默认的空参构造方法

什么是方法重载?

在一个类中,方法名相同,参数类型或者参数个数不同,就属于方法重载。

==和equals比较

==比较的是栈中的值,基本数据类型的值在栈中,而引用数据类型存放在栈中的是堆中的地址

而Object的equals默认采用的也是==,但是String类的Object对其进行了重写,先比较字符串的长度是否相等,如果相等在比较内容是否相等

final修饰类、成员变量、局部变量、局部内部类和匿名内部类

  • final修饰类表示类不能被继承
  • final修饰方法表示类不能被重写覆盖,但是可以重载
  • final修饰变量一旦变量被复制就不能改变它的值,这一点需要具体分析
  1. 当修饰类变量的时候(静态成员变量),只能在静态代码块中对其进行初始化,或者声明变量的时候指定初始值。
  2. 如果 final 修饰的是成员变量,可以在非静态初始化块、声明该变量或者构造器中执行初始值。
  3. 修饰局部变量可以在声明变量的时候进行初始化,也可以不指定值,等到用到的时候再指定值,但是只能指定一次。
  4. 如果修饰的是基本类型值一旦确定就不能够修改
  5. 如果修饰的是引用类型,那么指定对象之后就不能再指向另一个对象,但是对象的内容可以改变
  • 为什么局部内部类和匿名内部类只能访问局部 final 变量?
首先需要知道的一点是 : 内部类和外部类是处于同一个级别的,内部类不会因为定义在方法中就会随着 方法的执行完毕就被销毁。
这里就会产生问题:当外部类的方法结束时,局部变量就会被销毁了,但是内部类对象可能还存在 ( 只有 没有人再引用它时,才会死亡) 。这里就出现了一个矛盾:内部类对象访问了一个不存在的变量。为了解 决这个问题,就将局部变量复制了一份作为内部类的成员变量,这样当局部变量死亡后,内部类仍可以访问它,实际访问的是局部变量的"copy"。这样就好像延长了局部变量的生命周期。 将局部变量复制为内部类的成员变量时,必须保证这两个变量是一样的,也就是如果我们在内部类中修 改了成员变量,方法中的局部变量也得跟着改变,怎么解决问题呢?
就将局部变量设置为 final ,对它初始化后,我就不让你再去修改这个变量,就保证了内部类的成员变量 和方法的局部变量的一致性。这实际上也是一种妥协。使得局部变量与内部类内建立的拷贝保持一致。

String、StringBuffer、StringBuilder

  • Stringfinal修饰的,不可变,每次操作都会产生新的String对象
  • StringBufferStringBuilder都是在原对象上操作
  • StringBuffer是线程安全的,StringBuilder线程不安全的
  • StringBuffer方法都是synchronized修饰的
  • 性能:StringBuilder > StringBuffer > String
  • 场景:经常需要改变字符串内容时使用后面两个
  • 优先使用StringBuilder,多线程使用共享变量时使用StringBuffer

重载和重写的区别

重载: 发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问 修饰符可以不同,发生在编译时。
重写: 发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于 等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为private 则子类就不能重写该方 法。

集合的体系结构

集合首先分为两种:单列集合,键值对集合。

单列集合的基类是collection,而键值对集合的基类是Map

先说说单列集合collection的子类

— List 有序,可重复

ArrayList
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程不安全,效率高
Vector
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程安全,效率低
LinkedList
优点: 底层数据结构是链表,查询慢,增删快。
缺点: 线程不安全,效率高

—Set 无序,唯一

HashSet
底层数据结构是哈希表。(无序,唯一)
如何来保证元素唯一性?
1.依赖两个方法:hashCode()和equals()

LinkedHashSet
底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
1.由链表保证元素有序
2.由哈希表保证元素唯一

TreeSet
底层数据结构是红黑树。(唯一,有序)
1. 如何保证元素排序的呢?
自然排序
比较器排序
2.如何保证元素唯一性的呢?
根据比较的返回值是否是0来决定
 

小汇总(使用方法):如果需要保证唯一,就是用set的子类,如果不用排序就选择hashset,如果需要排序就选择linkedset或者treeset

如果不需要保证唯一,可以使用List的子类,需要保证线程安全,就选Vector,如果不需要保证线程安全就选ArrayList或者LinkedList,根据实际情况选择。

Map接口:

ap接口有三个比较重要的实现类,分别是HashMap、TreeMap和HashTable。

  • TreeMap是有序的,HashMap和HashTable是无序的。
  • Hashtable的方法是同步的,HashMap的方法不是同步的。这是两者最主要的区别。

List和Set集合的区别

List和Set集合都继承至collection

List :有序,按对象进入的顺序保存对象,可重复,允许多个 Null 元素对象,可以使用 Iterator 取出
所有元素,在逐一遍历,还可以使用 get(int index) 获取指定下标的元素
Set :无序,不可重复,最多允许有一个 Null 元素对象,取元素时只能用 Iterator 接口取得所有元
素,在逐一遍历各个元素

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值