前言:这几天一直在公司忙于学习公司的业务,很难抽出时间记录博客。之前投的简历在上周周末进行了面试,中等大小的公司,以下是问到的面试题,之前有记录过的此处会给出链接。希望能帮到各位想要找工作或者提高自己的小伙伴儿们,如果有什么需要改进的地方,还请大佬不吝赐教🤞🤞
小威在此先感谢诸佬了👏👏
🏠个人主页:小威要向诸佬学习呀
🧑个人简介:大家好,我是小威,一个想要与大家共同进步的男人😉😉
目前状况🎉:目前大二,在一家满意的公司实习👏👏🎁如果大佬在准备面试,找工作,刷算法,可以使用我找实习前用的刷题神器哦刷题神器点这里哟
💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,我亲爱的大佬😘
牛客部分使用反馈,个人感觉还不错,帮我找到了心仪的公司,希望各位伙伴儿们通过它也能提高不少🥂🥂🥂
以下正文开始
文章目录
- 🧃Mybatis中#{}和${}的区别
- 🍷Mysql的四大特性
- 🍹Linux常见的命令了解哪些
- 🥫HTTP和HTTPS的区别
- 🧉OSI模型有几层,分别是什么
- 🍺Get和Post有什么区别
- 🥂三次握手和四次挥手
- ☕SpringMVC的工作流程
- 🍸Redis的RDB和AOF文件
- 🍶算法题全排列
🧃Mybatis中#{}和${}的区别
首先说一下SQL注入
SQL注入是一种代码注入技术,用于攻击数据驱动的应用,恶意的SQL语句被插入到执行的实体字段中,攻击者在界面的表单信息或URL上输入一些奇怪的SQL片段(例如“or ‘1’=‘1’”这样的语句),有可能入侵参数检验不足的应用程序。
所以两种方式的区别就体现出来了:
1.#{变量名}可以进行预编译、类型匹配等操作,#{变量名}会转化为jdbc的类型。#方式能够很大程度防止sql注入;
2.$ {变量名}不进行数据类型匹配,直接替换。 方式无法方式sql注入。$ 方式一般用于传入数据库对象,例如传入表名;
3.#会自动加双引号,$不会加双引号。
这两个符号在mybatis中最直接的区别就是:#相当于对数据加上单引号,$相当于直接显示数据(只讨论字符串类型的)。
举个栗子:
-
#对传入的参数视为字符串,也就是它会预编译,
select * from user where name = #{name}
,比如我传一个xiaowei,那么传过来就是select * from user where name = 'xiaowei';
-
$ 将不会将传入的值进行预编译,
select * from user where name=${name}
,比如我传一个xiaowei,那么传过来就是select * from user where name = xiaowei;
-
#的优势就在于它能很大程度的防止sql注入,而 $ 则不行。比如:用户进行一个登录操作,后台sql验证式样的:
select * from user where username=#{name} and password = #{pwd}
,如果前台传来的用户名是“xiaoweihaoshuai”,密码是 “1 or 1=1”,用#的方式就不会出现sql注入,而如果换成$方式,sql语句就变成了select * from user where username=wang and password = 1 or 1=1
。这样的话就形成了sql注入。
🍷Mysql的四大特性
Atomicity(原子性):一个事务(transaction)中的所有操作,要么全部做完,要么全部不做,不会在中间某个环节结束。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
Isolation(隔离性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读已提交(read committed)、可重复读(repeatable read)和串行(Serializable)。
Durability(持久性):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
🍹Linux常见的命令了解哪些
目录切换:cd
目录查看:ls
创建目录:mkdir
删除目录或文件:rm -rf
拷贝目录:cp
新建文件:touch
修改文件:vi
查找命令: grep,find
让普通用户临时使用root权限,只需输入自己账户的密码:sudo
查看当前目录路径:pwd
查看进程:ps -ef
结束进程:kill -9 pid(-9 强制;pid:进程号)
切换用户:su
修改文件权限:chmod
🥫HTTP和HTTPS的区别
HTTP协议以明文方式发送内容,不提供任何方式的数据加密。HTTP协议不适合传输一些敏感信息。而https则是具有安全性的ssl加密传输协议。
HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。
🧉OSI模型有几层,分别是什么
OSI模型分为7层。
由最低层到高层依次是物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。
🍺Get和Post有什么区别
相同点:GET 和 POST属于OSI七层模型中的传输层,都是shttp请求方式, 底层都是 TCP/IP协议。
首先,get是从服务器上获取资源,而post方式是向服务器提交数据。
第二,get方式隐私性,安全性较差,这是由于get的参数会放到url的后面,get是把参数数据列加到提交表单的属性所指的url中,值和表单内各个字段一一对应,以name=value的方式,添加到前端界面action所指的url后面,并且用"?"进行连接,各个变量之间以“&”符号连接;而post方式是将表单中的数据放到Http协议中的请求头或消息体中。
第三,Get传输数据会受到URL的长度限制,而Post可以传输大量的数据,比如上传文件等。
get请求会被保存在浏览器历史记录当中,post不会。get请求可以被收藏为书签,因为参数就是url中,但post不能。它的参数不在url中
使用get方式时,数据会显示在地址栏上。
🥂三次握手和四次挥手
这个知识点之前有详细记录过,点击此处传送😉😉
☕SpringMVC的工作流程
- 前端发送请求被前端控制器DispatcherServlet拦截
- 前端控制器调用处理器映射器HandlerMapping对请求URL进行解析,解析之后返回调用给前端控制器
- 前端控制器调用处理器适配器处理调用链
- 处理器适配器基于反射通过适配器设计模式完成处理器(控制器)的调用处理用户请求
- 处理器适配器将控制器返回的视图和数据信息封装成ModelAndView响应给前端控制器
- 前端控制器调用视图解析器ViewResolver对ModelAndView进行解析,将解析结果(视图资源和数据)响应给前端控制器
- 前端控制器调用视图view组件将数据进行渲染,将渲染结果(静态视图)响应给前端控制器
- 前端控制器响应用户请求
组件说明
DispatcherServlet:前端控制器,也称为中央控制器,它是整个请求响应的控制中心,组件的调用由它统一调度。
HandlerMapping:处理器映射器,它根据用户访问的 URL 映射到对应的后端处理器 Handler。也就是说它知道处理用户请求的后端处理器,但是它并不执行后端处理器,而是将处理器告诉给中央处理器。
HandlerAdapter:处理器适配器,它调用后端处理器中的方法,返回逻辑视图 ModelAndView 对象。
ViewResolver:视图解析器,将 ModelAndView 逻辑视图解析为具体的视图(如 JSP)。
Handler:后端处理器,对用户具体请求进行处理,也就是我们编写的Controller 类。
🍸Redis的RDB和AOF文件
可以参考之前写的Redis相关知识点,点击此处传送
RDB和AOF都有各种的优缺点,如果对数据安全性要求高,在实际开发中往往会结合两者来使用。
持久化方式:
RDB定时对整个内存做快照;而AOF记录每一次执行的命令;
数据完整性:
RDB不完整,两次备份之间会丢失数据;AOF相对完整,取决于刷盘策略;
文件大小:
RDB会有压缩,文件体积小;而AOF记录命令,文件体积很大;
宕机恢复速度:RDB很快;而AOF慢,因为要执行一遍命令;
数据恢复优先级:
RDB低,因为数据完整性不如AOF,AOF高,因为数据完整性更高。
系统资源占用:
RDB占用高,大量CPU和内存消耗;而AOF占用低,主要是磁盘IO资源,但AOF重写时会占用大量CPU和内存资源。
使用场景:
RDB在可以容忍几分钟的数据丢失,追求更快的启动速度时使用比较合适;
AOF主要在对数据安全性要求较高时比较常见。
🍶算法题全排列
面试中问到了一道经典的算法题,经典的回溯题案例,想学习的朋友们往下试着写写哟。
题目:
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例 1:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例 2:
输入:nums = [0,1]
输出:[[0,1],[1,0]]
示例 3:
输入:nums = [1]
输出:[[1]]
题解如下:
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res=new ArrayList<List<Integer>>();//存放最终结果
boolean[] isused=new boolean[nums.length];//值是否被用到过
List<Integer> list=new ArrayList<Integer>();//每次循环符合情况的结果
dfs(nums,isused,res,list);
return res;
}
private void dfs(int[] nums,boolean[] isused,List<List<Integer>> res,List<Integer> list){
if(list.size()==nums.length){
res.add(new ArrayList<Integer>(list));
return ;
}
for(int i=0;i<nums.length;i++){
if(!isused[i]){
isused[i]=true;
list.add(nums[i]);
dfs(nums,isused,res,list);
list.remove(list.size()-1);
isused[i]=false;
}
}
return ;
}
}
文章到这里就结束了,以后还会记录一些其他的知识,喜欢的大佬可以多多支持哦😉😉。
如果有什么疑问的地方请指出,诸佬们一起讨论🍻🍻
最后再次给大家安利一波牛客,牛客真的很不错的软件,点击刷题神器
注册牛客,快来和博主一起刷题吧嘿嘿嘿👏
同时祝伙伴儿找到理想的工作及猛猛地提升算法能力哦😏
再次感谢各位小伙伴儿们的支持🤞