前言:这周还好,在公司没有前几周忙。最近又面试了一家公司,一不小心投了简历没想到让面试了,以下是问到的面试题,之前有记录过的此处就不记录了,问的项目问题也不展示了,毕竟做的项目都不一样。希望能帮到各位想要找工作或者提高自己的小伙伴儿们,如果有什么需要改进的地方,还请大佬不吝赐教🤞🤞
小威在此先感谢诸佬了👏👏
🏠个人主页:小威要向诸佬学习呀
🧑个人简介:大家好,我是小威,一个想要与大家共同进步的男人😉😉
目前状况🎉:目前大二,在一家满意的公司实习👏👏🎁如果大佬在准备面试,找工作,刷算法,可以使用我找实习前用的刷题神器哦刷题神器点这里哟
💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,我亲爱的大佬😘
牛客部分使用反馈,个人感觉还不错,帮我找到了心仪的公司,希望各位伙伴儿们通过它也能提高不少🥂🥂🥂
以下正文开始
文章目录
- 🍣SQL语句是如何优化的
- 🍱串行,并行,和并发的区别
- 🥩字节流和字符流有什么区别
- 🍤Spring的AOP如何理解
- 🍛抽象类与接口的区别
- 🍖B+树为什么优于B树
- 🦪常见的状态码有哪些
- 🍹最接近的三数之和
🍣SQL语句是如何优化的
- 在where,orderby查询优化涉及到的字段上建立索引,避免全局扫描;
- 书写语句时,应列出具体的字段,尽量不用 “*” 代替,否则影响执行效率;
- 在使用组合索引时,应遵循最左匹配原则,比如组合索引为a,b,c时,在执行语句where b=1 and a=1时,此时会走索引,因为MySQL内部会自动优化为a=1 and b=1;然而执行语句where b=1 and c=1 时,此时不会走索引,不符合最左匹配原则,而且当子句为where a=1 and b > 1 and c=1时,此时只有a和b走索引,c不走索引,因此在保证使用最左匹配原则的基础上,范围查询between,>,<,like尽量不要使用;
- 应避免在有大量字段重复值的字段上建立索引,比如性别sex,年龄age等,即使创建了索引,用处也不是很大;
- 尽量避免在where子句后面的字段进行一些判断。如:大于>,小于<, !=,null值判断(where name is null),in 和 not in 等,也要尽量避免在where 子句中使用 or 来连接条件,这些都可能会导致在查询时不走索引而进行全局扫描。
- 索引虽然能大大增加我们的执行效率,但过多的索引会占用内存,因此在设计索引时要考虑在经常用到的字段上建立索引;
- 尽量不要在where后面的子句中对字段进行运算,函数等操作,这可能导致数据库走全局扫描;
- 尽量不要在经常变化的字段上建立索引;
- 在创建字符型字段时,应尽量用可变长度类型varchar代替char,这样可以内存空间可以保障,搜索效率也会变高;
- 可以使用explain关键字来分析在查询等操作时是否走了索引,走了哪些索引,以及索引类型等,能够帮助我们改进SQL语句。
🍱串行,并行,和并发的区别
串行是指如果有多个任务需要执行,先执行一个任务,等待该任务完成后,再执行另一个任务,两个任务执行的时间不会发生重叠。
串行比较好理解,接下来解释一些并发和并行。
并发概念:是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。(两个或多个事件在同一时间间隔内发生,这些事情宏观上是同时发生的,但微观上是交替发生的)
而并行是指:两个或多个事件在同一时刻同时发生
两者区别
- 概念不同
并发:并发是指两个或多个事件在同一时间间隔发生
并行:并行是指两个或者多个事件在同一时刻发生。- 侧重点不同
并发侧重于在同一实体上
并行:并行侧重于在不同实体上- 处理不同
并发:并发在一台处理器上“同时”处理多个任务。
并行:并行在多台处理器上同时处理多个任务
🥩字节流和字符流有什么区别
1.两者组成不同
字节流是由字节组成的,而字符流是由字符组成的。
2.两者结尾不同
字节流以stream结尾(如inputStream和outputStream);而字符流以reader和writer结尾
3.两者处理数据的方式不同字节流主要用于处理二进制数据,它是按字节来处理的;而字符流按虚拟机的encode编码来处理,也就是要进行字符集的转化
4.字节流和字符流每次读写的字节数不同:
在Java编程语言中,字符由两个字节组成。
字符流是块读写,字节流是字节读写;
而且字符流有缓存,字节流没有。
🍤Spring的AOP如何理解
Aspect Oriented Programming面向切面编程,AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,它是一种利用“横切”的技术(底层实现就是动态代理),可以使用jdk,cglib两种代理方式,对原有的业务逻辑进行拦截,并且可以在这个拦截的横切面上添加特定的业务逻辑,对原有的业务进行增强,基于动态代理实现在不改变原有业务的情况下对业务逻辑进行增强。
AOP和OOP区别:
OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分。
而AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。这两种设计思想在目标上有着本质的差异。
AOP中的术语:
Joint point:连接点,说白了就是程序中的方法。表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。
Aspect:切面,表示定义切点的方法的类, Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。
Pointcut:切点。就是添加到切入点的新增的业务方法,表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
Advice:通知,也可以叫做方法增强,表示的是配置新增的业务的配置方式(是在切入点的前面还是后面)Advice 定义了在 pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
AOP通知策略:就是声明将切面类中的切点方法如何织入到切入点
• before
• after
• after-throwing
• after-returning
• around
下面进行解释:
注解中的AOP:
<aop:config>
<!-使用aop:pointcut标签声明切入点:切入点可以是一个方法-->
<aop:pointcut id="book_insert" expression="execution(★
com.dao.BookDA0Impl.insert())"/>
caop:aspect ref="myAspect">
<!--aop:before 前置通知,切入到指定切入点之前-->
<aop:before method="method1" pointcut-ref="book_insert"/>
<!--aop:after 后置通知,切入到指定切入点之后-->
<aop:after method="method2" pointcut-ref="book_insert"/>
<!--aop:after-throwing 异常通知,切入点抛出异常之后-->
<aop:after-throwing method="method3" pointcut-ref=“book_insert"/>
<!--aop:after-returning 方法返回值返回之后,对于一个Java方法而言return返回值也是方法的一部分因此“方法返回值返回之后”和“方法执行结束”是同一个时间点,随意after和 after-returning根据配置的顺序决定执行顺序-->
<aop:after-returning method="method4" pointcut-ref=“book_insert"/>
<aop:around method=“method5" pointcut-ref="book_insert"/>
</aop:aspect>
🍛抽象类与接口的区别
首先解释什么是抽象类:
将类与类之间的共同特征提取出来,就可以形成抽象类。
抽象类不能直接实例化对象,但可以使用多态即父类的引用指向子类的对象,抽象类作为父类。
什么是接口:
接口可以看做特殊的抽象类,当然接口也无法实例化和创建对象,在使用时也可以使用多态,父类的引用指向子类的对象,这里的父类就是接口。
区别:
- 抽象类体现的是继承关系(extends),接口体现的是实现关系(implements),一个类可以实现多个接口,而类只能继承一个抽象类。
- 抽象类中可以定义,普通方法,静态方法,抽象方法,提供给子类使用,而接口中的方法都是抽象的,接口中的成员都有固定的修饰符。
- 抽象类中可以有构造方法,而接口中不可以有构造方法
- 抽象类中的抽象方法的访问类型可以是public,protected,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
🍖B+树为什么优于B树
b+树的中间节点不保存数据,可以容纳更多的节点元素
所有的叶子结点使用链表相连,有助于区间查找和遍历
B+树的内部节点只存放键,不存放值,因此,一次读取,可以在内存页中获取更多的键,有利于更快地缩小查找范围。 B+树的叶节点由一条链相连,因此,当需要进行一次全数据遍历的时候,B+树只需要使用O(logN)时间找到最小的一个节点,然后通过链进行O(N)的顺序遍历即可。而B树则需要对树的每一层进行遍历,这会需要更多的内存置换次数,因此也就需要花费更多的时间
B树的话,就需要进行每一层的递归遍历
相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好
🦪常见的状态码有哪些
这里以图片形式展示
🍹最接近的三数之和
题目:
给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
示例 1:
输入: nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
示例 2:
输入:nums = [0,0,0], target = 1
输出:0
class Solution {
public int threeSumClosest(int[] nums, int target) {
// 排序
Arrays.sort(nums);
int closestNum = nums[0] + nums[1] + nums[2];//先将前三个值相加
for (int i = 0; i < nums.length - 2; i++) {//移动到倒数第三个代表到头了
int l = i + 1, r = nums.length - 1;
while (l < r){
int threeSum = nums[l] + nums[r] + nums[i];
if (Math.abs(threeSum - target) < Math.abs(closestNum - target)) { //绝对值判断赋值操作
closestNum = threeSum;
}
if (threeSum > target) { //移动
r--;
} else if (threeSum < target) {
l++;
} else {
// 如果已经等于target的话, 肯定是最接近的
return target;
}
}
}
return closestNum;
}
}
文章到这里就结束了,以后还会记录一些其他的知识,喜欢的大佬可以多多支持哦😉😉。
如果有什么疑问的地方请指出,诸佬们一起讨论🍻🍻
最后再次给大家安利一波牛客,牛客真的很不错的软件,点击刷题神器
注册牛客,快来和博主一起刷题吧嘿嘿嘿👏
同时祝伙伴儿找到理想的工作及猛猛地提升算法能力哦😏
再次感谢各位小伙伴儿们的支持🤞