面试准备 - 日常记录

面向对象的编程思想

一.什么是面向对象(Object Oriented Programming)

面向对象思想将客观世界中的事物描述为对象,并通过抽象思维方法将需要解决的实际问题分解为人们易于理解的对象模型,然后通过这些对象模型来构建应用程序的功能;

二. 面向对象的概念:

对象、类、封装、继承、多态

对象:客观具体存在的事务,如这个人,这个桌子,由属性和行为组成;

类: 对大量对象共性的抽象,是对客观事务的抽象,也由属性和成为组成;

三.四大基本特征

抽象:提取现实世界中某些事物的关键特性,为该事物建模的过程,得到的模型中一般包含属性(数据)和操作(行为);

封装: 把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏;

继承:可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

多态:允许将子类类型的引用赋值给父类类型的,将父对象设置成为和一个或更多的他的子对象相等 ,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。

封装可以隐藏实现细节,使得代码模块化;

继承可以扩展已存在的代码模块(类);为了实现代码重用。

多态则是为了实现接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。

四.七大设计原则

1 开闭原则
一个软件实体,如类,模块和函数应该多外扩展开发,对内修改关闭
即不修改原有代码的前提下给程序扩展功能,增加了程序的可扩展性。

2 单一职责原则
一个类只允许有一个职责,即只有一个导致该类变更的原因

3 依赖倒置原则

依赖抽象而不是依赖实现,高层模块不能依赖底层模块
即针对接口编程,而不是针对实现编程,通过抽象搭建框架,建立类与类的关联,以减少类间的耦合性。

4 接口分离原则

多个特定的客户端接口要好于一个通用性的总接口;
避免用一个接口里面包含不同职责的方法,接口责任划分更加明确

5 迪米特法则

一个对象应该对尽可能少的对象有接触,只接触那些真正需要接触的对象

6 里氏替换原则

所有引用基类的地方必须能透明地使用其子类的对象,而程序执行效果不变。可以检测继承使用的正确性。

7 合成复用原则

尽量使用合成/聚合的方式,而不是使用继承。

JVM内存模型

JVM内存模型包括:程序计数器、本地方法栈、虚拟机堆(线程)、线程栈、方法区(元空间);程序计数器、线程栈、本地方法栈是每个线程所独有的。

 1. 线程栈

        JVM的每一个线程对应一个线程栈,一个线程的每个方法会分配一块栈帧内存空间。栈帧中包含:局部变量表、操作数栈、动态链接和方法出口。

局部变量表:存储基本数据类型(int、float、byte等),如果是引用数据类型,则存储的是其在堆中的内存地址,也就是指向对象的一个指针。
操作数栈:操作数运算时一块临时的空间来存放操作数。
动态链接:将代码的符号引用转换为在方法区(运行时常量池)中的直接引用。
方法出口:存储了栈帧中的方法执完之后回到上一层方法的位置。
 2. 本地方法栈

        运行本地方法的空间,也就是native本地方法运行时的一块空间。

3. 程序计数器

        程序计数器是用于存放下一条指令所在单元的地址的地方。当执行一条指令时,首先需要根据PC中存放的指令地址,将指令由内存取到指令寄存器中,此过程称为“取指令”。与此同时,PC中的地址或自动加1或由转移指针给出下一条指令的地址。此后经过分析指令,执行指令。完成第一条指令的执行,而后根据PC取出第二条指令的地址,如此循环,执行每一条指令。

4.  方法区(元空间)

        主要包括:常量、静态变量、类信息、运行时常量池,操作的是直接内存。

5. 堆

        堆是运行时数据区,所有类的实例和数组都是在堆上分配内存。它在 JVM 启动的时候被创建。对象所占的堆内存是由自动内存管理系统也就是垃圾收集器回收。

二、JVM中对象及常量、局部变量、全局变量的存储位置

1. 局部变量

基本数据类型:变量名和变量值存储在方法栈中。
引用数据类型:变量值存储在方法栈中(存储的是堆中对象的内存地址),所指向的对象是存储在堆内存中(如new出来的对象)。
2. 全局变量

基本数据类型:变量名和变量值存储在堆内存中。
引用数据类型:变量名存储的是所引用对象的内存地址,变量名和变量值存储在堆内存中。
三、JVM内存参数

        默认堆中年轻代(Young)占1/3,老年代(Old)占2/3,年轻代中包含Eden区和Survivor区,Survivor区包含From(S0)区和To(区),默认新生代中Eden区、From区、To区的比例为8:1:1,当Eden区内存不足时会触发Minor gc,没有被回收的对象进入到Survivor区,同时分代年龄+1,当再次触发Minor gc时,From区中的对象会移动到To区,Minor gc会回收Eden区和From区中的垃圾对象,对象的分代年龄会一次次的增加,当分代年龄增加到15以后,对象会进入到老年代。

        当老年代内存不足时,会触发Full gc,如果Full gc无法释放足够的空间,会触发OOM内存溢出,在进行Minor gc或Full gc时,会触发STW(Stop The World),即停止用户线程。

Spring Boot程序的JVM参数设置格式(Tomcat启动直接加在bin目录下catalina.sh文件里):

java -Xms2048M -Xmx2048M -Xmn1024M -Xss512K -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -jar microservice-eureka-server.jar

-Xss:每个线程的栈大小

-Xms:设置堆的初始可用大小,默认物理内存的1/64

-Xmx:设置堆的最大可用大小,默认物理内存的1/4

-Xmn:新生代大小

-XX:NewRatio:默认2表示新生代占年老代的1/2,占整个堆内存的1/3。

-XX:SurvivorRatio:默认8表示一个survivor区占用1/8的Eden内存,即1/10的新生代内存。

关于元空间的JVM参数有两个:-XX:MetaspaceSize=N和 -XX:MaxMetaspaceSize=N

-XX:MaxMetaspaceSize: 元空间最大值, 默认-1, 即不限制,或者说只受限于本地内存大小。

-XX:MetaspaceSize: 指定元空间触发Fullgc的初始阈值(元空间无固定初始大小), 以字节为单位,默认是21M左右,达到该值就会触发full gc进行类型卸载, 同时收集器会对该值进行调整: 如果释放了大量的空间, 就适当降低该值; 如果释放了很少的空间,会适当提高该值( 如果设置了-XX:MaxMetaspaceSize,不会超过其最大值 )。这个跟早期jdk版本的-XX:PermSize参数意思不一样,-XX:PermSize代表永久代的初始容量。

由于调整元空间的大小需要Full GC,这是非常昂贵的操作,如果应用在启动的时候发生大量Full GC,通常都是由于永久代或元空间发生了大小调整,基于这种情况,一般建议在JVM参数中将MetaspaceSize和MaxMetaspaceSize设置成一样的值,并设置得比初始值要大,对于8G物理内存的机器来说,这两个值可以都设置为256M。

四、JVM对象的内存分配

1. 划分内存的方法:

“指针碰撞”(Bump the Pointer)(默认用指针碰撞)
        如果Java堆中内存是绝对规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间那边挪动一段与对象大小相等的距离。

“空闲列表”(Free List)
        如果Java堆中的内存并不是规整的,已使用的内存和空 闲的内存相互交错,那就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例, 并更新列表上的记录。

2. 解决并发问题的方法:

CAS(compare and swap)
         如果Java堆中的内存并不是规整的,已使用的内存和空闲的内存相互交错,那就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例, 并更新列表上的记录

本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)
        把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存。通过-XX:+/-UseTLAB参数来设定虚拟机是否使用TLAB

        JVM会默认开启-XX:+UseTLAB,-XX:TLABSize 指定TLAB大小。
JVM垃圾回收机制

一、串行GC(Serial GC)

串行GC是很简单的一种GC算法,它对年轻代使用 mark-copy(标记-复制) 算法,对老年代使用 mark-sweep-compact(标记-清除-整理)算法。而这两者都是单线程的垃圾收集器,并不能进行并行处理。因此,两者都会触发全线暂停(stop the world, STM),停止所有的应用线程。因此这种GC算法不能充分利用多核CPU。不管有多少CPU内核, JVM 在垃圾收集时都只能使用单个核心。

所以这种算法只适合于几面MB堆内存的JVM,在单核CPU的情况下使用。它的JVM参数配置如下:

java -XX:+UseSerialGC

二、并行GC(Parallel GC)

相对于串行GC而言,顾名思义,并行GC可以通过并行执行来减少GC时间,其使用的算法和串行GC一样,也是对年轻代使用 mark-copy(标记-复制) 算法,对老年代使用 mark-sweep-compact(标记-清除-整理)算法,但是在标记和复制/整理阶段都会使用多个线程。因此适用于多核处理器。它的JVM参数配置可以使用-XX:+UseParallelGC 或-XX:+UseParallelOldGC

三、CMS GC (Concurrent Mark Sweep GC)

CMS算法与以上两种算法一样,也是面向分代的垃圾回收算法,主要面向老年代进行垃圾收集,其尝试通过使用单独的垃圾收集器线程在执行应用程序线程的同时执行并跟踪可访问对象,来减少由于主要收集而导致的暂停时间。在并发标记阶段,CMS GC会把发生变化的对象所在的Card标识为Dirty,这样后续就只需要扫描这些Dirty Card的对象,从而避免扫描整个老年代。这样,就达到了减少应用停顿时间的目的。

CMS的问题在于堆内存碎片化问题无法得到解决,因此,JVM有可能会触发Full GC来进行碎片整理。

CMS GC的参数配置如下:

-XX:+UseConcMarkSweepGC

四、G1 GC

为克服CMS GC的缺点,在JDK1.7中引入了G1 GC,G1 GC在并发回收的同时,会对对象进行适合的移动,有效的复制对象,从而减少空间碎片的产生。在G1 GC中,如果清除步骤发现所有的区别都是由可回收垃圾组成的,则会立即回收这些空间,并且将这些空间插入到一个LinkedList实现的空闲队列里,这一特点也是G1 GC和其它GC的最大差别。

但是在一些特殊情况下,G1 GC可能会增加Java堆的尺寸。例如在Full GC中,基于堆尺寸的计算结果会调整堆的空间。或者在一个对象分配失败的时候,G1会尝试增加堆尺寸来满足对象分配等。

G1 GC涉及到的JVM参数如下,从JAVA 9开始,G1 GC是默认的GC算法,此前并行GC是默认算法:

-XX:UseG1GC

-XX:G1HeapRegionSize

-XX:G1MaxNewSizePercent

-XX:G1NewSizePercent

-XX:MaxGCPauseMillis

-XX:ConcGCThreads

-XX:ParallelGCThreads

-XX:G1MixedGCLiveThresholdPercent

-XX:InitiatingHeapOccupancyPercent

-XX:G1HeapWastePercent

-XX:G1OldCSetRegionThresholdPercent

-XX:G1MixedGCCountTarget

-XX:G1ReservePercent

-XX:MaxTenuringThreshold

五、Shenandoah GC

JDK12开始引入了Shenandoah GC,它的主要目标是使99.9%的停顿小于10ms,这种算法与其它GC算法的主要区别是引入了一个Concurrent Evacuation的过程,在这一过程中,JVM将对象集合从集合集复制到其它区别。

它的JVM参数配置如下:

-XX:+UseShenandoahGC

mybatis
非常重要:
SQL 映射文件:了解如何编写 MyBatis 的 SQL 映射文件,包括 SQL 语句、参数映射和结果映射。
数据库连接和事务管理:熟悉 MyBatis 的数据库连接配置和事务管理方式,如数据源配置、连接池和事务管理器。
重要:
动态 SQL:了解 MyBatis 的动态 SQL 功能,包括条件判断、循环和动态拼接 SQL 语句。
映射器接口和注解:了解如何使用 MyBatis 的映射器接口和注解方式,执行 SQL 操作和参数映射。
缓存机制:熟悉 MyBatis 的缓存机制,包括一级缓存和二级缓存的配置和使用方式。
参数传递和结果集处理:了解 MyBatis 中参数传递的方式,如基本类型、对象、集合和动态 SQL 参数等,以及结果集的处理方式。
一般:
插件开发:了解如何使用 MyBatis 插件机制,实现自定义的扩展功能。
分页支持:了解 MyBatis 的分页插件或分页查询方式,实现数据库结果集的分页查询。
高级映射和关联关系:了解 MyBatis 中的高级映射技术,如一对一、一对多、多对一和多对多的关联关系处理。
批量操作:了解 MyBatis 的批量插入、更新和删除操作,提高数据库操作的效率。
延迟加载:了解 MyBatis 的延迟加载机制,实现按需加载关联对象的功能。
动态数据源:了解如何使用 MyBatis 实现动态数据源切换的功能。

1.什么是MyBatis?它的主要特点是什么?

MyBatis是一个开源的持久层框架,用于将Java对象映射到关系型数据库的数据记录。它通过简化数据库访问的过程,提供了灵活的SQL映射和查询功能,使得开发者可以更方便地与数据库交互。

主要特点如下:
1.简化的SQL编写:MyBatis使用简洁的XML或注解配置方式,将SQL语句与Java代码分离,使得SQL的编写更加直观和易于维护。
灵活的映射方式:MyBatis支持将查询结果映射到POJO(Plain Old Java Object)对象或其他复杂的数据结构,可以通过配置来实现灵活的结果集映射。
2.参数映射:MyBatis支持将Java对象或基本数据类型映射到SQL语句中的参数,避免了手动拼接SQL字符串的繁琐过程。
3.缓存机制:MyBatis提供了一级缓存和二级缓存,可以有效地减少数据库访问次数,提高性能。一级缓存是默认开启的,而二级缓存需要手动配置开启,并且可以跨SqlSession共享。
4.声明式事务管理:MyBatis支持基于注解或XML配置的声明式事务管理,简化了事务管理的代码编写和管理过程。
5.插件机制:MyBatis提供了插件(Interceptor)机制,允许开发者自定义拦截器来扩展或修改MyBatis的行为,例如日志记录、性能监控等。
6.跨数据库兼容性:MyBatis具有很好的跨数据库兼容性,可以与多种关系型数据库进行交互,如MySQL、Oracle、SQL Server等。
7.良好的社区支持:MyBatis拥有活跃的社区,提供了丰富的文档、示例和讨论,可以帮助开发者解决问题和学习更多关于MyBatis的知识。
总之,MyBatis通过提供简单、灵活、高效的数据库访问解决方案,使得Java开发者能够更加便捷地进行数据库操作,提高了开发效率和系统性能。
2.MyBatis的工作原理是什么?请描述MyBatis的执行流程。

MyBatis的工作原理可以分为三个主要步骤:配置阶段、运行阶段和结果处理阶段。
下面是MyBatis的执行流程的详细描述:
1.配置阶段:
读取MyBatis的配置文件(XML或Java代码),其中包含了数据源、映射文件路径、插件配置等信息。
根据配置文件创建SqlSessionFactory对象,SqlSessionFactory是SqlSession的工厂类,用于创建SqlSession对象。
2.运行阶段:
使用SqlSessionFactory创建SqlSession对象,SqlSession是MyBatis的核心接口,用于执行SQL操作和管理事务。
通过SqlSession获取Mapper接口的实现类对象,Mapper接口定义了数据库操作的方法。
调用Mapper接口的方法,即执行SQL语句,MyBatis会根据方法名在映射文件中找到对应的SQL语句。
MyBatis将方法的参数映射到SQL语句中的占位符,执行SQL语句并获取结果。
3.结果处理阶段:
MyBatis将数据库返回的结果映射到指定的Java对象或其他数据结构。
如果有配置缓存,则将结果缓存起来,方便下次相同查询的快速返回。
将结果返回给调用方,完成数据库操作。

需要注意的是,MyBatis的执行流程是可定制和可扩展的。通过插件机制,可以在执行流程的不同阶段进行拦截和修改。插件可以实现自定义的功能,如日志记录、性能监控等。
总结起来,MyBatis的工作原理是通过配置文件创建SqlSessionFactory,然后通过SqlSession执行SQL操作,最后将结果映射到Java对象。这样的执行流程使得开发者能够灵活地操作数据库,同时提供了缓存、事务管理等功能来提高性能和可靠性。

3.MyBatis的核心组件有哪些?请简要描述它们的作用。

MyBatis的核心组件包括以下几个:
1.SqlSessionFactoryBuilder:用于创建SqlSessionFactory对象的构建器。通过配置文件或者编程方式创建SqlSessionFactory对象,它是SqlSession的工厂类。
2.SqlSessionFactory:是SqlSession的工厂类,用于创建SqlSession对象。它是单例模式,一般在应用初始化阶段创建并共享。
3.SqlSession:是MyBatis的核心接口,用于执行SQL操作和管理事务。它提供了各种方法来执行数据库的增、删、改、查操作,还可以获取Mapper接口的实现类。
4.Mapper接口:Mapper接口定义了数据库操作的方法,通过使用注解或XML配置的方式,将方法与具体的SQL语句进行绑定。Mapper接口不需要用户实现,MyBatis会动态生成Mapper接口的实现类。
5.Executor:是MyBatis执行器的接口,定义了SQL语句的执行方式。MyBatis提供了多种执行器实现,如简单执行器(SimpleExecutor)、复用执行器(ReuseExecutor)和批处理执行器(BatchExecutor)等。
6.StatementHandler:是执行器的核心组件,负责处理SQL语句的预处理、参数绑定、结果集映射等工作。
7.ParameterHandler:负责处理SQL语句中的参数,将Java对象或基本数据类型映射到SQL语句的占位符上。
8.ResultSetHandler:负责将数据库返回的结果集映射到Java对象或其他数据结构上。
9.TypeHandler:负责处理Java对象和数据库列之间的类型转换。MyBatis提供了一系列默认的TypeHandler,也可以自定义TypeHandler来处理特定的数据类型。
这些核心组件共同协作,实现了MyBatis的核心功能,包括SQL的解析、执行、结果映射等。SqlSessionFactoryBuilder用于创建SqlSessionFactory对象,SqlSessionFactory创建SqlSession对象,SqlSession执行SQL操作,Executor执行SQL语句,StatementHandler处理SQL语句,ParameterHandler处理参数,ResultSetHandler处理结果集,TypeHandler进行类型转换。通过这些组件的协作,MyBatis提供了简洁、灵活的数据库访问解决方案。
mybatis、mybatisPlus--详细版_陈小吨的博客-CSDN博客

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值