首页 > 编程语言 >Java基础题

Java基础题

时间:2022-11-22 21:44:36浏览次数:55  
标签:Java 一个 可以 基础 数据库 线程 java ArrayList

Java基础题

1. Java面向对象有哪些特征

继承、封装、多态三大特征相互相乘
封装:封装内部的一些实现机制,就跟方法封装一些实现的机制一样
继承:就是从已有的类派生出新的类,新的类继承已有类的行为和属性,并扩展新的能力。
多态:多态有多种形式,封装和继承最终归于多态。多态指的是类与类的关系,多态必要的三要素,继承、重写,父类引用指向子类对象。

为什么这些面向特征能帮助我们写很好的代码:
封装:封装好的东西可以重复利用,增加了代码的复用性
继承:也是增加代码的复用性
多态:增加了代码的可移植性,健壮性、灵活性,实现可以随便

2. ArrayList和LinkedList有什么区别

相同点:
首先ArrayList和LinkedList都实现了list接口

不同点:
ArrayList是基于索引数据接口,它的底层是数组。
LinkedList:是以元素列表的形式存储他的数据。
linkedlist比ArrayList更占空间,因为linkedlist一个字节存储两个引用,一个指向前一个元素,一个指向下一个元素。一般Linkedlist用于要求顺序较高的增和删较频繁的场景,因为Linkedlist的一些方法可以快速进行指定,LinkedList删除字节的后,不会重新排序,而是指向下一个元素。所以对于删除、修改要比ArrayList效果要高。

查询速度方面ArrayList要大于linkedlist,因为ArrayList是基于索引数据结构,使用索引在数组里面搜索和查询数据是很快的。但是删除数据开销比较大,删除数据之后需要重写排列数组中所有的数据。所以删除修改ArrayList没有LinkedList性能高。

3. java中==equals有哪些区别

  1. ==:比较他们的数值是否相等,列如:int、long、double、short、byte、float这些都是数值类型,是不能直接new的,比较他们的地址是否相等,如果地址相等则返回true,否则false。如果两个String变量字符串比较,如果是没有new,地址相同,则也是返回true
  2. equals():两个方法之间的比较,如果两个对象内容相等则返回true,否则false。
  3. 注意点:Integer比较也需要使用equals(),就算是地址相等。因为Integer数值超过[-128,127]的时候会new一个对象,==是地址比较,一旦new了,就是就扩容了一块地址,那么最终的结果肯定就有问题了。

4 .Java中异常处理机制

try、catch、finally:捕获异常
throw:抛出异常
throws:声明异常

5. 重载和重写的区别(区别无参构造和有参)

重载:写在一个类里面的,一个方法可以有多个实现,参数和返回值不同即可
重写:是子类父类中,子类重写父类的方法。
重写和重载方法名必须相同

6. String、StringBuffer、StringBuilder区别以及使用场景

都可以存储和操作字符串
String:声明的变量是引用类型,每次改变量值都会新建一个String对象,所以频繁更改变量的时候,避免使用String。
StringBuffer/Stringbuilder:都是可以直接修改,而不会在新建一个对象。变量值是进行追加,然后StringBuffer是jdk0版本的,Stringbuilder是jdk5版本时候的,stringbuilder效率要比stringbuffer效率高,因为stringbuffer方法有加上安全锁,线程安全了,对应的效率就低了

7. 怎样声明一个类不会被继承,什么场景下会用

被fianl修饰
当前类不在被继承,不需要重写。

8. Spring的核心

Spring是一个开源框架,为了简化企业开发而诞
生的,我们现在用到的springboot、springcloud都是基于spring基础之上研发的。我现在做的MES系统不是原生的springcloud,是通过springboot集成的。
开发中用到服务端采用三层架构,每一层都提供了技术支持:

表示层(web):提供了springmvc等框架的整合

业务层(service):管理事务、记录日志等

持久层(dao):提供了与mybatis、hibernate等框架整合

spring的核心是ioc控制反转、aop面向切面。

ioc控制反转:
1、控制什么:控制对象的创建和销毁、就是对象的声明周期
2、反转什么:之前创建一个对象都是new,现在有了IOC,就可以把对象控制权交给了IOC容器。
这样说可能有点模糊:
举列有一个用户,有一辆车,每天就是干两件事,上学、回家。

阶段一(用户自己创建一辆车完成功能)

创建
一个汽车类
一个用户类
当用户需要用到车,就new一个汽车类,调用方法,实现我们要去的地方
(问题:如果每次用车时,就要new一个汽车类,非常麻烦)

阶段二(用户自己传递奔驰车完成功能)

用户类添加构造方法汽车类作为参数,用户需要用车,只需要传递一辆车就可以实现。
(问题:现在汽车类是一辆具体的(宝马),那换一辆车开,就需要修改汽车里面的方法,就比较麻烦)

阶段三 (用传递车完成功能(不是具体的车)

这里可以定义车的接口

  1. 宝马车类
  2. 奔驰车类
  3. 奥迪车类
    实现车(car类)接口
    用户类构造方法参数是car接口,没有具体的实现方法,所以现在可以用到容器进行管理,当我们需要用到车,直接到容器里面拿。这里也是一个控制反转的思想,我们把车创建销毁交给容器,而且控制权也交给容器,我们只是使用功能。
    项目中有SpringUtils的工具类,方便我们在开发中获取bean。
    这里面大概就是我理解ioc的控制反转和注入。
    案例代码地址:https://baijiahao.baidu.com/s?id=1654948911688026610&wfr=spider&for=pc
    aop:是面向切面编程,简单的说在程序运行时候,动态的将代码切入到类的指定方法,指定位置上的编程思想就是面向切面编程。也可也说动态代理。
    列举:做了一个sn调拨功能:
    流程概述:pad扫入调拨单,调拨单有分为主表子表(子表为明细表)扫主表的单据号,pad带出信息,然后点击一条明细进去,通过明细的物料编码到条码存库,关联出条码信息出来,进行调拨。这里会条码库存、库存数量、条码关联档案、还有就是调拨sn这几个功能进行数据库操作。如果出现了异常、这里肯定就要进行回滚。那这些业务逻辑只要有进行数据库操作的地方都要加上事务,列如开启事务、提交事务、回滚操作。那都加上才能达到原子性。但是这样代码看起来就很臃肿,不美观、易读性差。
    解决:
    这里直接引用spring事务@Transactional(rollbackFor=Exception.class)和动态代理JDK代理实现。
    只需要在Service业务上面加上注解,这样就保证了事务的原子性,也解决了代码的臃肿冗余性。
    这里大概就是我对aop面向切面的大概理解。

9. java常用设计模式

简介:为什么使用设计模式:首先设计模式是可以被我们反复使用、优化经验设计的一个总结,使我们的代码更容易被人理解、代码重用性,代码的可靠性、程序的重用性

单列模式

  1. 单列模式只有一个类
  2. 单列对象必须由单列类自行创建
  3. 单列类对外提供一个访问单列的全局访问点
    (注:私有静态变量、构造方法,公有的静态访问方法)
  4. 懒汉模式和饿汉模式
    懒汉模式特点:类加载时没有生成单列,当我们调用getinstance方法时才会创建这个单列
    饿汉模式特点:类加载的时候就创建一个静态对象出来,以后不再改变,线程相对来说就是安全的。
  5. 应用场景:频繁创建和销毁对象,频繁访问数据库或文件对象。就可以使用单列模式。单列模式只允许创建一个对象,因此比较节省内存。速度快。

工厂模式

  1. 简单工厂模式:

  2. 工厂方法:

  3. 抽象工厂模式:
    属于创建型模式,它提供了一种创建对象最佳方式,为什么了,在工厂模式中,我们创建对象时不会暴露客户端创建逻辑,通过共同的接口指向新创建的对象。

  4. 举列:当我们需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆车是怎么做出来的,以及这辆车是怎么实现的。
    如:创建一个车的接口,创建一个宝马奔驰类实现车的接口,在创建一个工厂,用户调用的时候(只需要告诉工厂是需要宝马还是奔驰就行了)。
    优点:扩展性高、如果想增加一个产品只需要在扩展一个工厂类,我们只需要关心产品接口就可以。
    缺点:每次增加一个产品,就要对应增加实现类和工厂,在我们开发中,类的个数就会成倍增加,也增加了类之间的依赖。
    应用场景:我们计划是不同的条件创建不同的实列,解决了我们接口选择的问题。
    代码案例:https://www.runoob.com/design-pattern/factory-pattern.html

    代理模式

    什么是代理模式:

    1. 通过代理控制对象的访问,可以在对象调用方法之前,调用方法之后去处理新的功能。
    2. 代理在原有的代码乃至业务流程都不修改的情况下,直接在业务流程中切入新代码,增加新功能,和spring aop面向切面编程很相似。

    代理模式运行的场景:

    1. spring aop、日志打印、异常处理、事务控制、权限控制等

    代理分类:

    1. 静态代理(静态定义代理类),也是动态代理的理论基础
    2. 动态代理(动态生产代理类,也称为JDK自带动态代理),使用反射完成代理,需要有顶层接口才能使用,常见是mybatis的mapper文件是代理

    举列:
    静态代理

    案例:https://blog.csdn.net/weixin_43122090/article/details/105462226

10. servlet声明周期

加载并实列化,初始化,服务,销毁

程序启动的时候,就会进行加载实列化,初始化,然后当用户进行操作的时候,就会进入控制层,服务层,由方法调用doget或dopost方法来响应用户,然后当容器资源紧张,或者长时间没有接受到请求就会销毁。

12. JVM、JRE、JDK的关系

JDK是java中开发的工具包,开发中API的一些包都是来自于JDK中
JER是java中的一个运行环境
JVN是java中的虚拟机,是java实现跨平台最重要的部分,可以运行java编写的软件程序。

13. Mybatis

mybatis是一个持久层框架,是实现了一个使用JPA对数据库进行增删改查的一个开源框架,他对jdbc数据库的过程进行了封装,是开发者更专注与SQL的本身,不用去关注实现的过程,他是一个半自动华的orm的组件。Hibernate是一个完完全全的orm的组件

bean的声明周期
1、 实例化(Instantiation)

2、 属性设置(populate)

3、 初始化(Initialization)

4、 销毁(Destruction)

14. 数据库事务

原子性:事务都是一个整体的,不可分离的,要么全部成功,要么全部失败
一致性:数据库执行前后,数据要和真实状态保持一致。这种一致性,在我们开发定义,自己给定的规格
列如:a仓库:5000 b仓库:5000 他们互转的数量不能大于5000,数量不能是负数
隔离性:多个用户并发操作数据库的时候,一个用户操作事务不能被其他用户事务干扰,也就是多个事务操作的隔离
持久性:一个事务提交成功了,那么他对数据库的数据操作就是永久性的,就算数据库出现故障,数据也是永久保存下来的。

15. java集合

List、Set、Map

List添加元素是有序的、可重复、有索引的

  1. LinkedList和Arraylist都实现了List接口
  2. ArrayList:实现了List接口,基于索引的接口,底层是数组,查询快。所有查询量大的时候会使用List作为集合来查。在修改和删除方便会比较慢,删除一个元素后,会进行重新排序
  3. LinkedList:以链表的形式进行存储数据,一个指向前一个,一个指向下一个,一般对顺序要求较高的增删操作频繁的场景,因为Linkedlist有指定的方法,可以快速进行操作。删除元素的时候,因为是已链表的形式进行存储的,上一个元素自动指向下一个,所以在修改和删除要比ArrayList性能要高。
     - public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。
     - public E get(int index):返回集合中指定位置的元素。
     - public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
     - public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回更新前的元素值。
小结:
    List系列集合有序,可重复,有索引的。
    ArrayList实现类集合底层基于数组存储数据的,查询快,增删慢!!
    开发中ArrayList集合用的最多!!
 
  List遍历方式:
        (1)for循环。(独有)
        (2)迭代器。
        (3)foreach。
        (4)JDK 1.8新技术。

Set:添加元素是无序的、无索引,并且元素不可以重复,允许一个空元素。可以高效添加删除、用于判断,可以过于重复元素

Map:
HashMap:以键值对的方法存储(key,value),并且键不可以重复,允许一个键为空。
用于我们需要指定key取出或者存储的时候

16. 多线程

1. 进程和线程的区别

举个列子:有一辆火车,火车有很多节,这个火车可以比作为进程,每一节可以比作为线程,进程必须最少要包含一个线程,线程也不能独立存在。

2. 并行、并发、串行的区别

串行:串行在时间上不可能发生重叠,前一个没有执行完,下一个不能执行,只能等待,前一个执行完,下一个才能执行。
并行:并行在时间上是重叠的,两个任务同时执行,互不干扰。
并发:并发是允许两个任务相互干扰,同一时间,只有一个任务执行,交替执行。

3. 什么是线程安全

当多个线程访问一个对象的时候,如果没有进行额为的同步或其他协调操作的时候,调用这个对象的访问结果都是正确的,那么可以说这个对象线程就是安全的。

4. Thread和Runnable

首先Thread和Runnable是一个继承关系,无论是使用Thread或者Runnable,都会new Thread,在执行一个run方法,如果是比较复杂的任务,那就可以用继承 thread,如果只是简单的执行一些方法,那就可以实现Runnable

5. 线程的生命周期和状态

  1. 新建:新创建一个线程
  2. 就绪:线程创建后,其它线程调用该对象的start方法,该状态的线程位于可运行的线程池中,变的可运行,等待获取CPU的使用权限。
  3. 运行:运行状态线程获取CPU权限,执行程序代码。
  4. 阻塞:阻塞状态是因为线程某种原因放弃了CUP的使用权,暂时停止运行,直到进入线程就绪状态,才有机会进入运行状态,
    列如sleep方法让线程进入休眠状态,resume(v曾)方法可以让线程立即运行
  5. 死亡:死亡状态就是说该线程执行完了或者遇到了异常退出了run方法,该线程生命周期结束

6. 并发数据不一致的问题

采用乐观锁,乐观锁顾名思义乐观,两个人都可以访问,访问到数据,但是某个人修改的时候,数据库的版本号也会进行修改进行加一,如果下一个在修改的时候,版本号就会不匹配就修改不了

17. mybatis的优化

一级缓存:mybatis会自动开启,数据缓存到SqlSession中,如果下次请求发现SqlSession中存在相当数据,则不在请求访问数据库,直接从缓存中读取。也可以使用Redis进行一个性能优化,列如把查询的数据存入Redis缓存当中。
二级缓存:整合ehcache框架

18. Java反射

在程序运行的时候,需要动态的加载一些类,而这些类一开始用不到,就不需要加载,在运行的时候根据需要才加载,原来使用new指定的类,属于硬编码形式,现在反射可以用类名参数就可以生成对象,降低了代码的耦合性,提高了程序的灵活性。列如spring的ioc和aop以及动态代理也是反射的编程思想,以及mybati-puls生成的方法也是反射编程思想

19. MySQL的死锁

MySQL的死锁会在innoDB引擎出现的问题
死锁是指两个或者两个以上的进程在执行的过程中,因争夺资源而造成的一种相互等待现象,若没有外力作用,就造成了死锁
多线程的并行。并发会造成死锁,串行不会造成死锁
解决死锁:
可以设置锁或者事务的超时时间
使用悲观锁或者乐观锁
通过事务的日志进行排产
还有一种最暴力的解决方案,就是把你存储死锁的那些表数据清空或者删除,重新执行脚本。这种在本地库还可以,在开发库就不推荐使用了。

20. 消息队列(MQ)(卡布卡)

消息队列简称MQ,我们可以理解为一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用。消息队列是分布式系统中的一个组件
消息队列的应用场景:
异步处理:在网站新用户注册时,需要将用户的信息保存到数据库中,同时还需要额外发送注册的邮件通知、以及短信注册码给用户。但因为发送邮件、发送注册短信需要连接外部的服务器,需要额外等待一段时间,此时,就可以使用消息队列来进行异步处理,从而实现快速响应。

系统解耦:使用消息队列可以实现系统与系统之间的解耦,比如 买票系统中买票,用户是不直接调用数据库系统的接口,而是把订单信息放到消息队列当中,然后数据库系统从消息队列当中拿去信息,然后再去减库存信息。

流行削峰:在像双11 的时候秒杀等系统的时候,用户直接访问数据库,数据库一时接受到大量的数据请求,就会压垮数据库,所以在这个时候加入消息队列,用消息队列的大吞吐量,快速处理用户的请求(哪怕是Redis还不足够应对这种大数据访问)。
因为消息队列是低延迟、高可靠、高吞吐的,可以应对大量并发

21. 说一下你对分布式理解是什么样的?

就是一种微服务的架构,就可以理解在同一个系统中,把不同的业务拆分成单个服务,对于这个服务,可以交给一个团队去独立的技术选型,独立的部署独立的运维,它这样是非常有好处的,这就是我对微服务的理解

Springcloud是一系列框架的集合,他利用SpringCloud的开发便利性简化了分布式系统基础设施的开发,如服务发现、服务注册、配置中心、消息总线、负载均衡、熔断器、数据监控等,都可以用SpringBoot的开发分隔做到一键启动和部署。

22. Springcloud里面的组件

1. 注册中心

第一个涉及到的就是注册中心,他主要承担的就是把我们的各种服务,把它注册到里面去,然后注册到这个里面去之后,
以后要调他的要先从这个里面来拿服务,这就是注册中心第一个

2. 服务发现

第二个既然有服务,那我们这个服务可能注册多个所以第二个组件feing,他是做负载均衡调用的,他主要的作用就是,他从注册中心拿到一堆服务列表,比如说我要那一个用户服务,那他可能有3个或者5个,这个时候我就要按照一定的负载均衡策略。然后完成调用,而这个操作就是交给ribbon或者feing,去做一个载均衡的调用,这个是第二个,

3. 熔断器

第三个的话除了做这个正常调用以外我们还有可能要做一下的事情,比如说我在调用这个服务的时候,这个服务突然挂了,这个时候为了保证服务的一个健壮性,要用到springcloud的hystrix(熔断器)然后他主要就是做熔断和降级以及限流的这个是第三个

4. 分布式配置

第四个的话我们众多的服务当中它有一些配置,而这些配置我把他分散到不同的模块当中,不同的微服务当中,这样管理起来是不好管理的,所以他要有一个统一的配置中心,springcloud configure这是配置中心

5. 网关

然后第五个就是最后一个网关,就像我们有n多个微服务,而这些服务,他最终是要暴露给前端调用的,而前端如果是一个服务
就有一个地址,他是非常不好管理的,这个时候我们处于让他统一管理统一地址,这个是第一个作用

二个作用是我还可以对我要访问的微服务做统一鉴权等等操作,而这些操作统统交给微服务的网关去处理,然后这就是springcloud的五大组

JVM虚拟机

jvm是整个java实现跨平台最核心的部分,所有的java程序首先编译成.class的类文件,编译后就可以到虚拟机上面执行,class文件是不可以直接与机器的操作系统相关联的,而是通过虚拟机间接与操作系统交互,由虚拟机将程序编译给到本地系统执行。还有就是jvm是不能直接运行class文件,因为class文件需要类库,这个时候需要用到jre,首先jre是java中的运行环境,jre里面会生成类库的,也是jvm所需要的库。
jre里面也包含了jvm

23. Java中函数式编程-Stream流-Lambda表达式

jdk1.8中新增了流Stream,和Lambda表达式

Stream流、Lambda表达式是函数式编程思想,可以让我们不用关注什么对象,而是关注对数据进行了什么操作,Stream可以很方便对我们的集合数组进行操作。并且在大数据下处理效果高,列如有大数据量集合可以使用我们的并行流进行操作。可以消灭嵌套地狱的if。让代码简洁、易理解,并且、快速开发。

24. Java泛型(约束类型)

  1. 泛型就是一个标签:尖括号里面加入:<数据类型>
  2. 泛型可以在编译阶段约束只能操作某种数据类型
  3. JDK1.7后,泛型后面的申明可以省略不写!列如:List arrayList = new ArrayList();
  4. 泛型和集合都只能支持引用数据类型,不支持基本数据类型

基本数据类型:
八种基本类型
1.布尔类型 boolean(未指明多少字节)
2.字符类型 chart(2个字节)
3.浮点类型 float(4个字节),double(8个字节)
4.整数类型 byte(1字节),short(2个字节),int(4个字节), long(8个字节)

引用类型:
1.类,如String
2.接口
3.数组
4.对象

泛型好处:泛型在编译阶段可以确定数据类型,不需要再去强转,不会出现类型转换错误,从而体现了java的严谨性和规范性。

自定义泛型建议使用:K,E,T,V

img

标签:Java,一个,可以,基础,数据库,线程,java,ArrayList
From: https://www.cnblogs.com/yingfa/p/16916545.html

相关文章

  • Java基础
    java基础一.java注释1.单行注释:////这是单行注释2.多行注释:/*注释内容*//*这是多行注释这是多行注释*/3.文档注释(JavaDoc):/**注释内容*//***@......
  • java变量 运算符包机制 doc
    java基础2一.变量java变量是程序中最基本存储单元,要素包含变量名变量类型作用域数据类型变量类型变量名=值;例:Stringa='shiftnm';变量作用域类......
  • javascript-代码随想录训练营day7
    454.四数相加Ⅱ题目链接:https://leetcode.cn/problems/4sum-ii/题目描述:给你四个整数数组nums1、nums2、nums3和nums4,数组长度都是n,请你计算有多少个元组(i,j,......
  • java注解-使用注解处理器实现动态生成get和set方法
    目录一、简介二、如何实现1.环境说明:2.创建项目3.定义@Data注解4.定义@Data的注解处理器5.创建一个测试类6.通过idea的maven工具栏进行编译7.查看编译后的结果8.通过反射查......
  • JAVA---单例模式
    单例模式单例的目的是保证某个类仅有一个实例。当有某些类创建对象内存开销较大时可以考虑使用该模式。单例模式又分为饿汉式和懒汉式。1.饿汉式饿汉式。顾名思义,该......
  • 关于Spring注解的基础详解(补充上次并不清楚的内容)
    注解,需要在.xml文件里面加这么一句话:<context:component-scanbase-package=""/>(组件)Component注解主要用于接口的实现类里面,代替掉.xml文件里面的这句话:(主要作用:代替......
  • 大前端html基础学习
    根目录相对路径:针对图片数量比较多的情况,新建一个文件夹,将所有图片放进去,imgs/cat.webp(1)/:下一级(2)a/b/c/cat.webp返回路径(向外找):从下一级html中找上级或上上级的图片,走......
  • JavaScript对象_Global和案例1_点灯开关
    JavaScript对象_Global:Global:1.特点:全局对象,这个Global中封装的方法不需要对象就可以直接调用。方法名();2.方法:encodeURI():url编码decodeURI():url解码encodeUR......
  • Git基础使用
    1、Git工作流程workspace:工作区,平时开发改动代码的地方,这个地方的代码是最新的Index:暂存区,通过gitadd.命令会将代码存放到暂存区Repository:本地仓库,通过gitcomm......
  • java15源码-LinkedBlockingQueue
    一类图二构造方法//LinkedBlockingQueue.java//take锁privatefinalReentrantLocktakeLock=newReentrantLock();//put锁privatefinalRee......