面经-快手测开 2023 - 7 - 11
简单介绍一下二手市场整体的架构,数据流的实现?
整体架构:
- 持久层和缓存的选型
- MySQL作为持久层:
- 支持复杂条件数据查询:在二手市场中,用户会根据自身需求筛选不同的条件进行各种复杂的查询,例如按照不同条件筛选商品等,MySQL提供丰富的查询语言和索引支持,能够高效查询相关数据。
- 结构化数据存储:二手市场涉及大量的结构化数据,例如:用户信息,商品信息等。而MySQL是关系型数据库,适合存储和管理结构化数据,提供事务支持,保证数据的一致性和完整性。
- Redis作为缓存:
- 二手市场是多读少写的场景,用户会频繁的浏览商品,但是对商品的修改变更有限,所以可以将物品信息添加至Redis中有效减轻MySQL的读取压力,提高系统的响应和性能。
- MySQL作为持久层:
- 服务的拆分方式
暂时因为是单体架构,没有钱去购买太多的服务器,所以服务暂时没有进行具体的划分,如果要进行划分的话我觉得可以划分成以下几种服务:
用户服务:主要是对用户的身份信息进行认证和鉴权。
UGC消息通知:可以处理二手市场发布、编辑商品信息后,通过邮件、消息推送的方式告知用户。
商品信息服务:负责二手商品信息的发布、编辑、删除、搜索等功能。
缓存服务:应对二手市场这种读大于写的场景,可以将最新的50条商品信息放入系统缓存中,优化用户查看商品的体验。
支付服务:支付服务负责处理用户的支付请求,与第三方支付平台进行交互,并确保支付的安全性和可靠性。
文件服务:用于处理用户上传的图片、视频。
服务容灾和负载均衡方式
- 服务容灾:
- 定期对系统的数据进行备份
- 定期检查维护服务器的实例,修复代码BUG等
- 负载均衡:
- CDN服务:将静态资源(图片、视频等)放置在内容分发网络中,加快资源加载速度,减少服务器负载
- 缓存数据,使用缓存减轻服务器负担,提高响应速度
- 反向代理:通过Nginx反向代理服务实现负载均衡,等后面有多台服务器之后将请求分发给不同的服务器,提高服务可扩展性。
- 服务容灾:
数据流实现:
- 用户上传商品:
- 用户在应用中填写商品信息,并上传相关照片
- 上传的用户信息和照片URL被发送到服务器中进行处理和存储
- 服务器对传过来的数据进行数据库存储,并生成一个唯一ID
- 商品展示和搜索:
- 其他用户访问二手市场时,前端向后端请求商品数据
- 后端从数据库中获取数据列表,并返回给前端
- 用户可以根据自身的需求条件查询特定的商品,前端将搜索条件发送给后端,后端根据条件查询数据库并返回匹配的商品信息。
- 商品详情获取:
- 当用户点击某个商品的详情信息之后,前端发送请求,传递对应的商品ID给后端
- 后端根据商品ID在数据库中搜索并返回具体商品信息给前端展示
如果检索某个具体商品是如何实现检索的?
查询的时候如何避免慢查询?
- 索引优化,将经常用到的字段创建索引(除去经常更新的字段、重复度很高的字段、数据量较少的情况),比如单列索引和联合索引,从而避免全表扫描。
- 分页查询:对于返回大量的数据查询,使用分页查询的方式,限制返回的数据量,避免一次返回大量的数据导致查询速率很慢。
- 缓存查询:对于一些比较查询比较频繁的数据可以使用缓存来避免每次都进行数据库查询。
- 合理设计数据库的表结构:比如说说评论查询,二级评论可以通过添加一个masterId字段(对应的说说id)来快速定位到此二级评论是归属于哪条说说之下。
如何正确的创建索引?(即:什么时候创建索引?)
- 字段具有唯一性限制,即重复度很低,且不是经常修改的字段
- 经常用于where子句查询
- 经常用于group by 或者 order by查询
- 表的数据量比较多的情况
二手市场进行物品查询,做测试的话会进行设计使用哪些测试用例?
- 正确、错误、空物品查询
- 物品大小写查询
- 高并发查询
- 过滤项查询
- 物品状态查询
- 安全性测试:比如SQL注入
- 边界值测试:比如输入极限情况下,很长的字符串验证系统是否能正确处理。
后端如何进行统计服务的性能?是否对请求进行一些限流的操作?如何进行限流的操作?
- 统计性能的方式:
- 日志记录
- 性能监控工具的使用:比如New Relic、Prometheus等
- 负载测试,模拟大量并发请求,观察系统的响应情况和性能指标。
- 有,限流操作如下:
- 固定窗口计时器:设置一个固定时间窗口,例如
HashMap、HashSet、HashTable的区别?
HashMap和HashTable区别:
- 线程是否安全:HashMap是非线程安全,HashTable是线程安全(通过synchronized修饰实现)。
- 效率:由于HashMap线程不安全,HashMap比HashTable效率高,但是HashTable几乎被淘汰,平时一般不会用HashTable。
- 键值对存值问题:HashMap是可存null键和null值,HashTable不允许有null键和null值,否则会抛出异常NPE。
- 初始容量大小和每次扩充容量大小不同:HashTable初始化容量是11,每次扩容就是2n+1,HashMap初始化容量是16,每次扩容就是原来的2n倍。
- 底层数据结构:HashMap是数组+链表/红黑树实现,在解决哈希冲突时,当链表长度大于阈值(默认为8),将链表转化成红黑树(将链表转化成红黑树之前,如果数组长度小于64就会进行数组扩容,而不是转换成红黑树),以减少搜索时间,而HashTable是数组+链表的形式实现。
HashMap和HashSet的区别:
- HashMap实现Map接口,HashSet实现Set接口。
- HashMap存储键值对,HashSet只存储对象。
- HashMap通过put方法添加元素,HashSet通过add()向Set中添加元素。
- HashMap使用Key计算hashcode,HashSet使用成员对象计算hashcode值。
HashMap是线程的安全的吗?介绍一下ConcurrentHashMap
线程不安全,因为多线程情况下,HashMap进行键值对存值的时候,可能会因为分配到一个桶里面造成数据覆盖的风险,比如线程1,2同时进行put操作,此时正好发生了hash冲突,线程1执行完hash冲突判断之后,时间片耗尽挂起,此时线程2进行hash冲突判断并对数据插入到链表中,后面等线程1重新获取到时间片,进行插入操作就会覆盖掉线程插入的数据。
ConcuurentHashMap:
Java8以上数据结构是Node数组+链表/红黑树,哈希冲突时当链表长度大于一定长度时,链表就会转换成红黑树。
接口和抽象类的区别?
- 接口是对类的行为进行约束,实现了某个接口就是已经拥有了具体的行为,抽象类是代码复用,强调的是类的从属关系。
- 接口的成员变量只能用public static final修饰且不可修改和初始化,抽象类的成员变量默认为default类型,可以在子类被重新赋值定义。
- 一个类可以实现多个接口但是只能继承一个父类。
如果某个网页打不开了,排查手段有哪些?
Linux中查看主目录下以.log结尾的文件?
1 | find /path/to/home/directory -type f -name "*.log" |
find
:命令本身,用于查找文件和目录。/path/to/home/directory
:替换为你要查找的主目录的路径。例如,如果你要在当前用户的主目录下查找,可以使用~
代替这个路径。-type f
:表示只查找普通文件,不包括目录等其他类型的文件。-name "*.log"
:表示查找文件名以.log
结尾的文件。*.log
是通配符,表示匹配所有以.log
结尾的文件名。
如何查询某个日志的内容?
- Cat
- Head
- Tail
- Less
- More
比较一下less命令和more命令的区别?
- less支持前后翻页,more只支持向后翻页
- less是根据要展示的内容加载到内存中,加快读取速度,more是将整个文件内容全部加载到内存中,可能会导致崩溃
算法题:力扣平衡字符串问题
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 HUT菜鸟小八的博客!
评论