面试宝典(知识点总结)

本文总结了Java和Web开发中的关键面试知识点,包括Spring的IoC和AOP原理、事务处理、RabbitMQ消息不丢失策略、MyBatis的预编译与SQL注入预防、Java反射机制、存储过程与函数区别、数据库性能优化、HTTP协议、线程与多线程、设计模式、算法、Nginx和LVS负载均衡、以及Dubbo服务治理等。这些内容涵盖了从数据库设计、数据安全、服务器配置到分布式服务等多个领域,是面试准备的重要参考资料。
摘要由CSDN通过智能技术生成

spring ioc和aop原理

Spring核心容器的主要组件是Bean工厂(BeanFactory),Bean工厂使用控制反转(IoC)模式来降低程序代码之间的耦合度,并提供了面向切面编程(AOP)的实现。

IOC不通过程序代码直接控制。控制从应用程序代码传输到外部控制器,控制转移称为反向。

AOP称为面向方面编程,它使用一种称为“横切”的技术,并将影响多个类的公共行为包装到可重用模块中,并将其命名为“Aspect”,即“方面”。简单的说,它是封装与业务无关的逻辑或职责,但是由业务模块一起调用,例如日志记录,这样可以减少系统的重复代码,减少模块之间的耦合,并简化未来的运作性和可维护性。

AOP有两个明显的特征:良好的隔离性和源代码无关性。

AOP应用范围:debugging调试、synchronization同步、logging记录跟踪等。

Spring依赖注入的方式主要有四个,基于注解注入方式、set注入方式、构造器注入方式、静态工厂注入方式。推荐使用基于注解注入方式,配置较少,比较方便。


spring事务

七种传播机制

1、PROPAGATION_REQUIRED(若当前存在事务,则加入该事务,若不存在事务,则新建一个事务。)

2、PAOPAGATION_REQUIRE_NEW(若当前没有事务,则新建一个事务。若当前存在事务,则新建一个事务,新老事务相互独立。外部事务抛出异常回滚不会影响内部事务的正常提交。)

3、PROPAGATION_NESTED(如果当前存在事务,则嵌套在当前事务中执行。如果当前没有事务,则新建一个事务,类似于REQUIRE_NEW。)

4、PROPAGATION_SUPPORTS(支持当前事务,若当前不存在事务,以非事务的方式执行。)

5、PROPAGATION_NOT_SUPPORTED(以非事务的方式执行,若当前存在事务,则把当前事务挂起。)

6、PROPAGATION_MANDATORY(强制事务执行,若当前不存在事务,则抛出异常)

7、PROPAGATION_NEVER(以非事务的方式执行,如果当前存在事务,则抛出异常。)

四大特性

1、原子性:操作要么全部成功,要么全部失败回滚。

2、一致性:事务执行前和执行后处于一致性状态。例如,转账前A、B共5000元,A、B之间转账后,两者之和仍应该是5000元。

3、隔离性:事务之间互不干扰。

4、持久性:事务一旦提交,数据的改变是永久性的,即使这时候数据库发生故障,数据也不会丢失。

隔离级别

1、读未提交:隔离级别最差,脏读、不可重复读、幻读都不能避免。

2、读已提交:可避免脏读,不可重复读、幻读无法避免。

3、可重复读:可避免脏读、不可重复读,幻读无法避免。

4、序列化:事务顺序执行,可避免脏读、不可重复读、幻读,但效率最差。因为A事务执行时,其他事务必须等待。

注:

1、脏读:A事务对一条记录进行修改,尚未提交,B事务已经看到了A的修改结果。若A发生回滚,B读到的数据就是错误的,这就是脏读。

2、不可重复读:A事务对一条记录进行修改,尚未提交,B事务第一次查询该记录,看到的是修改之后的结果,此时A发生回滚,B事务又一次查询该记录,看到的是回滚后的结果。同一个事务内,B两次查询结果不一致,这就是不可重复读。

3、幻读:A事务对所有记录进行修改,尚未提交,此时B事务创建了一条新记录,A、B都提交。A查看所有数据,发现有一条数据没有被修改,因为这是B事务新增的,就想看到了幻象一样,这就是幻读。


RabbitMQ如何保证消息不丢失

https://www.cnblogs.com/flyrock/p/8859203.html

 


1、mybatis以及预编译,sql注入

MyBatis框架作为一款半自动化的持久层框架,其SQL语句都要我们自己手动编写,这个时候当然需要防止SQL注入。其实,MyBatis的SQL是一个具有“输入+输出”的功能,类似于函数的结构,如下:

<select id="getBlogById" resultType="Blog" parameterType=”int”>
    SELECT id,title,author,content
    FROM blog   WHERE id=#{id}
</select>

这里,parameterType表示了输入的参数类型,resultType表示了输出的参数类型。回应上文,如果我们想防止SQL注入,理所当然地要在输入参数上下功夫。上面代码中黄色高亮即输入参数在SQL中拼接的部分,传入参数后,打印出执行的SQL语句,会看到SQL是这样的:

SELECT id,title,author,content FROM blog WHERE id = ?

不管输入什么参数,打印出的SQL都是这样的。这是因为MyBatis启用了预编译功能,在SQL执行前,会先将上面的SQL发送给数据库进行编译;执行时,直接使用编译好的SQL,替换占位符“?”就可以了。因为SQL注入只能对编译过程起作用,所以这样的方式就很好地避免了SQL注入的问题。

【底层实现原理】MyBatis是如何做到SQL预编译的呢?其实在框架底层,是JDBC中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的SQL语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译。

话说回来,是否我们使用MyBatis就一定可以防止SQL注入呢?当然不是,请看下面的代码:

<select id="getBlogById" resultType="Blog" parameterType=”int”>
      SELECT id,title,author,content
      FROM blog  WHERE id=${id}
</select>

仔细观察,内联参数的格式由“#{xxx}”变为了“${xxx}”。如果我们给参数“id”赋值为“3”,将SQL打印出来是这样的:

SELECT id,title,author,content FROM blog WHERE id = 2
<select id="orderBlog" resultType="Blog" parameterType=”map”>
      SELECT id,title,author,content
      FROM blog  ORDER BY ${orderParam}
</select>

仔细观察,内联参数的格式由“#{xxx}”变为了“${xxx}”。如果我们给参数“orderParam”赋值为“id”,将SQL打印出来是这样的:

SELECT id,title,author,content FROM blog ORDER BY id

显然,这样是无法阻止SQL注入的。在MyBatis中,“${xxx}”这样格式的参数会直接参与SQL编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“${xxx}”这样的参数格式。所以,这样的参数需要我们在代码中手工进行处理来防止注入。

【结论】在编写MyBatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止SQL注入攻击。

#{}:相当于JDBC中的PreparedStatement

${}:是输出变量的值

简单说,#{}是经过预编译的,是安全的;${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。


2、java反射

1、通过Object类的getClass方法获取

2、使用.class的方法(类名.class)

3、使用Class.forName方法


存储过程和函数的区别

1、返回值不同。函数有一个返回值,而存储过程是通过参数返回的,可以有多个或没有;

2、调用不同。函数可在查询语句中直接调用,而存储过程必须单独调用。

 


varchar和nvarchar区别

1、varchar是非Unicode编码,nvarchar是Unicode编码;

2、varchar的最大值是8000,nvarchar是4000;

3、varchar能存储的字节数是它的长度,nvarchar能存储的字节数是它长度的2倍;

4、varchar比nvarchar更省空间。


表单重复提交解决办法?

前端:设置按钮只触发一次,提交按钮变灰。

后端:使用token+session

         第一步,用户调用后台接口;

         第二步,后台生成sessionToken传到前端;

         第三步,前端将sessionToken传到后台;

         第四步,后台将第一次生成的sessionToken和前端传来的sessionToken进行对比,如果一致就可以提交表单,不一致就表示表单重复提交了。


mysql大数据量存储

按规则进行分库分表


JDK1.8中HashMap的变化

1.8之前:HashMap处理“碰撞”的时候,都采用链表来存储,当碰撞的节点很多时,查询时间是O(n).

1.8中:HashMap处理“碰撞”增加了红黑树数据结构,当碰撞节点较少时,采用红黑树存储,当较大时(>8个),采用红黑树存储。


Redis缓存的优势

1、读写性能很高;

2、redis支持多种数据类型。存储的是key-value格式的数据,其中key是字符串,value的数据类型有String、list、set、hash(哈希)、有序集合zset(sorted  set);

3、非关系型数据库;

4、持久化:redis的持久化方式有rdb和aof两种;rdb是将内存中的数据压缩后写入到硬盘上,aof是将日志整理写到硬盘中,并设置不同的持久化方式,有效的额减轻了服务器的压力,同时在很大程度上防止了数据的丢失。


3、SpringCloud

组件

        Eureka(注册中心):各个服务启动时,Eureka Client都会将服务注册到Eureka Server,并且Eureka Client还可以反过来从Eureka Server拉取注册表,从而知道其他服务在哪里。由服务端和客户端组成;服务端:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值