商城常见面试题

发布时间:2024年01月05日

商城常见面试题

0、详细讲一下你的项目?

项目基于多个微服务模块实现,使用Nacos做为微服务的注册与发现中心。引入gateway组件作为服务入口的统一管理。使用Open Feign作为服务间通信的组件,基于请求与响应的方式。使用seata组件提供分布式事务的服务。基于ES实现商品的检索等等。

1、你项目中的难点是什么?(字节)(华为)(美团)

一、查询商品详情

查询商品详情,也就是从商城主页面点击一个商品到展示一个商品的详细信息这一步骤。由于逻辑比较复杂,而且有些数据还需要进行远程调用。

**(获取SKU基本信息 -> 获取SKU图片信息 -> 获取SKU促销信息 -> 获取SPU销售属性 -> 获取规格参数组以及组下参数-> 获取SPU详情)**为了优化这一部分的时间,引入了线程池技术从而多线程异步的方式执行以上任务。

但是异步任务又涉及到一个异步编排的问题,也就是说有些任务的先后顺序是有要求的。可以使用completableFuture来完成异步编排。

二、登录问题

抽取SSO单点登录模块,一切的登录请求由该模块处理。是基于相同顶级域名的SSO实现。

2、你用了线程池,为什么用线程池?工作顺序说一下?(顺丰科技)(滴滴)(美团)(shopee)

  1. 使用线程池可以减少创建和销毁线程的次数,从而降低资源的消耗。每个工作线程都可以重复使用
  2. 可以根据系统的承受能力,调整线程池中工作线程的数量,防止因为消耗过多内存导致服务器崩溃

创建线程池之后,核心线程开始执行任务,核心线程占用完了,其他任务进入阻塞队列,空闲线程开始执行任务。没有空闲线程了并且队列也满了,使用拒绝策略拒绝其他任务。

拒绝策略:抛弃老任务策略、丢弃新任务策略、直接抛异常策略等等

3、单点登录是什么?(顺丰科技)(shopee)

单点登录英文全称Single Sign On,简称就是SSO。它的解释是:在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统。

普通的登录认证机制:

在这里插入图片描述

我们在浏览器(Browser)中访问一个应用,这个应用需要登录,我们填写完用户名和密码后,完成登录认证。这时,我们在这个用户的session中标记登录状态为yes(已登录),同时在浏览器(Browser)中写入Cookie,这个Cookie是这个用户的唯一标识。下次我们再访问这个应用的时候,请求中会带上这个Cookie,服务端会根据这个Cookie找到对应的session,通过session来判断这个用户是否登录。如果不做特殊配置,这个Cookie的名字叫做jsessionid,值在服务端(server)是唯一的。

同顶级域名下的单点登录:

一个企业一般情况下只有一个域名,通过二级域名区分不同的系统。比如我们有个域名叫做:a.com,同时有两个业务系统分别为:app1.a.com和app2.a.com。我们要做单点登录(SSO),需要一个登录系统(微服务),叫做:sso.a.com。

我们只要在sso.a.com登录,app1.a.com和app2.a.com就也登录了。通过上面的登陆认证机制,我们可以知道,在sso.a.com中登录了,其实是在sso.a.com的服务端的session中记录了登录状态,同时在浏览器端(Browser)的sso.a.com下写入了Cookie。那么我们怎么才能让app1.a.com和app2.a.com登录呢?这里有两个问题:

  • Cookie是不能跨域的,我们Cookie的domain属性是sso.a.com,在给app1.a.com和app2.a.com发送请求是带不上的。
  • sso、app1和app2是不同的应用,它们的session存在自己的应用内,是不共享的。

在这里插入图片描述

解决办法:针对cookie跨域问题,将cookie域设置为顶域,即属于a.com。这样所有的子域系统都能访问到顶域的cookie。针对session问题,可以使用Spring-session 解决session共享问题。

3.1、spring session 原理?

spring-session 配合redis 将session 进行统一管理。

4、为什么需要单点登录?

方便客户、不需要记住多个 ID 和密码。

5、cookie可以跨域名传输吗?(平安科技)

默认不可以,但可以设置。

服务端使用使用@CrossOrigin注解时。只需要在网页端设置跨域 XMLHttpRequest 请求的 withCredentials 属性就可以正常设置和获取跨域 Cookie。

6、如何写一个统计页面访问次数业务?(顺丰科技)

7、你Jmeter压测的什么接口?能达到一个什么样的性能?(美团)

分别压测了动静分离、redis中间件引入前的商城主页面接口。

8、你为什么用canal?(美团)

解决数据库缓存的一致性问题。另外一种解决方式是采用改完数据库删缓存的方式。

canal通过模拟MySQL的从机,从而完成类似于MySQL的主从复制的过程。然后canal将从MySQL读到的数据同步到redis、ES中。

9、什么是分布式事务?有什么特点?和单机事务有什么区别?(shopee)(跟谁学)

后面分布式事务中有详细讲解。

10、两阶段提交?

2pc,后面分布式事务中有详细讲解。

11、线程池的核心线程数有没有经验值?(滴滴)

  • 如果是CPU密集型应用(CPU使用率很高,若开过多的线程数,只能增加上下文切换的次数,因此会带来额外的开销。),则线程池核心线程数大小设置为N+1
  • 如果是IO密集型应用(IO密集型任务CPU使用率并不高,因此可以让CPU在等待IO的时候去处理别的任务,充分利用CPU时间。),则线程池核心线程数大小大小设置为2N+1

其中N为CPU的核心数。

12、你分布式服务中假设同一功能的微服务部署了多台,你的请求是怎么处理的?(百度)

可以依靠 Open Feign 组件内部封装的Ribbon实现提供相同服务的微服务的负载均衡。

@FeignClient("mall-coupon") // 标识了要去调用的那个微服务
public interface CouponFeignService {
    @PostMapping("/coupon/spubounds/save")
    R saveSpuBounds(@RequestBody SpuBoundTo spuBoundTo);

    @PostMapping("/coupon/skufullreduction/saveinfo")
    R saveSkuReduction(@RequestBody SkuReductionTo skuReductionTo);

}

在使用@FeignClient注解的时候 是默认使用了Ribbon进行客户端的负载均衡的,默认的是随机的策略,那么如果我们想要更改策略的话,需要修改消费者yml中的配置,如下:

ribbon:
	NFLoadBalancerRuleClassName: com.netflix.loadbalancer.BestAvailableRule #配置规则 最空闲连接策略

13、你的项目还有什么可以扩展的地方?(字节)

加第三方登录(微博、QQ等)功能。完善SSO功能。

14、数据库结构设计方面问题?

采用分库分表的方式设置数据库。为每一个微服务设置独立的数据库。

15、分布式服务中生成全局唯一ID的方式?(招银网络科技)

分布式ID的特点:全局唯一性、递增性、高可用性。

常见解决方案:

UUID、雪花算法、UidGenerator、Leaf

雪花算法概要:SnowFlake是Twitter公司采用的一种算法,目的是在分布式系统中产生全局唯一且趋势递增的ID。SnowFlake算法在同一毫秒内最多可以生成多少个全局唯一ID呢: 同一毫秒的ID数量 = 1024 X 4096 = 4194304。雪花算法的实现主要依赖于数据中心ID和数据节点ID这两个参数。

16、分布式、微服务、SOA?(shopee)(美团)

微服务的特点:技术异构性、隔离性、可扩展性、易于优化性。

17、购物车模块用户登录与没有登录分别如何使用购物车功能?(shopee)

  1. 用户没有登录时,我们将用户的购物车信息存储在cookie中。但是此时用户登录了在其他电脑上就会看不到当前购物车的信息。
  2. 用户登录后,将用户的cookie中的信息存储到redis中保存,这样的话同一账号下都可以使用同一个购物车的信息。

18、如果用户一直添加购物车添加商品怎么办?并且他添加一次你查询一次数据库?互联网上用户那么多,这样会对数据库造成很大压力你怎么办?(shopee)

用户往购物车中添加商品并不会直接操作数据库,而是通过操作redis或者cookie然后最终通过redis的持久化机制存储到MySQL中。所以频繁的添加购物车不会有问题。

19、如何实现分页功能?

20、如何解决MySQL数据库和ES数据不一致问题?(美团)(字节)

  1. 双写模式: 我们采取MySQL作为主要的数据存储,利用MySQL的事务特性维护数据一致性,使用ElasticSearch进行数据汇集和查询,此时es与数据库的同步方案就尤为重要。

    保证es与数据库的同步方案:

    1、首先添加商品入数据库,添加商品成功后,商品入ES,若入ES失败,将失败的商品ID放入redis的缓存队列(或MQ),且失败的商品ID入log文件(若出现redis挂掉,可从日志中取异常商品ID然后再入ES),
    task任务每秒刷新一下redis缓存队列,若是从缓存队列中取到商品ID,则根据商品ID从数据库中获取商品数据然后入ES。

  2. canal组件控制一致性

20.1、如果数据库写失败了怎么办?ES写失败了怎么办?

若入ES失败,将失败的商品ID放入redis的缓存队列(或MQ),且失败的商品ID入log文件(若出现redis挂掉,可从日志中取异常商品ID然后再入ES),
task任务每秒刷新一下redis缓存队列,若是从缓存队列中取到商品ID,则根据商品ID从数据库中获取商品数据然后入ES。
如果数据库写失败了怎么办?ES写失败了怎么办?

若入ES失败,将失败的商品ID放入redis的缓存队列(或MQ),且失败的商品ID入log文件(若出现redis挂掉,可从日志中取异常商品ID然后再入ES),
task任务每秒刷新一下redis缓存队列,若是从缓存队列中取到商品ID,则根据商品ID从数据库中获取商品数据然后入ES。

文章来源:https://blog.csdn.net/weixin_48877626/article/details/135297095
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。