阿里面试整理

1. 类修饰词default和protected关系

Java一共有四类类修饰符,private default,public protected

protected 包内所有类可见,包外有继承关系的子类可见。

default表示默认,不仅本类访问,而且是同包可见。

当修饰词是private时,只有类内能够访问到,其他任何类都不能直接访问到。

当修饰词是public时,任何类内都能访问到。

2.参数传递,值传递和引用传递的关系,String和char数组作为入参,结果会改变吗

值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参数的值。

引用传递:也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,方法执行中形式参数值的改变将会影响实际参数的值。

String 比较特别,看过String 代码的都知道, String 是 final的。所以值是不变的。 函数中String对象引用的副本指向了另外一个新String对象,而数组对象引用的副本没有改变,而是改变对象中数据的内容.

String作为参数传入时,因为在java中都是传递的是参数的引用,也就是按值传递的,String作为参数时,传递的是String数据的拷贝,那么方法中是不会改变数据本身的内容,char[]作为参数入参时,传递的是引用类型也就是数组的指向的引用的拷贝,引用的拷贝也是指向数组,所以对改变原数组的值。

3.异常都有几大类?运行时的空指针会抛异常吗?IO Exception异常发生需要自己去捕获?

Java中的异常主要分为运行时异常runtimeExclrtion和非运行时异常IOExcletion,

运行时异常,主要是程序的编写存在问题,javac在编译时,不会提示和发现这样的异常,不要求在程序处理这些异常。所以如果愿意,我们可以编写代码处理(使用try…catch…finally)这样的异常,也可以不处理。对于这些异常,我们应该修正代码,而不是去通过异常处理器处理 。这样的异常发生的原因多半是代码写的有问题。比如数组越界异常,类未找到异常等等异常情况。

IOExcletion非运行时异常,这种异常编译器要求强制处置,要么try-cathch,要么在方法名后面抛出。要么捕获要么抛出。

4.线程池的TheadPoolExcutor核心参数,什么时候创建线程,什么时候不创建,线程达到最大上限是什么策略?什么时候加入缓存队列?

一个完整的线程池应该具备如下要素:

任务队列:用于缓存提交的任务

线程数量管理功能:一个线程池应该很好的管理和控制线程的数量,可以通过三个参数来实现,比如创建线程池时初始的线程数量init,线程池自动扩展时最大的线程数量;在线程空闲时需要释放一定的线程但是也要维持一定的活跃数量。

5.线程状态?什么时候进入阻塞态什么时候进入等待状态?wait之后的状态可以直接回到Runnable吗?

(1). NEW 新建状态 线程刚被创建,但是还没启动,还没调用start方法
(2). Runnable 可运行状态 线程可以在Java虚拟机中运行的状态,可能正在运行自己的代码,也可能没有,这取决于操作系统处理器
(3). Blocked 锁阻塞 当一个线程试图获取一个对象锁时,而该对象锁被其他的线程持有,则该线程进入Blocked状态,当该线程持有锁时,该线程将变成Runnable状态
(4). Waiting 无限等待 一个线程在等待另一个线程执行唤醒动作时,该线程进入Waiting状态,进入这个状态后是不能自动唤醒的,必须等待另一个线程调用notify或者是notifyAll方法才能够唤醒。
(5). Timed Waiting 计时等待 同Waiting状态 ,,有几个方法有超时参数,调用他们将进入Timed Waiting状态,这一状态将一直保持到超时期满或者是接收到唤醒通知,带有超时参数的常用方法有Thread.sheep、Object.wait
(6). Teminated 被终止 因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。

6.高并发会带来什么问题?死锁的解决办法?

高并发就是多个进程或者线程同时处理不同的操作。高并发会导致系统数据不正确,会出现脏数据等等问题。

对于一些大型网站,比如门户网站,在面对大量用户访问、高并发请求方面,基本的解决方案集中在这样几个环节:使用高性能的服务器、高性能的数据库度、高效率的编程语言、还有高性能的Web容器。

7.Java的锁的了解,Sychronzed有哪些方法?一个类中两个Sychronized方法被两个线程锁住,分别去调用会阻塞吗?

悲观锁乐观锁:

悲观锁:先说概念。对于同一个数据的并发操作,悲观锁认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,确保数据不会被别的线程修改。Java中,synchronized关键字和Lock的实现类都是悲观锁。

而乐观锁认为自己在使用数据时不会有别的线程修改数据,所以不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据。如果这个数据没有被更新,当前线程将自己修改的数据成功写入。如果数据已经被其他线程更新,则根据不同的实现方式执行不同的操作(例如报错或者自动重试)。

乐观锁在Java中是通过使用无锁编程来实现,最常采用的是CAS算法,Java原子类中的递增操作就通过CAS自旋实现的。

CAS全称 Compare And Swap(比较与交换),是一种无锁算法。在不使用锁(没有线程被阻塞)的情况下实现多线程之间的变量同步。java.util.concurrent包中的原子类就是通过CAS来实现了乐观锁。

悲观锁适合写操作多的场景,先加锁可以保证写操作时数据正确。

乐观锁适合读操作多的场景,不加锁的特点能够使其读操作的性能大幅提升。

8.设计模式知道哪些?设计原则有哪些?单例模式构造函数有何特点?静态方法初始化具体操作?为什么要加volatile?

9.Spring的IOC和AOP? IoC自动注入的注解?@Autowired的功能?

10.数据库方面除了项目之外还有哪些深入学习?试验RR级别下出现幻读?

\1. 什么是多态?

接口的多种不同的实现方式即为多态

在同一个方法中,这种由于参数类型不同而导致执行效果各异的现象就是多态

在Java中为了实现多态,允许使用一个父类类型的变量来引用一个子类类型的对象,根据被引用子类对象特征的不同,得到不同的运行结果。

多态具体表现在重写和重载

多态就是类的多种表现方式

比如方法的同名不同参

子类重写父类

方法的重写和重载是Java多态性的不同表现。

重写是父类与子类之间多态性的一种表现。

重载是一个类中多态性的一种表现。

如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 。

子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。

如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载。

并且重载的方法是可以改变返回值的类型的。

\2. 接口与抽象类的区别?

含有abstract修饰符的类即为抽象类,抽象类不能创建实例对象。含有抽象方法的类必须定义为abstract class。在abstract class中,方法不必是抽象的,但是抽象方法必须在具体子类中实现,所以,不能有抽象构造方法或抽象静态方法。子类如果没有实现抽象父类中的所有抽象方法,则必须定义为abstract类型。抽象类需要被继承才能使用,而被final修饰的类无法被继承,所以abstract和final是不能共存的。

接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。\接口中的方法定义默认为public abstract类型**,接口中的成员变量类型默认为public static final。

\3. 为什么会有java内存模型?

java内存模型(Java Memory Model,JMM)是java虚拟机规范定义的,用来屏蔽掉java程序在各种不同的硬件和操作系统对内存的访问的差异,这样就可以实现java程序在各种不同的平台上都能达到内存访问的一致性。

本文标题:阿里面试整理

文章作者:雷凯博

发布时间:2020年06月06日 - 18:06

最后更新:2021年05月16日 - 19:05

原始链接:http://yoursite.com/2020/06/06/%E9%98%BF%E9%87%8C%E9%9D%A2%E8%AF%95%E6%80%BB%E7%BB%93/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

坚持原创技术分享,您的支持将鼓励我继续创作!
-------------本文结束感谢您的阅读-------------
0%