阿里本地生活一二三面

发布时间:2024-11-14 21:54
文章目录 一、问题二、复盘1. 动态代理2. 红黑树的左右旋3. 触发 Full GC4. 类加载的应用场景5. 排序问题6.Spring MVC7. Spring 事务8.拦截器9. int 型的数组,随机返回数组里 n 个数10. B 树11. 快排思路 & top k 问题12. 泛型 一、问题 在项目中的体会Java 的几种动态代理(答:JDK 提供的)红黑树【本质:二叉查找树】的左旋、右旋什么时候触发 Full GC :关于老年代回收,有个 JVM 参数配置,可以配置比例、年龄。类加载开发模式的应用场景10G 大小的文件进行排序,讲一下归并排序的思路缓存技术用过吗
【未解决】Spring MVC 的介绍、架构、处理请求的流程、拦截器【链式处理】Spring 事务数据库的查询优化【like 这样的模糊匹配性能是不高的】int 型的数组,随机返回数组里 n 个数B树的特性,B+树,B+树的插入快排和堆排向堆中插入数据top n 大Java 用泛型 和 C 做对比的优势如果两个对象能用 equals 方法进行对比,需要有哪些约束项目 WebSocket 是什么库的 设计思路用户是怎么加入进来的,怎么群发的如果人很多,怎么办 二、复盘 1. 动态代理 动态代理的特点:
字节码随用随创建,随用随加载动态代理的作用:
不修改源码的基础上,增强方法分类
(1)基于接口的
涉及的类:Proxy
提供者:JDK 官方
创建代理对象过程:
使用 Proxy 类中的 newProxyInstance 方法,
要求:被代理类至少实现一个接口,否则不能使用
        newProxyInstance 的参数:
ClassLoader 类加载器
    用于加载代理对象字节码,和被代理对象使用相同的类加载器
Class[ ] 字节码数组
    用于让代理对象和被代理对象有相同方法
InvocationHandler 用于提供增强的代码
    让写如何代理的,一般写该接口的实现类,通常情况下都是匿名内部类

(2)基于子类的
涉及的类:Enhoncer
提供者:第三方 cglib 库
创建代理对象:
使用 Enhoncer 类的 create 方法
要求:被代理类不能是 final 类
        Enhoncer 的 create 方法,有 2 个参数:
class 类型:
指定被代理对象的指定字节码
callback 类型:
用于实现方法的增强,一般是该接口的子接口实现类:
MethodInterceptor

2. 红黑树的左右旋

右旋——自己变为左孩子的右孩子;
左旋——自己变为右孩子的左孩子。

3. 触发 Full GC

    JDK 6 之后规定 只要老年代的连续空间大于 新生代对象总大小 或者 历代晋升的平均大小 就会进行 Minor GC,否则会进行 Full GC 。
    

4. 类加载的应用场景 资源隔离热部署代码保护
资源隔离:
    相同的包名类名,不同的方法调用,可以使用ClassLoader。
热部署:
    Tomcat容器,每个WebApp有自己的 ClassLoader ,加载每个 WebApp 的 ClassPath 路径上的类,一旦遇到 Tomcat 自带的 Jar 包就委托给CommonClassLoader加载。
代码保护:
    对于公司的一些核心类库,可能会把字节码加密,这样加载类的时候就必须对字节码进行解密,可以通过 findClass 读取 URL 中的字节码,然后加密,最后把字节数组交给defineClass()加载 Tomcat 中的类加载器:
    Java 中 ,类加载器是一种 父子关系数来组织的,除了 BootStrap 之外,都会包含一个 父类加载器。
    Tomcat 中,涉及到的 类加载器 大概有以下几类:
(1)BootStrap 和 System 用于加载 Java 基础类
(2)Common 和 WebappX
Common 类加载器
    一般来说,这个类加载器用来加载一些 既需要 Tomcat 容器内 和 所有应用 共同可见的 class,应用的 class 不建议放到这儿加载
Webapp 类加载器 相对于 传统的 Java 类加载器,最主要的区别:
子优先:
    也就是说 在 Web应用 内,需要加载一个类的时候,不是先委托给父类加载器,而是先自己加载,在自己的类路径上找不到才会再委托父类。
    为什么需要子优先呢?假如两个应用内 使用了相同命名空间里的一个 class ,一个使用 Spring 2.x,一个使用 Spring 3.x,如果是 父类加载期先加载的话,在第一个应用加载后,第二个应用再需要时,就直接从父类加载器中拿到了,但是却不符合需要。
    另外有一点,各个 Web 应用的类加载器,是相互独立的,即 WebappClassLoader 的多个实例,只有这样,多个应用之间 才可能使用不同版本的 相同命令空间下的类库,而互不影响。
    该类加载器会加载 Web 应用的 WEB-INF/classes 内的 class 和 资源文件,以及 WEB-INF/lib 下的所有 jar 文件。
    (如果需要按照传统的 Java类加载器加载 Class 的话,Tomcat 提供了配置,可以实现父优先。) 5. 排序问题

    假设 1G内存, 10G 数据,将 10G数据 切分成 10份 ,通过内存调用磁盘的方式,每1G进行排序,排序结束后,我们会得到10个有序的数据数组。
    归并:多路归并过程可以使用最小堆。
    内存中开辟一个大小为 10 的最小堆,和一个缓冲区(小于1G,不要太小)。
    取 10 份排序好的数据的首位进入最小堆。则最小的数位于堆顶,移除堆顶元素并写入缓冲区,然后从移除元素的元素所属数组中的下一位进入最小堆,在次移除堆顶进入缓冲区…直到缓冲区满,缓冲区回写磁盘,清空缓冲区,再次将数据置入最小堆…
    直到10份数据全部写完,然后将最小堆的元素按顺序回写磁盘即可。

归并排序的思路:
    先把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排序的两部分合并在一起,这样整个数组就有序了。

6.Spring MVC

(1) 介绍
Web 经典三层构造:表现层、业务逻辑层 、数据访问层 DAO,Spring MVC 为 表现层 提供了一个框架,

传统MVC
M(model)模型层,用来管理类与类之间的关系。
V(View视图层),如浏览器端显示的HTTP响应与请求;
C(Control)控制层,用来调用相应的构造。
这样不同功能的模块不会相互耦合。

Spring用于M层,管理类与类之间的关系,而 SpringMVC 则是用于C层。

(2)流程说明
①用户发送请求至前端控制器 DispatcherServlet。
②DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器。处理器映射器根据请求 url 找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。
③DispatcherServlet 通过 HandlerAdapter 处理器适配器调用处理器。
④HandlerAdapter 执行Controller层中的对应方法。
⑤Controller 执行完成返回 ModelAndView 或 ViewName。 HandlerAdapter 将 handler 执行结果 ModelAndView 返回给 DispatcherServlet。
⑥DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器。
⑦ViewReslover 解析后返回具体 View 对象。 DispatcherServlet 对 View 进行渲染视图(即将模型数据填充至视图中)。
⑧DispatcherServlet 响应用户。

7. Spring 事务

见 https://blog.csdn.net/weixin_41750142/article/details/105669429

8.拦截器

    Spring MVC 的处理器拦截器 类似于 Servlet 开发中的过滤器 Filter ,用于对处理器进行 预处理 和 后处理。用户可以自定义一些拦截器来实现特定的功能。它是 AOP 思想的具体应用。要自定义拦截器,必须实现 HandlerInterceptor 接口。
    说到拦截器,还有一个——拦截链(Interceptor Chain),拦截器链是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按照之前定义的顺序被调用。
❀ 过滤器 与 拦截器 之间的区别:❀
(1)过滤器 是 Servlet 规范的一部分,任何 Java Web 工程中都可以使用。
(2)拦截器是 Spring MVC 框架的一部分,只有使用 Spring MVC 框架的工程才能使用。
(3)过滤器在 url-pattern 中配置了 /* 之后,可以对所有要访问的资源拦截。
(4)拦截器是只会拦截要访问的控制器方法,如果访问的是 jsp、html、css、image 或者 js 是不会进行拦截的。

编写 拦截器:
实现 HandleInterceptor 接口

//自定义拦截器 public class MyInterceptor1 implements HandlerInterceptor { //预处理,如果返回true 说明执行下一个拦截器;否则要执行controller 类中的方法 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) ... ... //后处理方法,在 controller 类方法执行之后,success.jsp 执行之前 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("后处理执行了"); } //最后执行 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("最后"); }

12345678910111213141516171819

在 SpringMVC.xml 中配置拦截器① 预处理方法,可以做一些逻辑判断:

<!--配置拦截器--> <mvc:interceptors> <mvc:interceptor> <!--要拦截的具体方法--> <!--所有方法都拦截--> <mvc:mapping path="/user/*"/> <!--不用拦截的方法--> <!--mvc:exclude-mapping path=""/--> <!--配置拦截器对象--> <bean class="com.jia.interceptor.MyInterceptor1"/> </mvc:interceptor> </mvc:interceptors> 1234567891011121314 9. int 型的数组,随机返回数组里 n 个数

    思想:每次产生一个随机数,在arr数组中取出相应的元素,每次对选中的元素和最后元素交换以下,下一次生成随机数的时候就在前m-1个元素中生成,这样每次只要交换一次元素,就不用去那个数组中判断当前下标是否已经被生成过一次,时间复杂度变成O(m)

10. B 树

(1)树
    由 n 个有限节点组成的具有层次关系的集合。像倒挂的树,是根朝上,叶朝下的,特点:

每个节点有 0 或 多个子节点。没有父节点的节点被称为根节点。每个非根节点 有且只有一个 父节点。除了根节点以外,每个子节点 可以分为 多个不相交的子树。

    有两种实现方式:顺序——数组 / 链表。
(2)二叉树
特点:

每个结点最多有两颗子树,即二叉树不存在 度 【最大的 节点拥有子树的个数】大于 2 的节点。二叉树的子树有左、右之分,次序不能颠倒。
特殊的⼆叉树:满⼆叉树:
    ⼀个⼆叉树,如果每⼀个层的结点数都达到最⼤值,则这个⼆叉树就是满⼆叉树。也就是说,如果⼀个⼆叉树的层数为K,且结点总数是(2^k) -1 ,则它就是满⼆叉树。完全⼆叉树:
    完全⼆叉树是效率很⾼的数据结构,完全⼆叉树是由满⼆叉树⽽引出来的。对于深度为 K 的,有 n 个结点的⼆叉树,当且仅当其每⼀个结点都与深度为 K 的满⼆叉树中编号从 1 ⾄ n 的结点⼀⼀对应时称之为完全⼆叉树。 ✨要注意的是满⼆叉树是⼀种特殊的完全⼆叉树。✨ 11. 快排思路 & top k 问题

    分治的思想,比如要排序的是下标从 p 到 r 之间的一组数据,选择 p 到 r 之间的任意一个数据作为分区点 pivot 分区点,然后遍历 p 到 r 之间的数据,将小于 pivot 的放到左边,将大于 pivot 的放到右边,将 pivot 放到中间。经过这一步骤后,数组 p 到 r 的数据就被分成了三部分,再递归地把 小于 pivot 和 大于 pivot 的数据进行上述排序,直到区间缩小到 1 为止。

top k 问题:
若切分后的左子数组的长度 > k,则第k大元素必出现在左子数组中;
若切分后的左子数组的长度 = k-1,则第k大元素为pivot;
若上述两个条件均不满足,则第k大元素必出现在右子数组中。

12. 泛型

(1)使用泛型的好处
    使程序具有更好的 可读性 和 安全性 。在编译期就可以检查,“出现编译错误 比 类在运行时出现类的强制类型转换异常要好得多。”

     (2)类型擦除
    虚拟机中没有泛型类型对象——所有的对象都属于普通类,无论何时定义了一个泛型类型,都自动提供了一个相应的原始类型,原始类型就是删去类型参数后的泛型类型名,擦除类型变量,并替换为 限定类型,如果未限定的话,就是 Object 类型。

     (3)约束与局限性

不能用基本类型实例化类型参数运行时 类型查询只适用于 原始类型不能创建参数化类型的数组
    只是不允许创建,但是声明 Pair<String> [ ] 的变量是合法的,不过不能用 new Pair<String> [10] 初始化这个变量。泛型类的静态上下文中类型变量无效
不能在静态域 或 方法 中 引用类型变量,如:

public class Singleton<T> { private static T singleInstance; //Error public static T getSingleInstance( ) //Error { if( singleInstance == null ) return singleInstance; } } 12345678910 不能抛出或捕获泛型类的实例
    泛型类扩展 Throwable 是不合法的:

public class Problem<T> extends Exception //Error -- can't extend Throwable 1

    catch 中也不能使用类型变量,比如:

public static<T extends Throwable> void doWork(Class<T> t) { try { do work} catch(T t) //Error --can't catch type variable { Logger.global.info(...) } } } 1234567891011

    以上都是 编译出错。

网址:阿里本地生活一二三面 https://www.yuejiaxmz.com/news/view/75798

相关内容

阿里本地生活:折腾9年,为何还是配角?
正式签约阿里巴巴本地生活平台,打造“智慧烘焙”
阿里巴巴华中总部全面封顶
阿里巴巴:绿色生活方式的流行,需要一些“推动”
本地生活服务市场的战争
2024 年阿拉伯联合酋长国生活成本更新
【面试经验】字节生活服务二面凉经
厨房里三个方面十二种风险源,不可不防!
【FunClip】阿里开源AI视频剪辑神器:全面体验与教程
生活二三事汇编15篇

随便看看