面试实题:No.12

1、消息中间件activeMQ中丢了消息你们是怎么处理的?

查日志,查死信队列,查持久化文件等等把丢失的数据找回来。消费方订阅方式不要使用“非持久化订阅”的方式,如果不是太重要,发出预警,通知生产者重新发送。

另外,有条件的话,需要搭建日志分析服务;将生产上的日志与MQ日志等进行统计分析,例如时间比对,域比对等等,综合计算消息完成率;以及失败消息的分析。

2、分布式系统中A服务有两台服务器,那么我们在调用的时候如何知道是调用的那台服务器?(dubbo可以实现,那么不用dubbo能解决吗?)

调用远程服务的时候,假设是RPC服务,那么通常的算法对于调用方来讲是未知的。如果已知的情况只有在知道分发策略的情况下,也就是说,你知道程序会怎么调的情况下。

从技术角度来讲,底层无非就是协议栈远程访问,那么IP肯定是透明的,只要开发代码能够接触到NET层。

另外还有一种结构,服务注册中心实时监控服务器某个服务 调用次数/时间 这样的一个负载值,会根据不同的负载值给客户端最合理的建议(有时候仅仅是建议),而客户端再根据某些算法或者约定再确定调用哪台机器上的服务。

总之一句话,RPC服务调用之前会确定将会调用服务的宿主机的IP、端口,协议栈等等信息,如果能够接触到这部分核心代码,便能知道具体的网络信息。

3、项目开发中有在线分支和开发分支,你们在上线的时候是怎么实现分支合并的?

一般的做法,定制版本号或者具体分支,例如第一版上线的版本号为1.0,分支是master,那么直至第二版上线之前,会陆续有很多代码测试通过的代码合并到master上,就需要代码版本监控,很多时候都是线下操作。

还有一种做法就是分支覆盖,主分支master,现在起分支develop-xxx,陆陆续续将代码都提交之后(可能是一次大型迭代开发),这时进行封版,建立另外的分支develop-yyy,所有修改bug的代码再次提交到develop-xxx上,新功能的开发提交到develop-yyy上,待develop-xxx上的代码测试通过之后,合并到pre-master上,进行最后的代码质量评审以及安全检查,无误后再合并到master进行发布。

方法有很多种,原则只有一个,不允许将任何测试未通过,或者测试通过,但可能会影响其他功能的代码合并至master

4、库存减少是当生成订单减少的,那么假设A商品只有两件了,甲和乙同时点击了生成订单,那么谁能下单成功?谁不能成功?怎么实现的?

这个是简单的锁问题(秒杀问题)。

假设库存只有2件,AB同时下单,那么AB两个用户将竞争锁资源。例如,两件商品生成锁L1,L2;A用户所在线程获取到了L1,这时上下文切换到B所在线程,它发现L1已经被占了,至于有没有下单完成还不知道,这时它尝试获取L2,并进行后续操作。假设这时用户A不想买了,或者支付超时,那么L1将会被释放。

5、未登录时购物车信息,存在cookie中?还有哪些方式?

未登录状态下,购物车信息就是存在cookie中的,如果禁用cookie的话,servlet引入了一种补充会话的机制 , 当用户发出下一次请求时 , 如果请求信息中没有包含Cookie头字段 , Servlet引擎则认为客户端不支持cookie,它将依据请求url参数中的会话标识号来实施会话跟踪.

这种技术称为url重写,tomcat发送给客户端的会话标识号的Cookie名称为JSESSIONID。url重写就是将JSESSIONID关键字作为参数名和会话标识号作为参数附加到URL后面。如果浏览器不支持Cookie或者关闭Cookie,就必须对所有可能被客户端访问的请求路径进行 URL重写,如超链接,form表单的action属性和重定向的URL.

response.encodeURL() 使 URL包含 session ID,如果你需要使用重定向,可以使用 response.encodeRedirectURL ()来对 URL 进行编码。encodeURL () 及 encodeRedirectedURL () 方法首先判断 cookie是否被浏览器支持;如果支持,则参数 URL 被原样返回,session ID 将通过 cookies 来维持。

6、redis的hash类型在项目中的使用场景。

我们在开发中常用redis存储五种数据类型,String,Hash,List,Set,Zset(sorted set)

关于hash在我们实际开发中的应用,我以存储用户信息为例。

第一种:   key:userID;     value:username;age;birthday

第一种将用户ID作为查找key,把其他信息封装成一个对象以序列化的方式存储,这种方式的缺点是,增加了序列化/反序列化的开销,并且在需要修改其中一项信息时,需要把整个对象取回,并且修改操作需要对并发进行保护,避免产生脏数据。

第二种: key:userID+name        value:name

       key:userID+age       value:age

       key:userID+birthday    value:birthday;

第二种方法是这个用户信息对象有多少成员就存成多少个key-value对儿,用用户ID+对应属性的名称作为唯一标识来取得对应属性的值,虽然省去了序列化开销和并发问题,但是用户ID为重复存储,如果存在大量这样的数据,内存浪费还是非常可观的。

我们采取hashmap方法存储解决了上述两个问题,在存储用户信息的时候,key依旧是userID,但是value值却是一个map,map中依旧存在key和value;key是姓名标签,对应的value是具体的姓名;如果需要修改姓名值时,只加用userID+field(姓名)就可以修改姓名值了。这样操作不需要重复存储数据,也不需要考虑并发保护问题。

7、问商城项目中都有哪些地方用到了Redis,是如何使用的,Redis怎样更新数据,什么情况下更新数据,常用的存储结构都有哪些?

项目中将经常使用但不经常改变的数据放到数据库中,例如商品列表中的图片,将图片id存进去

先把数据加载到缓存中,缓存成功后再切换显示最新的数据,将旧数据设置过期;

string,list,set,sorted set,hash

发布了441 篇原创文章 · 获赞 1021 · 访问量 53万+

猜你喜欢

转载自blog.csdn.net/A_BlackMoon/article/details/104758283