2021-10-30

2021-10-30,第1张

2021-10-30 1、抽象类和接口的区别 

实现:抽象类的子类使用extends来继承;接口必须使用implements来实现接口

构造函数:抽象类可以有构造函数;但是接口不能有

实现数量:类可以实现很多接口;但是只能继承一个抽象类

访问修饰符:接口中的方法默认使用public修饰;抽象类中的方法可以是任意访问修饰符

          

2、string类能不能被继承,为什么

String类实际是一个被final关键字修饰的char[]数组,而final修饰的类是不能被继承的

String类为什么是final的:string类是jdk提供的一个核心类,这种类是非常底层的,为了避免安全隐患用final修饰,让它不被更改

3、ArrayList和linkedList区别

(1)二者实现结构不同arraylist是基于数组,linkedlist是基于链表,他们的特性也是由其数据结构决定的。

(2)随机遍历访问时linkedlist的性能要低于arraylist.

(3)linkedlist的增删要优于arraylist

(4)arraylist的初始化时默认10容量,而linkedlist默认初始化为空。

4、多线程是怎样实现的

(1)继承Thread类

package com.thread;
//通过继承Thread类实现自定义线程类
public class MyThread extends Thread {
	//线程体
    @Override
    public void run() {
        System.out.println("Hello, I am the defined thread created by extends Thread");
    }
    public static void main(String[] args){
        //实例化自定义线程类实例
        Thread thread = new MyThread();
        //调用start()实例方法启动线程
        thread.start();
    }
}

优点:实现简单,只需实例化继承类的实例,即可使用线程
缺点:扩展性不足,Java是单继承的语言,如果一个类已经继承了其他类,就无法通过这种方式实现自定义线程

(2)实现Runnable接口

package com.thread;
public class MyRunnable implements Runnable {
    //线程体
    @Override
    public void run() {
        System.out.println("Hello, I am the defined thread created by implements Runnable");
    }
    public static void main(String[] args){
    	//线程的执行目标对象
        MyRunnable myRunnable = new MyRunnable();
        //实际的线程对象
        Thread thread = new Thread(myRunnable);
        //启动线程
        thread.start();
    }
}

优点:扩展性好,可以在此基础上继承其他类,实现其他必需的功能,适用于多线程处理一份资源的场景

缺点:构造线程实例的过程相对繁琐一点

(3)实现Callable接口

age com.thread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class MyCallable implements Callable {
    @Override
    public String call() throws Exception {
        return "Hello, I am the defined thread created by implements Callable";
    }
    public static void main(String[] args){
        //线程执行目标
        MyCallable myCallable = new MyCallable();
        //包装线程执行目标,因为Thread的构造函数只能接受Runnable接口的实现类,而FutureTask类实现了Runnable接口
        FutureTask futureTask = new FutureTask<>(myCallable);
        //传入线程执行目标,实例化线程对象
        Thread thread = new Thread(futureTask);
        //启动线程
        thread.start();
        String result = null;
        try {
            //获取线程执行结果
            result = futureTask.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println(result);
    }
}

优点:扩展性好、支持多线程处理同一份资源、具备返回值以及可以抛出受检查异常

缺点:相较于实现Runnable接口的方式,较为繁琐

5、索引的优缺点

优点:(1)大大加快数据的检索速度       

           (2)创建唯一性索引,保证数据库表中每一行数据的唯一性

           (3)加速表和表之间的连接

           (4)降低查询中分组和排序的时间

缺点:(1)索引需要占物理空间

           (2)当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度

6、SpringMVC是什么

springMVC是一个基于mvc的web框架;是spring框架的一个模块,拥有spring的特性。

model模型,主要用于数据封装,业务逻辑处理;view视图,主要用于视图的展示;

controller控制器,主要用于分发指派的工作,是一个轻量级的web框架

7、Spring的IOP和AOP

ioc是spring的两大核心概念之一控制反转,ioc给我们提供了一个ioc的bean容器,这个容器会帮我们自动创建管理对象,不需要我们去手动的创建,ioc有一个非常强大的功能叫di依赖注入,我们可以通过写java代码或者配置xml文件,把我们想要注入对象所依赖的其他的bean自动的注入进去,

AOP在做项目的时候经常会遇到一些重复的代码,比如事务、日志,我们需要在很多类里面同时把这些代码全部写进去,AOP可以把这些共有的代码抽象出来然后切入到我们想要切入的类里面,减少了冗余代码提高代码复用性,AOP的实现是依靠动态代理实现的,如果我们将来要代理的这个对象它有接口,我们就可以使用java原生的动态代理来完成动态代理的实现

8、Spring、SpringMVC、Springboot

Spring是一个ioc容器,用来管理bean,使用依赖注入实现控制反转,降低耦合性,可以很方便的整合各种框架,提供AOP机制,弥补面向对象代码重复的问题,可以将类中的共同特性抽取出来形成切面、自动注入给方法执行,减少代码冗余。

springmvc是spring对web框架的一个解决方案,主要用于接收http请求解析参数,springmvc提供了一个前端控制器dispatcherservler,用来接收请求,定义了一套路由解析策略(url到handler的映射)及适配执行handler,将handler结果使用视图解析技术生成视图展现给前端。

springboot的核心实际上是spring+springmvc,是spring提供的一个快速开发工具包,可以更方便的去开发spring+springmvc应用,简化了配置(约定了默认配置),另外springboot整合了一系列的解决方案(starter机制),在使用spring、mybatis等不需要去配置太多东西,只需要它的starter包

整合tomact插件

 9、Java 中 *** 作字符串都有哪些类?它们之间有什么区别?

*** 作字符串的类有:String、StringBuffer、StringBuilder。

String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次 *** 作都会生成新的String 对象,然后将指针指向新的 String 对象,而 StringBuffer、StringBuilder 可以在原有对象的基础上进行 *** 作,所以在经常改变字符串内容的情况下最好不要使用 String。

StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,但 StringBuilder 的性能却高于 StringBuffer,所以在单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer。

10、int和Integer的区别

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

注:Integer变量和int变量比较时,只要两个变量的值是向等的,则结果为true(因为包装类Integer和基本数据类型int比较时,java会自动拆包装为int,然后进行比较,实际上就变为两个int变量的比较)

11、String类是基本数据类型吗?

String不是基本的数据类型,是final修饰的java类,java中的基本类型一共有8个,它们分别为:
1 字符类型:char
2 基本整型:byte,short,int,long
3 浮点型:float,double
4 布尔类型:boolean

12、同步和异步区别

(1)同步是阻塞模式,异步是非阻塞模式。

(2)同步是指发送一个请求,需要等待返回,然后才能发送下一个请求。有个等待过程。

(3)异步发送一个请求,不需要等待返回,直接就可以发送下一个请求。

13、数组有没有length()方法

java中数组是没有length()方法的,只有length属性,数组array.length返回的是该数组的长度。

字符串String是有length()方法的,str.length()返回的是该字符串的长度。

14、异常类型和处理

(1)Throwable 是 Java 语言中所有错误或异常的超类

(2)Throwable有两个子类,Error和Exception。

        Error是错误,对于所有的编译时期的错误以及系统错误都是通过Error抛出的。这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时

        Exception是另外一个非常重要的异常子类。它规定的异常是程序本身可以处理的异常。Exception 又有两个分支 ,一个是运行时异常 RuntimeException(NullPointerException 、 ClassCastException) , 一 个是检查异常CheckedException(IOException、SQLException)

        异常和错误的区别是,异常是可以被处理的,而错误是没法处理的。 

异常的处理

1. 通过try...catch语句块来处理

1)在java语言中,通常将可能出现异常的语句放入try{}语句中,将出现错误后需要执行的语句放入到catch{}语句中,将无论是否发生异常都要执行的语句放在finally{}语句中。

2)如果系统出现系统错误或者运行Runtime异常,jvm会结束程序运行,不一定会执行finally{}中的语句。

3)如果try{}中产生的异常在catch中没有处理,系统将停止程序,也不会执行finally中的语句。

15、linux常用命令

ls:显示文件或目录        cd:切换目录        mkdir:创建目录        rmdir:删除空目录

touch:创建文件        touch:创建文件        rm:删除文件        pwd:查看你当前所在的目录

vi:编辑器        i:编辑        :wq:退出并保存        :q! 强制退出        

查看本地服务:打开cmd -- services.msc

16、Maven

Maven是一个Java工具,所以你必须安装Java环境。Maven项目对象模型(POM)是一个项目管理工具软件,可以通过简短的信息描述来管理项目的构造,报告和文档。

功能:Maven主要用于解决导入依赖于Java类的jar和编译Java项目的主要问题。(最早手动导入jar,并使用Ant编译Java项目)
依赖的jar包由pom.xml文件中的dependency属性管理,并且jar包包含类文件和一些必要的资源文件。当然,它可以构建项目,管理依赖关系并生成简单的单元测试报告。

17、js和jsp的区别

jsp:jsp是Servlet设计,中文名字叫java服务器页面,java都是在服务器上进行的,一般返回值是一个html,所以要依靠浏览器才能预览。

js:javascript是一种脚本,我们经常在html中看到javascript,javascript可以用来给html增加动态效果。

jsp与js的区别:jsp和javascript的区别首先是位置上的不同,javascript一般在前台运行,要求浏览器要支持js,而JSP是在后台服务器上的,主要用于控制html;还有区别就是jsp是在html中以<%%>的形式出现,而js是在HTML中以来实现。

18、GC垃圾回收机制

(1)要回收哪些区域:方法区(废弃的常量和无用的类)和堆需要GC。 (程序计数器、JVM栈、本地方法栈。因为它们的生命周期是和线程同步的,随着线程的销毁,它们占用的内存会自动释放)

(2)如何判断对象是否存活:1、引用计数法

2、可达性分析算法(根搜索算法   ):从一个节点开始,搜索该节点的引用节点,找到该节点后又继续寻找这个节点的引用节点,当所有节点都被找到后,剩下的节点就被认为是没有被引用到的节点,即无用节点

注:通过可达性分析算法,不可达的节点不会被立即销毁,会经历两次标记。第一次标记,判断对象是否复写了finalize方法,如果没有被复习,直接进行第二次标记并回收。如果在finalize()方法中重新与引用链建立了关联关系,那么将会逃离本次回收,继续存活。

(3)垃圾收集算法:

1、标记-清除算法:分为“标记”和“清除”两个阶段,标记出所有需要清除的对象,标记完成后,统一清除所有被标记的对象。

不足:效率角度:标记和清除两个过程的效率都不高

空间角度:标记清楚后会产生大量不连续的内存碎片,内存碎片太多可能会导致以后程序需要分配较大的对象时,无法找到足够的连续内存空间,从而不得不再继续一次标记-清除

2、复制-清除算法:它将可用的内存分为两块,每次都只用其中一块,当这一块内存用完了,就将还在存活着的对象复制到另一块上面,然后再把已经使用过的内存空间一次性清理掉。

优点:解决了效率问题,不存在内存碎片问题

缺点:内存缩小为原来的一半,在存活对象较多的情况下(老生代),要进行大量复制,效率低

3、标记-整理算法:与标记-清除算法一样,只是在标记后不会直接回收,而是把存活对象向一端移动,清除掉边界以外的内存。

4、分代收集算法:上面3中算法的集合,根据对象的生命周期的不同将内存划分为几块,根据各块的特点选择适合的算法。大批对象死去、少量对象存活的(新生代),使用复制算法,复制成本低;对象存活率高、没有额外空间进行分配担保的(老年代),采用标记-清理算法或者标记-整理算法。

19、线程和进程

一个程序下至少有一个进程,一个进程下至少有一个线程,一个进程下也可以有多个线程来增加程序的执行速度,线程是进程中执行运算的最小单位。

区别:

    (1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位

    (2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行

    (3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源

    (4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

20、sleep和wait的区别

sleep()是线程类Thread的方法:作用是导致此线程暂停执行指定时间,把执行机会给其他线程,但是监控状态依然保持,到时候会自动恢复

wait()是Object类的方法:对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池。只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池,准备获得对象锁进行运行状态

区别:

类不同:sleep是Thread的静态方法,wait是Object的方法,任何对象实例都能调用。

释放锁:sleep不会释放锁,它也不需要占用锁。wait会释放锁,但调用它的前提是当前线程占有锁(即代码要在synchronized中)。

用法不同:sleep()时间到会自动恢复;wait()可以使用notify()/notifyAll()直接唤醒

20、在java中怎么保证多线程的运行安全

多个线程同时执行同一段代码(只读一般是线程安全的,写需要考虑线程安全问题)

解决方法:线程安全及三种解决方案 - 知乎

(1)同步代码块:格式:synchronized(同步锁){ 可能会出现线程安全问题的代码(访问了共享数据的代码) }

(2)同步方法:格式:public synchronized void method(参数列表){ 可能会产生线程安全问题的代码 (访问了共享数据的代码) }

(3)锁机制:

使用如下步骤:1.在成员位置创建一个ReentrantLock对象
2.在可能会出现安全问题的代码前调用Lock接口中的方法lock获取锁
3.在可能会出现安全问题的代码后调用Lock接口中的方法unlock释放

21、synchronized和lock有什么区别

(1)来源:lock是一个接口,而synchronized是java的一个关键字,synchronized是内置的语言实现

(2)异常是否释放锁:
synchronized在发生异常时候会自动释放占有的锁,因此不会出现死锁;而lock发生异常时候,不会主动释放占有的锁,必须手动unlock来释放锁,可能引起死锁的发生。(所以最好将同步代码块用try catch包起来,finally中写入unlock,避免死锁的发生。)

(3)是否响应中断:
lock等待锁过程中可以用interrupt来中断等待,而synchronized只能等待锁的释放,不能响应中断

(4)是否知道锁状态
Lock可以通过trylock来知道有没有获取锁,而synchronized不能

(5)在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择

22、servlet

解释:是一个服务连接器,用java语言编写的服务器段程序,具有独立于平台和协议的特性,主要功能是交互式的浏览和生成数据

实现过程:

首先客户发送一个请求,Servlet是调用service()方法对请求进行响应的,通过源代码可见,service()方法中对请求的方式进行了匹配,选择调用doGet,doPost等这些方法,然后再进入对应的方法中调用逻辑层 的方法,实现对客户的响应。

在Servlet接口和GenericServlet中是没doGet,doPost等等这些方法的HttpServlet中定义了这些方法(创建servlet的三种方法),但是都是返回error信息,所以,我们每次定义一个Servlet的时候,都必须实现doGet或 doPost等这些方法。

生命周期:初始化阶段、响应客户请求阶段、终止阶段

(1)创建Servlet对象,通过服务器反射机制创建Servlet对象,第一次请求时才会创建。(默认)

(2)调用Servlet对象的init()方法,初始化Servlet的信息,init()方法只会在创建后被调用一次(初始化阶段)

(3)响应请求,调用service()或者是doGet(),doPost()方法来处理请求,这些方法是运行在多线程状态下的。(响应客户请求阶段)

(4)在长时间没有被调用或者是服务器关闭时,会调用destroy()方法来销毁Servlet对象。(终止阶段)

23、jsp--servlet

JSP是Servlet技术的扩展,本质上就是Servlet的简易方式。JSP编译后是“类servlet”。

Servlet和JSP最主要的不同点在于:

Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。 而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。 JSP侧重于视图,Servlet主要用于控制逻辑 Servlet更多的是类似于一个Controller,用来做控制。

24、Tomcat

Tomcat 是由 Apache 开发的一个 web容器,实现了对Servlet 和 JSP 的支持,主要作用开启监听端口监听用户的请求,解析用户发来的http请求然后访问到指定的应用系统,然后返回的页面经过tomcat返回给用户。

 25、spring依赖注入的几种方式

(1)setter方法注入        (2)构造方法注入        (3)注解注入(autowired)

(1)(2)两种注入方式需要在spring-config.xml文件中进行配置,通过java反射技术实现

26、序列化和反序列化的底层实现原理是什么?_徐刘根的博客-CSDN博客_什么是序列化

 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5434580.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存