面试java基础

Java运行机制

Java程序运行时,必须经过编译和运行两个步骤。首先将后缀名为Java的源文件进行编译,最终生成后缀名为.class的字节码文件。然后Java虚拟机将字节码文件进行解释执行,并将结果显示出来。

①编写一个 Hello world.Java的文件。

②使用“Javac Hello world.Java”命令开启Java编译器并进行编译。编译结束后,会自动生成一个Hello World. class的字节码文件

③使用“ Java Hello world”命令启动Java虚拟机运行程序,Java虚拟机首先将编译好的字节码文件加载到内存,这个过程被称为类加载,它是由类加载器完成的,然后虚拟机对加都到内在中的Java类进行解释执行,便可看到运行结果。

数据类型

Int和Integer有什么区别?

int是基本类型,直接存数值,而integer是对象,用一个引用指向这个对象.integer是int的包装类型,在拆箱和装箱中,二者自动转换.

拆箱和装箱:

String 和StringBuffer的区别

String类提供了数值不可改变的字符串。StringBuffer类提供的字符串进行修改。

基本数据类型

byte、int、char、long、float、double、boolean和short。

请你讲讲数组(Array)和列表(ArrayList)的区别?什么时候应该使用Array而不是ArrayList?

Array和ArrayList的不同点:
Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
Array大小是固定的,ArrayList的大小是动态变化的。
ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。

关键字
final:静态的

修饰类时候,表明不能被继承,类中的成员方法也不能被调用;修饰成员变量

对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。

面向对象

请解释Java中的概念,什么是构造函数?什么是构造函数重载?

构造函数:构造函数定义的是,对象在调用功能之前,在建立时,应该具备的一些内容。也就是对象的初始化内容。构造函数是在对象建立时由 jvm 调用, 给对象初始化。一般函数是对象建立后,当对象调用该功能时才会执行。

构造函数重载 主要作用在参数上 参数的类型,个数不一样

请你谈一下面向对象的原则

单一职责原则:一个类只做它该做的事情。

开闭原则:软件实体应当对扩展开放,对修改关闭。

依赖倒转原则:面向接口编程。

请说明内部类可以引用他包含类的成员吗,如果可以,有没有什么限制吗?

一个内部类对象可以访问创建它的外部类对象的内容,内部类如果不是static的,那么它可以访问创建它的外部类对象的所有属性内部类如果是sattic的,即为nested class,那么它只可以访问创建它的外部类对象的所有static属性一般普通类只有public或package的访问修饰,而内部类可以实现static,protected,private等访问修饰。当从外部类继承的时候,内部类是不会被覆盖的,它们是完全独立的实体,每个都在自己的命名空间内,如果从内部类中明确地继承,就可以覆盖原来内部类的方法。

请说明JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?

try-catch-finally 抓抛模型

throw语句用来明确地抛出一个”异常”。throws用来标明一个成员函数可能抛出的各种”异常”。

请你讲讲abstract class和interface有什么区别?

声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。抽象类就是里面也可以定义方法,但是不能创建对象使用。

接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。

请说明面向对象的特征有哪些方面

封装:类和方法其实都是封装,封装的好处有提高了代码的复用性,隐藏了实现的细节,提高了安全性

继承:让类与类之间产生关系,为多态打下基础,若一个新类继承了原有类的属性和方法,并增加了自己的新属性和新方法,称之为派生类

多态:一个接口,多个方法。通过继承实现的不同对象调用相同的方法,进而有不同的行为

集合

请说明List、Map、Set三个接口存取元素时,各有什么特点?

List以特定索引来存取元素,可以有重复元素。Set不能存放重复元素(用对象的equals()方法来区分元素是否重复)。Map保存键值对(key-value pair)映射,映射关系可以是一对一或多对一。Set和Map容器都有基于哈希存储和排序树的两种实现版本,基于哈希存储的版本理论存取时间复杂度为O(1),而基于排序树版本的实现在插入或删除元素时会按照元素或元素的键(key)构成排序树从而达到排序和去重的效果。

请讲讲你所知道的常用集合类以及主要方法?

最常用的集合类是List 和 Map。

List 的具体实现包括 ArrayList 和 Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。List 适用于按数值索引访问元素的情形。

Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作"键"和"值"),其中每个键映射到一个值。

请你说明HashMap和Hashtable的区别?

HashMap和Hashtable都实现了Map接口,因此很多特性非常相似。但是,他们有以下不同点:
HashMap允许键和值是null,而Hashtable不允许键或者值是null。
Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。
HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。另一方面,Hashtable提供了对键的列举(Enumeration)。
一般认为Hashtable是一个遗留的类。

线程

线程的概念:

每个运行的程序都是一个进程,在一个进程中还可以有多个执行单元同时运行,这些执行单元可以看作程序执行的一条条线索,被称为线程。操作系统中的每一个进程中都至少存在一个线程。当一个Java程序启动时,就会产生一个进程,该进程会默认创建一个线程,在这个线程上会运行main()方法中的代码。

线程的创建和实现:

在JAVA中,用Thread类代表线程,所有线程对象,都必须是Thread类或者Thread类子类的实例。每个线程的任务就是执行一段顺序执行的代码,JAVA使用线程执行体来容纳这段代码。所以,我们创建线程时,主要是根据实际需求,编写放入线程执行体的代码。

  1. 通过继承Thread类创建线程类

    定义一个类继承Thread类,并重写Thread类的run()方法,run()方法的方法体就是线程要完成的任务,因此把run()称为线程的执行体。

    创建该类的实例对象,即创建了线程对象。

    调用线程对象的start()方法来启动线程。

  2. 通过实现Runnable接口创建线程类

    定义一个类实现Runnable接口 这个类里面实现run()方法。

    创建该类的实例对象obj。

    将obj作为构造器参数传入创建的Thread类实例对象中,这个对象才是真正的线程对象,然后用这个对象使用.start()调用。

线程的生命周期

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GtZy0lgu-1593404537201)(E:\笔记整理\Typora\java面试\面试准备图片\image-20200623192536554.png)]

  • 新建状态

    创建一个线程对象后,该线程对象就处于新建状态,此时它不能运行,只分配了内存。

  • 就绪状态

    当线程对象调用了start()方法后, 该线程就进人就绪状态(也称可运行状态)。处于就绪状态的线程位于可运行池中,此时它只是具备了运行的条件,能否获得CPU的使用权开始运行,还需要等待系统的调度。

  • 运行状态

    如果处于就绪状态的线程获得了CPU的使用权,开始执行run()方法中的线程执行体,则该线程处于运行状态。

  • 阻塞状态

    一个正在执行的线程在某些特殊情况下,如执行耗时的输人/输出操作时,会弃CPU的使用权,进人阻塞状态。

  • 死亡状态

    线程的run()方法正常执行完毕或者线程抛出一个未捕获的异常(Exception)、错误(Error) ,线程就进人死亡状态。-旦进人死亡状态,线程将不再拥有运行的资格,也不能再转换到其他状态。

  1. 线程休眠

sleep(longmillis),该方法可以让当前正在执行的线程暂停–段时间,进人休眠等待状态。当前线程调用sleep(longmillis)方法后,在指定时间(参数millis)内是不会执行的,这样其他的线程就可以得到执行的机会了。sleep( long millis) 方法声明抛出InterruptedException 异常,因此在调用该方法时应该捕获异常,或者声明抛出该异常。时间长短决定休眠时间。

  1. 线程让步

Java程序中的线程让步可以通过yield()方法来实现,该方法和sleep()方法有点相似,都可以让当前正在运行的线程暂停,区别在于yield()方法不会阻塞该线程,它只是将线程转换成就绪状态,让系统的调度器重新调度-一次。当某个线程调用yield()方法之后,只有与当前线程优先级相同或者更高的线程才能获得执行的机会。

  1. 线程插队

Thread类中也提供了一个join()方法来实现线程插队。当在某个线程中调用其他线程的join()方法时,调用的线程将被阻塞,直到被join()方法加入的线程执行完成后它才会继续运行。

线程安全问题

安全问题的产生:由多个线程同时处理共享资源所导致的。

解决:保证处理共享资源的代码在任何时刻只能有一个线程访问。

  • 同步代码块

    synchronized(lock){

    操作共享资源代码块 //这个lock锁 是一个关键标志 默认情况标志为1 表示执行

    }

  • 同步方法

    使用synchronized修饰的方法在某一时刻只允许一个线程访问,访问该方法的其他线程会发生阻塞,直到当前线程访问完毕后,其他线程才有机会执行方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值