丧心病狂的面试知识

设计模式

  1. 单例模式(线程安全的对象发布写法)
  2. 工厂模式
  3. 代理模式(实现代理模式的方式有哪些 jdk的invocationHandler,基于接口 ,cglib,(MethodInterceptor)基于方法)
  4. 享元模式:主要用于减少创建对象的数量,以减少内存占用和提高性能。尝试重用现有的同类对象。
  5. 迭代器模式(Iterator):对外不暴露内部的数据结构,提供统一的接口,实现next,hashNext的访问数据的基本功能
设计模式 设计模式应用场景
单例模式 连接池,线程池,工厂类
工厂模式
代理模式 功能增强,比如日志处理,权限判断等等
享元模式 java 中的string,如果有就返回,否则创建并保存到字符串缓存池;数据库的数据池
迭代器模式 隐藏内部数据结构,对外提供统一的数据访问方式

面向对象的特点

  1. 封装,继承,多态

软件设计原则:

  1. 开闭原则:对扩展开放,对修改关闭,需要增加新功能,增加一个实现接口的具体类就好了
    比如伪代码: 判断武器类型,给出伤害值
  2. 里氏代换原则: 开闭原则的补充,(保障基类的可复用性)
  3. 迪米特原则:类与类的少了解,即类只需要知道依赖类必须知道的方法,减少类之间的联系,只需要知道关心的方法,不要过多的依赖
  4. 依赖倒置:调用者不依赖被调用者(具体实现),而是依赖抽象,被调用者的具体实现发生更改,后续,被调用者可以被无感替换
  5. 接口隔离: 接口定义要最小化,就是接口只专注一个领域,不要大而全,要小而细。Cloneable 接口只负责克隆

数据结构

  1. 数组与链表(连续内存与非连续内存,随机访问效率,删除效率不一样)

  2. 排序算法实现以及时间,空间复杂度,改良分析

  3. 堆和栈

  4. 二叉树,搜索树,完全二叉时,满二叉树,哈夫曼树(最优树)

  5. 二叉树的递归遍历,借助栈的非递归遍历

  6. 字典树(原理以及应用场景,可能的优化角度)

  7. B 树,B+树,特点,以及应用场景(数据库索引)

  8. 邻接矩阵与邻接表

  9. 查找

  10. hash法,hash冲突的解决方式(可能会考虑到redis集群时的hash算法)
    冲突解决方法:开放地址法(线性探测(删除比较麻烦,只能标记为删除)
    随机探测(步长随机数序列))
    拉链法(指针数组+链表)

  11. 深度优先于广度优先
    广度优先:类比成树中 层次遍历
    深度优先:类比树中序遍历

  12. 图的基本概念
    无向图:
    有向图:
    表示方式:
    邻接表:
    邻接矩阵:

  13. 最短路径(算法)
    **单源最短路径:dj(贪心算法),**使用一维数组D[i] 记录起点到i的最短距离,
    如果起点v0 到i需要经过 k,则D[i]=min{d[i],D[k]+e(k,i)}
    多源最短路径:floyd(dp)
    d[i] [j] 表示i与j之间的最短距离
    递推公式: d[i][j]=min(d[i][j],d[i][k]+d[k][j]);

  14. 最小生成树
    可使用贪心算法:

算法名 描述 使用场景,复杂度
prims 设点集为S,已选取点为S1,未选取点集为S-S1, 1,初始化,选取第一个点2, 遍历 已选取点和未选取点之间最小边,并将该点加入S1,直到S-S1为空,完成 时间复杂度:o(n 2 ^2 2),与边数目无关,适用于稠密图
cruskal 1.初始化 将边按照从小到大排列,所有点看成是孤立的;2,依次选取边, 如果该边的两个端点在同一个连通图中,则跳过;否选取该边;3,重复2直到只剩一个连通图,这就得到最小生成树 复杂度:o(elge) ,e是边的条数,这里主要是排序来体现的,适合于稀疏图
查找方式 数据结构 时间复杂度
顺序查找 顺序存储,链式存储 顺序存储(o(1)),链式存储o(n)
随机查找 顺序存储(o(1)),链式存储o(n)
二分查找 有序顺序存储结构 o(lgn)
hash查找 o(1)
索引查找 o(lgn)+o(k) 先使用二分查找找到块,然后在块中顺序查找

spring

  1. servlet
    Servlet对象只会创建、初始化一次,如果有多个请求同时访问,会从线程池中获取一个线程还是用这个Servlet对象处理用户请求,算是单例多线程,这就会带来一个问题,线程安全问题,访问特别是修改Servlet类中的全局变量时会导致数据错误,所以尽量不使用在Servlet类中声明全局变量。实在不行就需要给线程加锁。
  2. springMvc 的流程

请求-》前端控制器(dispatchServlet)->调用处理映射器(HandlerMapping),生成处理器对象以及处理拦截器->DispatchServlet(前端控制器)->调用处理适配器进一步调用处理器-》执行处理器( Controller)->返回ModelAndView给dispatchServlet,传递modelAndView -》ViewResolver(视图解析器)-》返回具体View ->DispatchServlet对View 进行渲染-》响应用户
在这里插入图片描述

  1. springmvc 的控制器是单例,线程问题怎么解决?(用同步会影响性能,不要写字段)
  2. 简述IOC,DI
    IOC:是控制反转

创建对象的权限:由开发者new 交由spring 去创建(需要将类的全限定名配置到xml文件中,spring底层根据反射去创建对象)
不使用ioc时:
A a=new A();
使用ioc后 A a=SpringContext.getBean("");

DI:是依赖注入(注入方式:构造+settter,一般使用后者)
3. spring中的bean有些什么类型?
4. spring 线程安全吗?
大多数bean 是单例的,而且spring并没有考虑线程安全,但是大多数bean是无状态的
每个bean自身的设计。不要在bean中声明任何有状态的实例变量或类变量,如果必须如此,那么就使用ThreadLocal把变量变为线程私有的,如果bean的实例变量或类变量需要在多个线程之间共享,那么就只能使用synchronized、lock、CAS等这些实现线程同步的方法了。
下面将通过解析ThreadLocal的源码来了解它的实现与作用,ThreadLocal是一个很好用的工具类,它在某些情况下解决了线程安全问题(在变量不需要被多个线程共享时)。
5. FactoryBean 与BeanFactory 的区别
BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于管理Bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
 FactoryBean 以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean接口的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获取FactoryBean对象,请在id前面加一个&符号来获取。

  1. 声明式事务的类型(xml+注解)
    优点:避免侵入业务代码,配置方便,便于管理
  2. 事务的特性
特性 描述
原子性 将事务中所做的操作捆绑成一个原子单元,即对于事务所进行的数据修改等操作,要么全部执行,要么全部不执行。
隔离性 由并发事务所做的修改必须与任何其他事务所做的修改相隔离。事务查看数据时数据所处的状态,要么是被另一并发事务修改之前的状态,要么是被另一并发事务修改之后的状态,即事务不会查看由另一个并发事务正在修改的数据。这种隔离方式也叫可串行性
持久性 事务完成之后,它对系统的影响是永久的,即使出现系统故障也是如此
一致性 事务在完成时,必须使所有的数据都保持一致状态,而且在相关数据中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构都应该是正确的

9. 如何实现分布式事务

没有应用场景,个人分析,分布式事务的产生是由于某个业务操作需要在
本地事务的实现当然很简单,加上Transactional 注解
如果是分布式事务:
方案一:2PC 提交
前提:
存在一个节点作为协调者,其他节点作为参与者,节点间可以相互网络通信
所有节点采用预写日志,并且日志保存在可靠的存储设备上,即使节点损坏也不会导致日志丢失
所有节点都不会永久性损坏(损坏后可以恢复)

阶段 说明
投票 本地执行事务成功(各节点事务信息写入redo,undo日志)的节点发消息给协调者,内容是"同意",如果某个节点执行失败,返回消息"终止"
提交执行阶段 如果协调者收到的回复全部是"同意",协调者发起消息"正式提交",节点正式完成操作,参与者节点返回"完成"信息,协调者如果收到全部都回复为"完成"时,完成事务; 如果出现一个"终止",协调者向所有参与节点发起"回滚"请求,参与者节点利用之前的undo日志,执行回滚操作,然后发送给协调者"回滚完成",收到所有参与者的回滚完成消息后,协调者取消事务

  1. 如何实现以下场景; 一个业务处理,包含两个操作,如何实现操作b 失败时,a操作事务不回滚,只是回滚b操作
//1. 获取连接
conn=getConn();
SavePoint savePoint=null;
// 2. 关闭自动提交事务  conn.setAutoCommit(false)
try{

A(发工资);
savePoint=conn.setSavePoint();

B(工资发放通知短信)(出现异常,如果A也回滚,那么就没工资了)
}catch(Exception e){
if(savePoint!=null){
// 说明 A 发工资是没有异常,那么就是B 发短信出现了异常
A 需要提交
conn.rollBack(savePoint);
conn.commit();
}
// A 操作出错,全部回滚
else{
conn.roolBack();
}
}
  1. spring aop 的实现方式
    基于注解,基于配置
-  核心是定义切点:需要被增强的方法
 -  定义通知:具体要增加的功能
-    定义切面:切点与通知组合形成切面
-  定义代理工厂对象(ProxyFactoryBean):将目标对象,切面组合,目标对象接口组合到一起用于制造代理对象

    <!--1,配置切点(需要被增强的方法) 拦截doSth 结尾的方法-->
    <bean id="myPointCut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
        <property name="pattern" value=".*study"/>
    </bean>
    <!-- 2,创建通知-->
    <bean id="myAdvice" class="top.forethought.framework.aop.xml.StudyAdvice">
    </bean>
    <!--3,创建切面(通知与切点组合在一起成为切面-->
    <bean id="<
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值