最终成功入职的java面试题

9 篇文章 0 订阅

《《《应届生java面试经验总结:超实用,点击查看》》》

面向对象的三大特性和五大原则

面向对象的三大特性和五大原则_ShyTan的博客-CSDN博客

Spring+SpringMVC+Mybatis原理整合

Spring+SpringMVC+Mybatis原理整合_ShyTan的博客-CSDN博客

servlet执行流程

    客户端发出http请求,web服务器将请求转发到servlet容器,servlet容器解析url并根据web.xml找到相对应的servlet,并将request、response对象传递给找到的servlet,servlet根据request就可以知道是谁发出的请求,请求信息及其他信息,当servlet处理完业务逻辑后会将信息放入到response并响应到客户端。

AOP与IOC的概念(即spring的核心)

     a) IOC:Spring是开源框架,使用框架可以使我们减少工作量,提高工作效率并且它是分层结构,即相对应的层处理对应的业务逻辑,减少代码的耦合度。而spring的核心是IOC控制反转和AOP面向切面编程。IOC控制反转主要强调的是程序之间的关系是由容器控制的,容器控制对象,控制了对外部资源的获取。而反转即为,在传统的编程中都是由我们创建对象获取依赖对象,而在IOC中是容器帮我们创建对象并注入依赖对象,正是容器帮我们查找和注入对象,对象是被获取,所以叫反转。

    b) AOP:面向切面编程,主要是管理系统层的业务,比如日志,权限,事物等。AOP是将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可重用的模块,这个模块被命名为切面(aspect),切面将那些与业务逻辑无关,却被业务模块共同调用的逻辑提取并封装起来,减少了系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。

Java异常及处理详解

Java异常及处理详解_ShyTan的博客-CSDN博客

重载和重写的区别

    override(重写)

      1. 方法名、参数、返回值相同

      2. 子类方法不能缩小父类方法的访问权限

      3. 子类方法不能抛出比父类方法更多的异常(子类方法可以不抛出异常)。

      4. 存在于父类和子类之间

      5. 方法被定义为final不能被重写。

    overload(重载)

      1. 参数类型、个数、顺序至少有一个不相同

      2. 不能重载只有返回值不同的方法名。

      3. 同一个类中的方法。

final

1)final修饰的方法,不允许被子类重写。

2)final修饰的类,不能被继承。

3)final修饰的变量,不能改变值。

static

static和“this、super”势不两立,static跟具体对象无关,而this、super正好跟具体对象有关。

static不可以修饰局部变量。

static修饰的属性的初始化在编译期(类加载的时候),初始化后能改变。

static修饰的对象只有一个值。

多线程

a)一个进程是一个独立的运行环境,可以看做是一个程序,而线程可以看做是进程的一个任务,比如QQ是一个进程,而一个QQ窗口是一个线程。

b)在多线程程序中,多线程并发可以提高程序的效率,cpu不会因为某个线程等待资源而进入空闲状态,它会把资源让给其他的线程。

c)用户线程:我们开发程序是创建的线程。守护线程:系统线程,如JVM虚拟中的GC

d)线程的优先级别:每一个线程都有优先级别,有限级别高的可以先获取CPU资源使该线程从就绪状态转为运行状态。也可以自定义线程的有限级别

e)死锁:至少两个以上线程争取两个以上cpu资源,避免死锁就避免使用嵌套锁,只需要在他们需要同步的地方加锁和避免无限等待

详解:多线程入门讲解_ShyTan的博客-CSDN博客

线程中sleep()与wait()的区别

对时间的指定。 
1,sleep方法必须指定时间。 
2,wait方法有重载形式,可以指定时间,也可以不指定时间。

对于执行权和锁的操作.: 
1,sleep():释放执行权,不释放锁,因为肯定能醒,肯定可以恢复到临时阻塞状态。 
2,wait():释放执行权,释放锁,因为wait不释放锁,如果没有时间指定,那么其他线程都进行不了同步中,无法将其唤醒。

1、这两个方法来自不同的类分别是Thread和Object

  2、sleep方法没有释放锁,而 wait 方法释放了锁,使得其他线程可以使用同步控制块或者方法。 
  3、wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围) 
  synchronized(x){ 
         x.notify() 
         //或者wait() 
  } 
  4、sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常 

Java集合类框架的基本接口有哪些

a) Collection集合接口,List、set实现Collection接口,arraylist、linkedlist,vector实现list接口,stack继承vector,Map接口,hashtable、hashmap实现map接口

详解:List、Set、Map等Java集合类_ShyTan的博客-CSDN博客

HashMap和Hashtable

1、HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。

2、HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。

3、由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。

4、HashMap不能保证随着时间的推移Map中的元素次序是不变的。

详解:HashMap和Hashtable_ShyTan的博客-CSDN博客

Arraylist与linkedlist的区别

a) 都是实现list接口的列表,arraylist是基于数组的数据结构,linkedlist是基于链表的数据结构。

b) 当获取特定元素时,ArrayList效率比较快,它通过数组下标即可获取,而linkedlist则需要移动指针。

c) 当存储元素与删除元素时,linkedlist效率较快,只需要将指针移动指定位置增加或者删除即可,而arraylist需要移动数据。

Arraylist实例的创建

ArrayList<String> list = new ArrayList<String>();

List实例的创建

List<String> list = new ArrayList<String>();

Java设计模式思想(单列模式,工厂模式,策略模式,共23种设计模式)

a) 单例模式:单例模式核心只需要new一个实例对象的模式,比如数据库连接,在线人数等,一些网站上看到的在线人数统计就是通过单例模式实现的,把一个计时器存放在数据库或者内存中,当有人登陆的时候取出来加一再放回去,有人退出登陆的时候取出来减一再放回去,但是当有两个人同时登陆的时候,会同时取出计数器,同时加一,同时放回去,这样的话数据就会错误,所以需要一个全局变量的对象给全部人使用,只需要new出一个实例对象,这就是单例模式的应用,并且单例模式节省资源,因为它控制了实例对象的个数,并有利于gc回收。

b) 策略模式:就是将几个类中公共的方法提取到一个新的类中,从而使扩展更容易,保证代码的可移植性,可维护性强。比如有个需求是写鸭子对象,鸭子有叫,飞,外形这三种方法,如果每个鸭子类都写这三个方法会出现代码的冗余,这时候我们可以把鸭子中的叫,飞,外形这三个方法提取出来,放到鸭父类中,让每个鸭子都继承这个鸭父类,重写这三个方法,这样封装的代码可移植性强,当用户提出新的需求比如鸭子会游泳,那么对于我们oo程序员来讲就非常简单了我们只需要在鸭父类中加一个游泳的方法,让会游泳的鸭子重写游泳方法就可以了。

c) 工厂模式:简单的工厂模式主要是统一提供实例对象的引用,通过工厂模式接口获取实例对象的引用。比如一个登陆功能,后端有三个类,controller类,interface类,实现接口的实现类。当客户端发出一个请求,当请求传到controller类中时,controller获取接口的引用对象,而实现接口的实现类中封装好了登陆的业务逻辑代码。当你需要加一个注册需求的时候只需要在接口类中加一个注册方法,实现类中实现方法,controller获取接口的引用对象即可,不需要改动原来的代码,这种做法是的可拓展性强。

数据库语句

a) 普通操作:

选择:select * from table1 where 范围

插入:insert into table1(field1,field2) values(value1,value2)

删除:delete from table1 where 范围

更新:update table1 set field1=value1 where 范围

b) 关联查询(left join on)(增加列

左外连接(左连接):结果集几包括连接表的匹配行,也包括左连接表的所有行。

SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c

c) union与unionAll  (增加行)

UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表。当 ALL 随 UNION一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2。

d) 主键索引、唯一索引

create [unique] index idxname on tabname(col….)

常用sql语句大全:常用SQL语句大全_ShyTan的博客-CSDN博客

数据库优化

a) 选择合适的字段,比如邮箱字段可以设为char(6),尽量把字段设置为notnull,这样查询的时候数据库就不需要比较null值

b) 使用关联查询( left join on)查询代替子查询

c) 使用union联合查询手动创建临时表

d) 开启事物,当数据库执行多条语句出现错误时,事物会回滚,可以维护数据库的完整性

e) 使用外键,事物可以维护数据的完整性但是它却不能保证数据的关联性,使用外键可以保证数据的关联性

f) 使用索引,索引是提高数据库性能的常用方法,它可以令数据库服务器以比没有索引快的多的速度检索特定的行,特别是对于max,min,order by查询时,效果更明显

g) 优化的查询语句,绝大多数情况下,使用索引可以提高查询的速度,但如果sql语句使用不恰当的话,索引无法发挥它的特性。

类加载的过程

a) 生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段。

b) 遇到一个新的类时,首先会到方法区去找class文件,如果没有找到就会去硬盘中找class文件,找到后会返回,将class文件加载到方法区中,在类加载的时候,静态成员变量会被分配到方法区的静态区域,非静态成员变量分配到非静态区域,然后开始给静态成员变量初始化,赋默认值,赋完默认值后,会根据静态成员变量书写的位置赋显示值,然后执行静态代码。当所有的静态代码执行完,类加载才算完成。

详解:Java虚拟机类的加载机制_ShyTan的博客-CSDN博客

对象的创建

a) 遇到一个新类时,会进行类的加载,定位到class文件

b) 对所有静态成员变量初始化,静态代码块也会执行,而且只在类加载的时候执行一次

c) New 对象时,jvm会在堆中分配一个足够大的存储空间

d) 存储空间清空,为所有的变量赋默认值,所有的对象引用赋值为null

e) 根据书写的位置给字段一些初始化操作

f) 调用构造器方法(没有继承)

父类与子类之间的调用顺序(打印结果)

a) 父类静态代码块

b) 子类静态代码块

c) 父类构造方法

d) 子类构造方法

e) 子类普通方法

f) 重写父类的方法,则打印重写后的方法

例题:https://blog.csdn.net/ShyTan/article/details/77574469

内部类与外部类的调用

a) 内部类可以直接调用外部类包括private的成员变量,使用外部类引用的this.关键字调用即可

b) 而外部类调用内部类需要建立内部类对象

数据区

Java运行时的数据区包括:(其中前两个是线程共享的)
      1、方法区(Method Area) :存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
      2、堆(Heap): 存放对象实例,几乎所有对象实例都在这里分配内存
      3、虚拟机栈(VM Stack): 描述的是Java方法执行的内存模型:每个方法在执行的同时会创建一个Stack Frame(方法运行时的基础数据结构)用于存储局部变量表、操作数栈、动态连接、方法出口等信息
      4、本地方法栈(Native Method Stack):  与虚拟机栈了类似,不过则为虚拟机使用的到的Native方法服务。(有的虚拟机譬如Sun HotSpot虚拟机直接把本地方法栈和虚拟机栈合二为一)

      5、程序计数器(Program Counter Register): 可看作当前线程所执行的字节码的行号的标识器.

高并发处理

a) 了解一点高并发性问题,比如一W人抢一张票时,如何保证票在没买走的情况下所有人都能看见这张票,显然是不能用同步机制,因为synchronize是锁同步一次只能一个人进行。

这时候可以用到锁机制,采用乐观锁可以解决这个问题。乐观锁的简单意思是在不锁定表的情况下,利用业务的控制来解决并发问题,这样即保证数据的可读性,又保证保存数据的排他性,保证性能的同时解决了并发带来的脏读数据问题。

事物的性质

事物具有原子性,一致性,持久性,隔离性

b) 原子性:是指在一个事物中,要么全部执行成功,要么全部失败回滚。

c) 一致性:事物执行之前和执行之后都处于一致性状态

d) 持久性:事物多数据的操作是永久性

e) 隔离性:当一个事物正在对数据进行操作时,另一个事物不可以对数据进行操作,也就是多个并发事物之间相互隔离。

使用详解:MySQL事务_ShyTan的博客-CSDN博客

HTTP协议

a) 常用的请求方法有get、post

b) Get与post的区别:传送数据,get携带参数与访问地址传送,用户可以看见,这的话信息会不安全,导致信息泄露。而post则将字段与对应值封装在实体中传送,这个过程用户是不可见的。Get传递参数有限制,而post无限制。

jvm的优化

a) 设置参数,设置jvm的最大内存数

b) 垃圾回收器的选择

Tomcat服务器优化(内存,并发连接数,缓存)

a) 内存优化:主要是对Tomcat启动参数进行优化,我们可以在Tomcat启动脚本中修改它的最大内存数等等。

b) 线程数优化:Tomcat的并发连接参数,主要在Tomcat配置文件中server.xml中配置,比如修改最小空闲连接线程数,用于提高系统处理性能等等。

c) 优化缓存:打开压缩功能,修改参数,比如压缩的输出内容大小默认为2KB,可以适当的修改。

冒泡排序、快速排序、二分查找

a) 冒泡排序

1

2

3

4

5

6

7

8

9

10

11

12

13

public static void mp(int a[]) {

int swap = 0;

for (int i = 0; i < a.length; i++) {

for (int j = i; j < a.length; j++) {

if (a[j] > a[i]) {

swap = a[i];

a[i] = a[j];

a[j] = swap;

}

}

}

System.out.println(Arrays.toString(a));

}

1

2

3

4

5

6

7

8

9

10

11

12

13

public static void mp(int a[]) {

int swap = 0;

for (int i = 0; i < a.length-1; i++) {

 for (int j = 0; j < a.length-1-i; j++) {

   if (a[j] > a[j+1]) {

    swap = a[j];

    a[j] = a[j+1];

    a[j+1] = swap;

   }

  }

}

System.out.println(Arrays.toString(a));

}

b)快速排序

选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。

public static void main(String[] args)
    {
        int[] a = { 49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 1, 8 };
        System.out.println("排序之前:");
        for (int i = 0; i < a.length; i++)
        {
            System.out.print(a[i] + " ");
        }
        // 快速排序
        quick(a);
        System.out.println();
        System.out.println("排序之后:");
        for (int i = 0; i < a.length; i++)
        {
            System.out.print(a[i] + " ");
        }
    }
 
    private static void quick(int[] a)
    {
        if (a.length > 0)
        {
            quickSort(a, 0, a.length - 1);
        }
    }
 
    private static void quickSort(int[] a, int low, int high)
    {
        if (low < high)
        { // 如果不加这个判断递归会无法退出导致堆栈溢出异常
            int middle = getMiddle(a, low, high);
            quickSort(a, 0, middle - 1);
            quickSort(a, middle + 1, high);
        }
    }
 
    private static int getMiddle(int[] a, int low, int high)
    {
        int temp = a[low];// 基准元素
        while (low < high)
        {
            // 找到比基准元素小的元素位置
            while (low < high && a[high] >= temp)
            {
                high--;
            }
            a[low] = a[high];
            while (low < high && a[low] <= temp)
            {
                low++;
            }
            a[high] = a[low];
        }
        a[low] = temp;
        return low;
    }

c)二分查找

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

public static int ef(int a[], int tag) {

int first = 0;

int end = a.length;

for (int i = 0; i < a.length; i++) {

int middle = (first + end) / 2;

if (tag == a[middle]) {

return middle;

}

if (tag > a[middle]) {

first = middle + 1;

}

if (tag < a[middle]) {

end = middle - 1;

}

}

return 0;

}

各种排序算法:各种排序算法详解&时间、空间复杂度_ShyTan的博客-CSDN博客

对ajax的理解

a) Ajax为异步请求,即局部刷新技术,在传统的页面中,用户需要点击按钮或者事件触发请求,到刷新页面,而异步技术为不需要点击即可触发事件,这样使得用户体验感增强,比如商城购物车的异步加载,当你点击商品时无需请求后台而直接动态修改参数。

  • 21
    点赞
  • 177
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShyTan

喜欢的给点打赏呗,纯手打

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值