2021/3/25 美团一面(凉经)数据库设计遇到的难点,怎么解决、SpringMVC执行原理、Redi数据类型场景、JVM堆大小设计、CMS不使用标记压缩,G1标记压缩、JVM的内存模型

1请你谈一谈在项目中数据库设计遇到的难点,并且你是怎么解决的?

1可以从范式的角度谈谈:关系模式一定要设计的合理,如果设计的不合理的话,会出现4个问题:1数据冗余太大,浪费大量的存储空间;2更新异常,数据冗余,更新数据时,维护数据完整性代价大;3插入异常,改插的数据插不进去;4删除异常,不该删除的数据不得不删。举个例子而言:一个描述学校的数据库,设计的对象:学生的学号(Sno) 所在系(Sdept) 系主任的名字(Mname) 课程名(Cname) 成绩(Grade)
如果是设计成一个单一的关系模式U={Sno , Sdept ,Mname , Cname , Grade},这个关系模式,可能会出现一些部分函数依赖,传递函数依赖等等,可能这里我没有涉及,为了解决这个问题,我们一般是使用规范化数据库设计理论的知识来解决这个问题,数据库原理的有介绍过数据依赖的知识,我们接触的是使用函数依赖来解决这个问题,我们设计的关系模式一定要复符合我们的额BC范式的要求,即不能出现部分函数依赖,传递函数依赖,这样可以有效的解决一写不合理的函数依赖造成的不合理的数据库设计;

2优化查询速度:我们考虑的一般是加索引的方式,通过一个主键索引;

2在实际的开发中,你是如何使用线程池的?

线程池的作用就是减少创建线程和回收线程的资源消耗,提高响应速度,方便管理;

3谈谈Sleep和wait的区别

1,所属的类不同:sleep方法是定义在Thread上 wait方法是定义在Object上
2,对于锁资源的处理方式不同 sleep不会释放锁 wait会释放锁
3,使用范围:sleep可以使用在任何代码块 wait必须在同步方法或同步代码块执行

4 SpringMVC执行原理

1 DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。
2 DispatcherServlet自行调用HandlerMapping,HandlerMapping根据请求url查找Handler。
3 HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。
4 HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。
5 Handler让具体的Controller执行。
6 Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。
7 HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。
8 DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名
9 视图解析器将解析的逻辑视图名传给DispatcherServlet。
10 DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。
11 最终视图呈现给用户

5Redis的基本数据类型?

字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets)

6Redis各种基本数据类型的使用场景?

1String

存储内容:通常使用字符串,如果字符串以整数的形式展示,可以作为数字操作使用(但是仍是字符串)
常用的命令:添加数据、修改数据 set key value 获取数据get key 删除数据 del key mset mget
应用场景1:String类型作为数值时的增减;大型企业级应用中,分表操作是基本操作,使用多张表存储同类型数据,但是对应的主键id必须保证统一性,不能重复,MySQL数据库并不具有类似的机制,那么如何解决?设置数值数据增加指定范围的值,设置数值数据减少指定范围的值
应用场景2:String 数据时效性设置;新闻网站会出现热点新闻,热点新闻最大的特征是对时效性,如何自动控制热点新闻的时效性;setex name 15 zs15s后过期;
应用场景3:String类型之高热度数据访问加速;微博大V主页显示粉丝数与微博数量,这些数据就是热度数据,不断发生变化,这些数据如何放入Redis?在Redis中为大V用户设定用户信息,以用户主键和属性值作为key,后台设定时间定时刷新即可:user: id :5765898790:focuss:3050

2Hash

127.0.0.1:6379> Hset people name zs age 21
(integer) 2
127.0.0.1:6379> Hget people name
"zs"
127.0.0.1:6379> Hget people age
"21"
127.0.0.1:6379> Hmget people name age
1) "zs"
2) "21"
127.0.0.1:6379> Hgetall people
1) "name"
2) "zs"
3) "age"
4) "21"
127.0.0.1:6379> Hdel people name
(integer) 1
127.0.0.1:6379> Hgetall people
1) "age"
2) "21"

应用场景1:hash类型应用场景购物车:电商网站购物车的设计与实现;
在这里插入图片描述
以用户的ID作为Key,每位用户创建一个hash存储结构存储对象的购物车信息,商品的编号作为field,购买的数量作为value进行存储。添加商品的时候,添加filed vale即可;浏览:遍历hash即可;删除商品:删除field即可;

3List

在redis里面,我们可以把list玩成栈,队列

lpush key value1 [value2] …
rpush key value1 [value2] …

lrange key start stop //获取从左数第start到stop个元素,从0开始
lindex key index //查询第i个元素
llen key //list的长度

lpop key //获取并删除左边第一个元素
rpop key //获取并删除右边第一个元素

业务场景1:微信朋友圈点赞,要求按照点赞顺序显示点赞好友信息。如果取消点赞,移除对应好友信息。
在这里插入图片描述
业务场景2:最新消息的展示:新闻、资讯类网站如何将最新的新闻或资讯按照发生的事件顺序展示

4Set

添加数据
sadd key menber1 [member2]
获取全部数据
smembers key
删除数据
srem key member1 [member2]
获取集合数据总量
scard key
判断集合中是否包含指定数据
sismember key member

业务场景1:随机操作数据;每位用户首次使用进入头条时候会设置3项爱好的内容,但是后期为了增加用户的活跃度,兴趣点,必须让用户对其他信息类别逐渐产生兴趣,增加客户留存度,如何实现?1系统分析出各个分类的最新或最热点信息条目并组织成set集合;2随机挑选其中部分信息;3配合用户关注信息分类中的热点信息组织展示的全信息集合

业务场景2:业务场景-共同好友:

求两个集合的交、并、差集并存储到指定集合中
sinterstore destination key1 [key2]
sunionstore destination key1 [key2]
sdiffstore destination key1 [key2]

业务场景3:访问量统计去重:针对不同的统计类型有不同的数据存储方式:1利用set集合的数据去重特征,记录各种访问数据;2建立string类型数据,利用incr统计日访问量(PV);3建立set模型,记录不同cookie数量(UV);4建立set模型,记录不用IP数量(IP)

5sorted sets

业务场景1:建立排序依据:票选广东十大杰出青年,各类综艺选秀海选投票,聊天室活跃度统计,游戏好友亲密度;

zadd key score value # 添加值,score代表优先级,可以一次添加多个

zrange key start end # 获取start-end的值,0 -1代表获取所有值

# 排序如何实现
zrangebyscore key startscore endscore # 对集合通过score排序, 默认升序

zrangebyscore key -inf inf withscores # 显示score

zrevrange salary 0 -1 [withscores] # 降序排列所有值

zrem key member [member] # 移除元素

zcard key # 获取有序集合中的个数

zcount key start end # 获取start-end之间的个数

7JVM堆大小的是如何设计的?

-Xmx:最大堆大小
-Xms:初始堆大小
-Xmn: 年轻代大小

Java整个堆大小设置,Xmx 和 Xms设置为老年代存活对象的3-4倍
永久代 PermSize和MaxPermSize设置为老年代存活对象的1.2-1.5倍
年轻代Xmn的设置为老年代存活对象的1-1.5倍
老年代的内存大小设置为老年代存活对象的2-3倍

Sun官方建议年轻代的大小为整个堆的3/8左右

8各种垃圾回收器使用的垃圾回收算法?

在这里插入图片描述

9为什么CMS不使用标记压缩算法,G1使用的标记压缩算法呢?

在并发清理的过程中,用Compact整理内存的时候,原来用户线程使用的内存就不可以使用了,要保证用后线程的继续运行,前提是它运行的资源不受影响。MarkCompact 更加适合STW的场景下。

G1的回收是以region为单位,region之间可以看做是复制算法,但整体实际上可以看做是标记压缩算法,这种算法可以避免内存碎片,这种特性有利于程序的长时间运行,分配大对象时不会因为无法找到连续的内存 而提前触发下一次GC.尤其是堆很大的时候。

10JVM的内存模型?

在这里插入图片描述
JVM包含两个子系统和两个组件,两个子系统为Class loader(类装载)、Execution engine(执行引擎);两个组件为Runtime data area(运行时数据区)、Native Interface(本地接口)

Class loader(类装载):根据给定的全限定名类名(如:java.lang.Object)来装载class文件到Runtime data area中的method area。

Execution engine(执行引擎):执行classes中的指令。

Native Interface(本地接口):与native libraries交互,是其它编程语言交互的接口。

Runtime data area(运行时数据区域):这就是我们常说的JVM的内存。

作用 :首先通过编译器把 Java 代码转换成字节码类加载器(ClassLoader)再把字节码加载到内存中,将其放在运行时数据区(Runtime data area)的方法区内,而字节码文件只是 JVM 的一套指令集规范,并不能直接交给底层操作系统去执行,因此需要特定的命令解析器执行引擎(Execution Engine),将字节码翻译成底层系统指令,再交由 CPU 去执行,而这个过程中需要调用其他语言的本地库接口(Native Interface)来实现整个程序的功能。

程序计数器(Program Counter Register)当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成;

Java 虚拟机栈(Java Virtual Machine Stacks):用于存储局部变量表、操作数栈、动态链接、方法出口等信息;

本地方法栈(Native Method Stack):与虚拟机栈的作用是一样的,只不过虚拟机栈是服务 Java 方法的,而本地方法栈是为虚拟机调用 Native 方法服务的

Java 堆(Java Heap):Java 虚拟机中内存最大的一块,是被所有线程共享的,几乎所有的对象实例都在这里分配内存;

方法区(Methed Area):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值