美团Java后端(一)

  • 介绍项目
  • Java ArrayList 和 LinkedList 的区别以及使用
  1. 二者实现结构不同,arraylist是基于数组,linkedlist是基于链表,他们的特性也是由其数据结构决定的。

  2. 随机遍历访问时linkedlist的性能要低于arraylist.

  3. linkedlist的增删要优于arraylist

  4. arraylist的初始化时默认10容量,而linkedlist默认初始化为空

  • Java 创建一个对象的方法

  1. 用new语句创建对象,这是最常用的创建对象的方式

  2. 运用反射手段,调用Java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法

  3. 调用对象的clone()方法

  4. 运用反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法

  • Java 序列化和反序列化

  1. Java序列化,反序列化-----java序列化指将Java对象转换为字节序列的过程,反序列化指将字节序列转换为目标对象的过程;

  2. 什么情况下需要序列化-----当Java对象需要网络传输或者持久化到磁盘上时;

  3. 序列化的实现---让类实现Serializable接口,标注该类对象可以被序列化;

  • 单例模式的优点是什么

可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收

  • == 和 equals 的区别

1)对于==,一般比较的是值是否相等

       如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;

如果作用于引用类型的变量,则比较的是所指向的对象的地址

2)对于equals方法,一般为比较内容是否相同

如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;

诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。

  • 介绍一下 MyBatis,它的优点是什么
  1. mybatis减少了百分之五十以上的代码量
  2. 非常的小巧也很容易学
  3. SQL代码从程序代码当中完全的分离出来
  4. 支持对象和数据库的ORM字段关系映射
  5. 支持编写动态SQL
  • InnoDB 的默认隔离级别是什么

InnoDB的默认隔离级别是可重复读

  • 讲一下不可重复读和幻读,分别怎么解决的

不可重复读与幻读的区别可以通俗的理解为:前者是数据变了,后者是数据的行数变了

为了解决不可重复读,MySQL 采用了 MVCC (多版本并发控制) 的方式。

MySQL 已经在可重复读隔离级别下解决了幻读的问题,用的是间隙锁。

  • 在一个事务里面,读取了一个记录,另一个事务将这个记录删除了,前一个事务就读不到了,这种情况是不可重复读还是幻读呢

幻读

  • InnoDB 是通过哪种机制来实现的可重复读

在Innodb存储引擎下使用了MVCC机制实现了可重复读。所谓MVCC机制就是额外的在每行数据后面增加两列来记录当前行的创建版本号和删除版本号

  • GC 确定垃圾有哪种算法
  1. 引用计数法
    在 Java 中,引用与对象相关联,如果要操作对象,则必须使用引用。因此,可以通过引用计数来确定对象是否可以回收。实现原则是,如果一个对象被引用一次,计数器 +1,反之亦然。当计数器为 0 时,该对象不被引用,则该对象被视为垃圾,并且可以被 GC 回收利用。弊端 :如果AB相互持有引用,导致永远不能被回收。

  2. 可达性分析
    为了解决引用计数法的循环引用问题,Java 采用了可达性分析的方法。其实现原理是,将一系列"GCroot"对象作为搜索起点。如果在"GCroot"和一个对象之间没有可达的路径,则该对象被认为是不可访问的。

  • GC root 对象有哪些

GC管理的主要区域是Java堆,一般情况下只针对堆进行垃圾回收。方法区、栈和本地方法区不被GC所管理,因而选择这些区域内的对象作为GC roots,被GC roots引用的对象不被GC回收。

  1. Class - 由系统类加载器(system class loader)加载的对象,这些类是不能够被回收的,他们可以以静态字段的方式保存持有其它对象。
  2. Thread - 活着的线程
  3. Java方法的local变量或参数
  4. JNI方法的local变量或参数
  • 介绍一下 static 关键字

static关键字最基本的用法是:

1、被static修饰的变量属于类变量,可以通过类名.变量名直接引用,而不需要new出一个类来

2、被static修饰的方法属于类方法,可以通过类名.方法名直接引用,而不需要new出一个类来

静态块也是static的重要应用之一。也是用于初始化一个类的时候做操作用的,和静态变量、静态方法一样,静态块里面的代码只执行一次,且只在初始化类的时候执行

补充相关知识点

1、被final修饰的类不可以被继承

2、被final修饰的方法不可以被重写

3、被final修饰的变量不可以被改变

被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的

  • Redis 数据类型

      string 字符串(可以为整形、浮点型和字符串,统称为元素)
      list 列表(实现队列,元素不唯一,先入先出原则)
      set 集合(各不相同的元素)
      hash hash散列值(hash的key必须是唯一的)
      sort set 有序集合

  • Redis 持久化方案

redis提供两种方式进行持久化,一种是RDB持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化),另外一种是AOF持久化(原理是将Reids的操作日志以追加的         方式写入文件)

RDB性能最大化,数据安全性低

AOF可以带来更高的数据安全性,运行效率上往往会慢于RDB

  • Redis 为什么用的是单线程

因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程

补充知识点---Redis为什么这么快

1、完全基于内存;

2、数据结构简单;

3、采用单线程,不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题;

4、使用多路I/O复用模型,非阻塞IO;

5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

针对多路 I/O 复用模型进行简单的探讨:

多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒(epoll 是只轮询那些真正发出了事件的流)

注:这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响Redis性能的瓶颈,主要由以上几点造就了 Redis 具有很高的吞吐量。

  • 讲一下 SQL 注入的方法(步骤)
  1. 寻找注入点,构造特殊的语句

    传入SQL语句可控参数分为两类 
    1. 数字类型,参数不用被引号括起来,如?id=1 
    2. 其他类型,参数要被引号扩起来,如?name="phone"

  2. 用户构造SQL语句(如:'or 1=1#;admin'#(这个注入又称PHP的万能密码,是已知用户名的情况下,可绕过输入密码

  3. 将SQL语句发送给DBMS数据库

  4. DBMS收到返回的结果,并将该请求解释成机器代码指令,执行必要得到操作

  5. DBMS接受返回结果,处理后,返回给用户

  • 怎么避免 SQL 注入
  1. 采用预编译语句集,它内置了处理SQL注入的能力----PreparedStatement
  2. 使用正则表达式过滤传入的参数
  3. 字符串过滤--非法字符过滤
  4. JSP页面判断代码----使用javascript在客户端进行不安全字符屏蔽
  • 讲一下 ZGC,CMS,G1 --垃圾回收算法

1. CMS 使用标记清除算法,优点是并发收集,停顿小。

2. G1打破了以往将收集范围固定在新生代或老年代的模式,GI 将 Java 堆空间分割成了若干相同大小的区域。GI 的一大优势在于可预测的停顿时间, 能够尽可能快地在指定时间内完成垃圾         回收任务

3. 和G1类似,但ZGC的region的大小更加灵活和动态。zgc的region不会像G1那样在一开始就被划分为固定大小的region。

zgc的region核心亮点就是:动态。

动态表现为:

(1)动态地创建和销毁。

(2)动态地决定region的大小

  • 开发的是否遇到过 OOM 吗,怎么导致的,怎么调试的

使用 JDK 自带的工具 jvisualvm.exe 进行分析

在JDK安装目录\bin 下

安卓例子:Android Studio自带的Memory Monitor,很简单的一个小工具,能够把应用内存实时展现出来

问题举例:app在我退出再进的时候,内存占用几乎翻番(内存泄漏)

  • 剑指 Offer 09. 用两个栈实现队列

维护两个栈,第一个栈支持插入操作,第二个栈支持删除操作。

根据栈先进后出的特性,我们每次往第一个栈里插入元素后,第一个栈的底部元素是最后插入的元素,第一个栈的顶部元素是下一个待删除的元素。为了维护队列先进先出的特性,我们引入第二个栈,用第二个栈维护待删除的元素,在执行删除操作的时候我们首先看下第二个栈是否为空。如果为空,我们将第一个栈里的元素一个个弹出插入到第二个栈里,这样第二个栈里元素的顺序就是待删除的元素的顺序,要执行删除操作的时候我们直接弹出第二个栈的元素返回即可。

  • 社区团购?

社区团购是依托真实社区的一种区域化、小众化、本地化、网络化的团购形式。


版权声明:本文为lijieling123原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。