java基础面试知识点

(一)java基础面试知识点

  1,java中==和equals和hashCode的区别

  答:1)“==”运算符用来比较两个变量的值是否相等。    

      2)equals是Object类提供的方法之一。每一个Java类都集成自Object类,所以每一个对象都具有equals这个方法。Object类中定义的equals(Object)方法的情况下,equals(Object)与“==”运算符一样,比较的是引用。

     3)hashCode()方法是从Object类中继承过来的,它也用来鉴定两个对象是否相等。Object类中的hashCode()方法返回对象在内存中地址转换成的一个int值,所以如果没有重写hashCode()方法,任何对象的hashCode()方法都是不相等的。

 2,int、char、long各占多少字节数

1:“字节”是byte,“位”是bit ;

2: 1 byte = 8 bit ;

    char 在java中是2个字节。

       java采用unicode,2个字节(16位)来表示一个字符。

       short 2个字节

       int 4个字节
       long 8个字节
 

3,int与integer的区

1、Integer是int的包装类,int则是java的一种基本数据类型 
2、Integer变量必须实例化后才能使用,而int变量不需要 
3、Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值 
4、Integer的默认值是null,int的默认值是0
4,谈谈对java多态的理解

实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。

多态的作用:消除类型之间的耦合关系。

多态的实现必要条件:继承,重写,父类引用指向子类对象(即,声明是父类,实际指向的是子类的一个对象

5,String、StringBuffer、StringBuilder的区别

String 字符串常量
StringBuffer 字符串变量(线程安全)

StringBuilder 字符串变量(非线程安全)

1.首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String

2.再来说线程安全,在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的

3. 总结一下 

String:适用于少量的字符串操作的情况  

StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况

StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

6,什么是内部类?内部类的作用

内部类( Inner Class )就是定义在另外一个类里面的类。与之对应,包含内部类的类被称为外部类。

内部类的主要作用如下:

1. 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类

2.内部类的方法可以直接访问外部类的所有数据,包括私有的数据

3. 内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便

内部类可分为以下几种:

7,抽象类和接口的区别

1、相同点
     A. 两者都是抽象类,都不能实例化。
     B. interface实现类及abstrct class的子类都必须要实现已经声明的抽象方法。

2.、不同点
     A. interface需要实现,要用implements,而abstract class需要继承,要用extends
     B. 一个类可以实现多个interface,但一个类只能继承一个abstract class
     C. interface强调特定功能的实现,而abstract class强调所属关系。 
    D. 尽管interface实现类及abstrct class的子类都必须要实现相应的抽象方法,但实现的形式不同。interface中的每一个方法都是抽象方法,都只是声明的(declaration, 没有方法体),实现类必须要实现。而abstract class的子类可以有选择地实现。

8,抽象类的意义

抽象类往往用来表征对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。具体分析如下:
1.因为抽象类不能实例化对象,所以必须要有子类来实现它之后才能使用。这样就可以把一些具有相同属性和方法的组件进行抽象,这样更有利于代码和程序的维护。
比如本科和研究生可以抽象成学生,他们有相同的属性和方法。这样当你对其中某个类进行修改时会受到父类的限制,这样就会提醒开发人员有些东西不能进行随意修改,这样可以对比较重要的东西进行统一的限制,也算是一种保护,对维护会有很大的帮助。
2.当又有一个具有相似的组件产生时,只需要实现该抽象类就可以获得该抽象类的那些属性和方法。

9,抽象类与接口的应用场景

interface(接口)的应用场合
     A. 类与类之前需要特定的接口进行协调,而不在乎其如何实现。
     B. 作为能够实现特定功能的标识存在,也可以是什么接口方法都没有的纯粹标识。
     C. 需要将一组类视为单一的类,而调用者只通过接口来与这组类发生联系。

     D. 需要实现特定的多项功能,而这些功能之间可能完全没有任何联系。

abstract class(抽象类)的应用场合
      一句话,在既需要统一的接口,又需要实例变量或缺省的方法的情况下,就可以使用它。最常见的有:
      A. 定义了一组接口,但又不想强迫每个实现类都必须实现所有的接口。可以用abstract class定义一组方法体,甚至可以是空方法体,然后由子类选择自己所感兴趣的方法来覆盖。
      B. 某些场合下,只靠纯粹的接口不能满足类与类之间的协调,还必需类中表示状态的变量来区别不同的关系。abstract的中介作用可以很好地满足这一点。
      C. 规范了一组相互协调的方法,其中一些方法是共同的,与状态无关的,可以共享的,无需子类分别实现;而另一些方法却需要各个子类根据自己特定的状态来实现特定的功能

10,抽象类是否可以没有方法和属性?

1,java允许类、接口或者成员方法具有抽象属性,但不允许成员域或者构造方法具有抽象属性

2,如果一个类不具有抽象属性,则不能在该类的类体中定义抽象成员方法

11,接口的意义

定义代码规范,抽象业务属性简化开发复杂度,使项目具备扩展性

12,泛型中extends和super的区别

  1. <? extends T> 只能用于方法返回,告诉编译器此返参的类型的最小继承边界为T,T和T的父类都能接收,但是入参类型无法确定,只能接受null的传入
  2. <? super T>只能用于限定方法入参,告诉编译器入参只能是T或其子类型,而返参只能用Object类接收
  3. ? 既不能用于入参也不能用于返参

13,父类的静态方法能否被子类重写

父类的静态方法不能被子类继承,更谈不上重写,就算是子类中有一个和父类一模一样的静态方法,那也是子类本身的,和父类的那个静态方法不是一回事。方法加静态后就属于类不属于对象了。

14,进程和线程的区别

操作系统面试题

1、进程和线程的区别?
解析:(1)进程是资源的分配和调度的一个独立单元,而线程是CPU调度的基本单元
          (2)同一个进程中可以包括多个线程,并且线程共享整个进程的资源(寄存器、堆栈、上下文),一个进程至少包括一个线程。
          (3)进程的创建调用fork或者vfork,而线程的创建调用pthread_create,进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程的结束
          (4)线程是轻两级的进程,它的创建和销毁所需要的时间比进程小很多,所有操作系统中的执行功能都是创建线程去完成的
          (5)线程中执行时一般都要进行同步和互斥,因为他们共享同一进程的所有资源
          (6)线程有自己的私有属性TCB,线程id,寄存器、硬件上下文,而进程也有自己的私有属性进程控制块PCB,这些私有属性是不被共享的,用来标示一个进程或一个线程的标志
2、死锁?死锁产生的原因?死锁的必要条件?怎么处理死锁?
解析:(--)相互等待资源而产生的一种僵持状态,如果没有外力的干预将一直持续这个状态
          (--)系统资源不足、相互竞争资源、请求资源顺序不当
          (2) 互斥、不可抢占、循环等待、请求与保持
          (3)因为互斥是不可改变的,所以只能破坏其他三个条件中的一个来解除死锁,方法:剥夺资源、杀死其中一个线程
3、Windows内存管理方式:段存储、页存储、段页存储
解析:
4、进程的几种状态?
解析:(1)run(运行状态):正在运行的进程或在等待队列中对待的进程,等待的进程只要以得到cpu就可以运行
          (2)Sleep(可中断休眠状态):相当于阻塞或在等待的状态
          (3)D(不可中断休眠状态):在磁盘上的进程
          (4)T(停止状态):这中状态无法直观的看见,因为是进程停止后就释放了资源,所以不会留在linux中
          (5)Z(僵尸状态):子进程先与父进程结束,但父进程没有调用wait或waitpid来回收子进程的资源,所以子进程就成了僵尸进程,如果父进程结束后任然没有回收子进程的资源,那么1号进程将回收
5、IPC通信方式?
解析:(1)管道(匿名管道(pipe亲缘关系的进程通信)、命名管道(mkfifo/mknod))
          (2)消息队列:是基于消息的、用无亲缘关系的进程间通信,主要函数:msgget、msgsend、msgrecv、msgctl
          (3)信号量:相当于一把互斥锁,通过p、v操作,主要函数:semget、semop、semctl
          (4)共享内存:是进程间通信速度最快的,所以用经常是集合信号量或互斥锁来实现同步,shmget、shmat、shmdt、shmctl
6、什么是虚拟内存?
解析:是将进程部分装入内存中,从而能实现一个很大的程序能在一个比它小的内存中运行,它的主要实现是靠程序的换进换出来实现的,因为内存中0~3G是用户使用,3~4G才是内存使用,通过映射来实现来进行逻辑地址到物理地址的映射

7、虚拟地址、逻辑地址、线性地址、物理地址的区别?
解析:  分段机制把一个逻辑地址转换为线性地址;接着,分页机制把一个线性地址转换为物理地址
(1)虚拟地址:虚拟内存映射出来的地址
(2)逻辑地址:程序的段加偏移量形成的,C/C++程序中取地址求出来的地址就是逻辑地址
(3)线性地址:是逻辑地址到物理地址的中间层,只有启动分页机制的时候才有线性地址,如果没有分页机制,那么线性地址就是物理地址
(4)物理地址:是内存中实实在在存在的硬件地址,
逻辑地址(启动分段)--》线性地址(启动分页)--》物理地址

一:进程与线程

概述几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程。当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是一个线程

 进程进程是指处于运行过程中的程序,并且具有一定的独立功能。进程是系统进行资源分配和调度的一个单位。当程序进入内存运行时,即为

 进程的三个特点:

1:独立性:进程是系统中独立存在的实体,它可以独立拥有资源,每一个进程都有自己独立的地址空间,没有进程本身的运行,用户进程不可以直接访问其他进程的地址空间。

2:动态性:进程和程序的区别在于进程是动态的,进程中有时间的概念,进程具有自己的生命周期和各种不同的状态

3:并发性:多个进程可以在单个处理器上并发执行,互不影响

 并发性和并行性是不同的概念:并行是指同一时刻,多个命令在多个处理器上同时执行;并发是指在同一时刻,只有一条命令是在处理器上执行的,但多个进程命令被快速轮换执行,使得在宏观上具有多个进程同时执行的效果

线程:

线程是进程的组成部分,一个进程可以拥有多个线程而一个线程必须拥有一个父进程线程可以拥有自己的堆栈,自己的程序计数器和自己的局部变量,但不能拥有系统资源。它与父进程的其他线程共享该进程的所有资源

线程的特点

线程可以完成一定任务,可以和其它线程共享父进程的共享变量和部分环境,相互协作来完成任务。

线程是独立运行的,其不知道进程中是否还有其他线程存在。

线程的执行是抢占式的,也就是说,当前执行的线程随时可能被挂起,以便运行另一个线程。

一个线程可以创建或撤销另一个线程,一个进程中的多个线程可以并发执行。

线程和进程之间的详细描述:

https://www.cnblogs.com/WJ-163/p/6261835.html

15,final,finally,finalize的区别

     Final用于修饰类、成员变量和成员方法。

Final修饰的类,不能被继承(StringStringBuilderStringBufferMath,不可变类),其中所有的方法都不能被重写,所以不能同时用abstract和Final修饰类(abstract修饰的类是抽象类,抽象类是用于被子类继承的,和final起相反的作用);

Final修饰的方法不能被重写,但是子类可以用父类中final修饰的方法;

Final修饰的成员变量是不可变的,如果成员变量是基本数据类型,初始化之后成员变量的值不能被改变,

如果成员变量是引用类型,那么它只能指向初始化时指向的那个对象,不能再指向别的对象,但是对象当中的内容是允许改变的。

    Finally通常和try catch搭配使用,保证不管有没有发生异常,资源都能够被释放(释放连接、关闭IO流)。

    Finalize是object类中的一个方法,子类可以重写finalize()方法实现对资源的回收。垃圾回收只负责回收内存,并不负责资源的回收,资源回收要由程序员完成,Java虚拟机在垃圾回收之前会先调用垃圾对象的finalize方法用于使对象释放资源(如关闭连接、关闭文件),之后才进行垃圾回收,这个方法一般不会显示的调用,在垃圾回收时垃圾回收器会主动调用。

16,序列化的方式

Android开发中的序列化有两种方法。

1,实现Serializable接口

2,实现Parcelable接口

17,Serializable和Parcelable的区别

1、作用

Serializable的作用是为了保存对象的属性到本地文件、数据库、网络流、rmi以方便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。而Android的Parcelable的设计初衷是因为Serializable效率过慢,为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable是通过IBinder通信的消息的载体。

2、效率及选择

Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据,而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化

3、编程实现

对于Serializable,类只需要实现Serializable接口,并提供一个序列化版本id(serialVersionUID)即可。而Parcelable则需要实现writeToParcel、describeContents函数以及静态的CREATOR变量,实际上就是将如何打包和解包的工作自己来定义,而序列化的这些操作完全由底层实现

18,静态属性和静态方法是否可以被继承?是否可以被重写?以及原因?

  1. java中静态属性和静态方法可以被继承,但是没有被重写(overwrite)而是被隐藏.  
  2. 原因:  
  3. 静态方法和属性是属于类的,调用的时候直接通过类名.方法名完成对,不需要继承机制就可以调用。如果子类里面定义了静态方法和属性,那么这时候父类的静态方法或属性称之为"隐藏"。如果你想要调用父类的静态方法和属性,直接通过父类名.方法或变量名完成,至于是否继承一说,子类是有继承静态方法和属性,但是 跟实例方法和属性不太一样,存在"隐藏"的这种情况。  
  4. 多态之所以能够实现依赖于继承、接口和重写、重载(继承和重写最为关键)。有了继承和重写就可以实现父类的引用指向不同子类的对象。重写的功能是:"重写"后子类的优先级要高于父类的优先级,但是“隐藏”是没有这个优先级之分的。  
  5. 静态属性、静态方法和非静态的属性都可以被继承和隐藏而不能被重写,因此不能实现多态,不能实现父类的引用可以指向不同子类的对象。非静态方法可以被继承和重写,因此可以实现多态。 

19,静态内部类的设计意图

在java中类是单继承的,一个类只能继承另一个具体类或抽象类(可以实现多个接口)。这种设计的目的是因为在多继承中,当多个父类中有重复的属性或者方法时,子类的调用结果会含糊不清,因此用了单继承。

而使用内部类的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。

        在我们程序设计中有时候会存在一些使用接口很难解决的问题,这个时候我们可以利用内部类提供的、可以继承多个具体的或者抽象的类的能力来解决这些程序设计问题。可以这样说,接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整。

20,成员内部类、静态内部类、局部内部类和匿名内部类的理解,以及项目中的应用

成员内部类

       成员内部类也是最普通的内部类,它是外围类的一个成员,所以它可以无限制的访问外围类的所有成员属性和方法,尽管是private的,但是外围类要访问内部类的成员属性和方法则需要通过内部类实例来访问。

在成员内部类中要注意两点:

  • 成员内部类中不能存在任何static的变量和方法;

  • 成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类。

静态内部类

     没有这个引用就意味着:

  • 它的创建是不需要依赖于外围类的。

  • 它不能使用任何外围类的非static成员变量和方法。

静态内部类与非静态内部类之间存在一个最大的区别:非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围内,但是静态内部类却没有。

局部内部类

      局部内部类是嵌套在方法和作用于内的,对于这个类的使用主要是应用与解决比较复杂的问题,想创建一个类来辅助我们的解决方案,到那时又不希望这个类是公共可用的,所以就产生了局部内部类,局部内部类和成员内部类一样被编译,只是它的作用域发生了改变,它只能在该方法和属性中被使用,出了该方法和属性就会失效。

匿名内部

1、匿名内部类是没有访问修饰符的。

2、new 匿名内部类,这个类首先是要存在的。

3、当所在方法的形参需要被匿名内部类使用,那么这个形参就必须为final。

4、匿名内部类没有明面上的构造方法,编译器

21,谈谈对kotlin的理解

Kotlin好处都有啥:

  • 个人觉得最重要的一点是思维观念。特别是在没学Java 8 的函数式之前先学会Kotlin的各种扩展/高阶函数的用法,感受就完全不一样。很多时候的需求只要不是太过于特定的话基本上靠forEach,map,filter几个都能很好的理解。思维和写代码不会被 写循环 的这个过程打断,写Java你可能写上循环以后就容易迷。用过Kotlin以后再回来用Java8发现Java8的这也太小儿科了。
  • 语法糖方面,Kotlin的语法糖算是比较人性化的。
    • 用var和val可以省略一次类型的写法。对于一些类型来说我们真没必要多写。其实我个人还是比较喜欢Scala/Groovy那样既能写类型也可以写关键字的方式的声明变量。不过我居然是在用了C#以后发现似乎类型还真没写几次。另外这里强烈建议可以把IDEA里面Kotlin的类型声明用hint显示出来。
    • 扩展方法:个人觉得Kotlin大概是我已知的有扩展方法的编程语言里面写起来最顺手的一个了。和声明一个普通函数的区别就在于多了个 类型. 。比起C#要写几个public static 再加一个this 再类型变量,喵喵喵?我为了用一个扩展还要多写出这么多东西?然后我就会被C升厨喷糖酸emmmm。然后js的话毕竟本身就很灵活直接类型.prototype.funcName,还行吧。Scala的话写起来也是要单独再搞一个类再用implict总有种暴露我智商低无法接受的感觉……以我的智商只会躺在kotlin里面了。
    • 高阶函数(also,apply,let这几个)。能用好高阶函数也是很棒的。比如apply应该有借鉴C#的构造函数的初始化成员赋值写法的,但是可以做更多的事情啊,做完了他自己的事情再返回本身。
    • 可迭代接口就能用到的扩展(上面提到的forEach,map,filter等几个)。自从有了这么些个扩展,彻底成了 it 爱好者协会。虽然it其实是iterator的意思,但是其实当做it来看也是很棒的。意思是你不需要考虑单参数的参数名字,大胆上it。有多个嵌套一起用的时候再重命名。
    • 写了这么久突然发现还没写到空安全。有没有大括号的区别,了解一下。你们知道julia标准库那些人丧心病狂到什么程度吗,为了不搞括号,有简单的if return的判断就直接用 || 和&&来搞定……大括号一层一层嵌套进去对于代码来是一种灾难啊,但是如果用链式调用那种大括号就会好很多(一堆forEach的那种)【?.只写一个两个的时候体验还是挺不错的。。但是如果写成一堆的 ?. 感觉是其实也是很烦的】

22,闭包和局部内部类的区别

闭包是一个可调用的对象,它记录了一些信息,这些信息来自于创建它的作用域。通过这个定义,可以看出内部类是面向对象的闭包,因为它不仅包含创建内部类的作用域的信息,还自动拥有一个指向此外围类对象的引用,在此作用域内,内部类有权操作所有的成员,包括private成员。
---摘抄自《Java编程思想》P205,10.8.1

23,string转换成integer的方式及原理

String str = "...";

Integer integer = null;

if(str!=null){

i = Integer.valueOf(str);

}

当我们要把String转化为Integer时,一定要对String进行非空判断,否则很可能报空指针异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值