拼多多一面、二面-Java工程师

1、自我介绍

2、自己的项目进行介绍

3、MySQL的作用和机制

4、数据库事务特性、每一个细问、四种隔离类型,每个类型对应的作用

脏读是什么?哪些可以避免脏读?

幻读是什么?哪些可以避免换的?

5、两个系统的事务怎么进行通信的,例如工商银行和农业银行进行两个事务的通信?

分布式事务处理:1)全局消息;2)基于可靠消息事务服务;3)最大通知;

银行,基于可靠消息服务

实现细节:通过消息中间件进行实现。系统A和系统B,系统A存在任务A,系统B存在任务B。任务A需要消息传递,是系统A发送给消息中间件发送消息,不会立刻发给系统B,而且首先进行消息持久化,再反馈消息给系统A。系统A发送commit然后中间件收到commit,再将消息发送系统B。

6、InnoDB和MyIASM的区别

什么情况下使用InnoDB?什么情况使用MyIASM?

7、是否用到索引

index(A,B,C)

select * from XXX where C = 1 and A = 2

select * from XXX where B = 3 and C = 4

select * from XXX where B = 5

8、索引的底层实现

    B+树

9、HashMap的存储数据结构

线程安全的map有哪些?

HashTable以及CurrentHashMap

线程安全是什么?

下面这个线程安全吗?

void putIfAbsent(String key, String value) {
     if(!table.containKey(key)) {
        table.put(key, value);    
     }
}

10、死锁的条件、手写死锁、如何解决死锁

public class Main2 implements Runnable{
 private int flag;
 Object o1 = new Object();
 Object o2 = new Object();
 public void run(){
  System.out.print(flag);
  if(flag==0){
   synchronized(o1){
    try {
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
    synchronized(o2){
     
    }
   }

}
  if(flag==1){
   synchronized(o2){
    try {
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
    synchronized(o1){
     
    }
   }
  }
 }
 
 public static void main(String[] args) {
  Main2 m1 = new Main2();
  Main2 m2 = new Main2();
  m1.flag = 1;
  m2.flag = 0;
  Thread t1 = new Thread(m1);
  Thread t2 = new Thread(m2);
  t1.start();
  t2.start();
 }

}

11、线程池

return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());

 1 :  6个任务进来

  2: 16任务进来

12、synchronized 和 java.util.concurrent.locks.Lock两者的区别

13、手撕代码、高效编码

拼多多二面

  • 先做一下自我介绍,
  • 然后自己挑一个项目去讲,主要涉及到项目的整体结构,用到了哪些技术
  • java,框架,设计模式,mysql等
  • 用阻塞队列去实现一个什么什么应该怎么做,
  • 关于排序的问题等
  • 给一个函数getZeroorOne(),返回 0 和 1,概率为 p 和 1-p,请你实现一个函数,使得返回 01 概率一样。 int i = getZeroorOne(); int j = getZeroorOne(); if(i==0 && j==0) return 1; if(i==1 && j==1) return 0;
  • 10亿个url,每个url大小小于56B,要求去重,内存4G。

思路:1)首先给定得url调用hash方法计算对应hash的value,在10亿的url中相同url必然由相同的value;2)将文件的hash table放在第value%n 台机器上;3)value/n 是机器上hash table的值;

将文件分布在多个机器上,这样要处理王亮延时,假设n个机器;1)首先hash文件得到hash value

v;2)将文件的hash table 放到第v%n台机器上;3)v/n是机器的hash table的值;

分析:将文件的url进行hash,得到值value,相同的url的文件具有相同的value,所以会被分配到同一台机器v%n上。在同一台机器上的重复的url文件具有相同的value/n值,如果出现了冲突,不同的url在同一台机器上也可能有相同的value/n值。在每个机器上将value/n值作为key,url值作为value构成hash表进行去重。最后将内存中去重后的hash表中的value值即url写入磁盘。合并磁盘中的各部分url文件,完成去重。

  • 把一个 bst 转化成一个双向链表。

搜索二叉树,转换为双向链表;中序遍历bst树,每输出一个节点便将其添加到双向链表中。

  • http 和 https 区别,https 在请求时额外的过程,https 是如何保证数据安全的。

http是明文传输,传输的数据很可能被中间节点获取,从而导致数据传输不安全;

https是加密传输,可以保证数据的传输安全;https则是在应用层与传输层之间又加了一层,该层遵守SSL/TLS协议,用于数据加密。SSL是个加密套件,负责对HTTP的数据进行加密。TLS是SSL的升级版。

  • IP 地址子网划分。

地址分类;网络位和主机位;子网掩码和IP换算;

  • POST 和 GET 区别。
  • 硬链接和软连接区别。

软连接,其实就是新建立一个文件,这个文件就是专门用来指向别的文件的(那就和windows 下的快捷方式的那个文件有很接近的意味)。

硬连接是不会建立inode的,他只是在文件原来的inode link count域再增加1而已,也因此硬链接是不可以跨越文件系统的。

  • DNS 解析过程。
  1. 浏览器先检查自身缓存中有没有被解析过的这个域名对应的ip地址,如果有,解析结束。同时域名被缓存的时间也可通过TTL属性来设置。
  2. 浏览器不命中,在windows中可通过c盘里一个叫hosts的文件来设置,如果你在这里指定了一个域名对应的ip地址,那浏览器会首先使用这个ip地址。
  3. 请求本地域名服务器(LDNS)来解析这个域名,这台服务器一般在你的城市的某个角落,距离你不会很远,并且这台服务器的性能都很好,一般都会缓存域名解析结果,大约80%的域名解析到这里就完成了。
  4. 如果LDNS仍然没有命中,就直接跳到Root Server 域名服务器请求解析
  5. 根域名服务器返回给LDNS一个所查询域的主域名服务器(gTLD Server,国际顶尖域名服务器,如.com .cn .org等)地址
  6. 此时LDNS再发送请求给上一步返回的gTLD
  7.  接受请求的gTLD查找并返回这个域名对应的Name Server的地址,这个Name Server就是网站注册的域名服务器
  8. Name Server根据映射关系表找到目标ip,返回给LDNS
  9. LDNS缓存这个域名和对应的ip
  10. LDNS把解析的结果返回给用户,用户根据TTL值缓存到本地系统缓存中,域名解析过程结束;
  • kill 用法,某个进程杀不掉的原因(进入内核态,忽略 kill 信号)。
  • linux 用过的命令。
  • 系统管理命令(如查看内存使用、网络情况)。
  • 管道的使用。
  • grep 的使用,一定要掌握,每次都会问在文件中查找。
  • shell 脚本。15、find 命令。16、awk 使用。
  • Linux 下的一些指令,(进程id), (进程 id),(进程id),?(上一条命令退出时状态),怎么查看进程,按照内存大小,CPU 占用排序等等。(大写 M 和大写 P)。
  • 介绍下你所了解的 epoll。

select/poll每次调用都会线性扫描全部的集合(同时还会轮询),导致效率呈现线性下降。而epoll不存在这个问题,因为epoll会为每个描述符FD注册一个回调函数,只有“活跃”的socket才会主动调用callback函数,其他idle状态socket则不会。当调用callback函数的FD,才返回相应的事件。

使用mmap加速内核与用户空间的消息传递;

select、poll、epoll都需要内核把fd消息通知给用户空间。而epoll通过内核与用户空间mmap处于同一块内存实现消息的传递。

  • 手写一个全排列。

全排列就是从第一个数字起每个数分别与它后面的数字交换;递归和非递归;

去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换;

全排列的非递归就是由后向前找替换数和替换点,然后由后向前找第一个比替换数大的数与替换数交换,最后颠倒替换点后的所有数据。

  • 介绍一下 Hash,怎么解决冲突。

1)开放地址法;线性探测再散列;伪随机探测再散列;2)再哈希法;3)链地址法(拉链法):将所有关键字为同义词的记录存储在同一线性链表中。4)建立一个公共溢出区:

  • 进程间的通信,共享内存方式的优缺点。

1)信号提前注册信号,有事通知就行;2)信号量:信号量实际上是一个计数器,通常在多线程或者多进程开发中会用到,主要用来控制多线程多进程对于共享资源访问,通常配合锁来实现同时只有一个进程或者线程操作共享资源,防止数据的不同步。3)消息队列:消息队列是消息的链表,存放在内核中并由消息队列表示符,我们可以在两个进程之间通过消息队列来实现进程间通信。不过消息队列在工作中好像并不怎么常用。4)无名管道 :主要用于父进程与子进程之间,或者两个兄弟进程之间。“先入先出”(FIFO)。5)有名管道:任何进程可以在任何时间通过文件名或路径名与该文件建立联系。6)共享内存:在系统内存中开辟一块内存区,分别映射到各个进程的虚拟地址空间中,任何一个进程操作了内存区都会反映到其他进程中。

  • 写个 strcpy 函数
  1. public static String copy(String s)
  2.  {
  3.   if(s == null || s.trim().isEmpty())
  4.    return null;
  5.   char[] a = s.toCharArray(); //任意字符数组
  6.   char[] b = new char[a.length];
  7.   for(int i=0;i<a.length;i++)
  8.   {
  9.    b[i] = a[i];
  10.   }
  11.   return new String(b);
  12.  }
  13. }
  • 给你一个系统(面试官好像是无人车部门的),后台的逻辑已经实现了,但是前端加载很慢,怎么检测。

浏览器自带插件可以看对应http请求耗时的;

  1. 后端的问题:看请求瀑布图,如果第一个请求特别长、特别长,明显比其他请求放到一起不和谐。
  2. 请求数太多:数一下瀑布图总共有多少行;css,js该合并的合并;
  3. 看看其他请求,这个请求比其他请求的时间大出一个数量级。可能是:(a)资源在第三方站点上,他们很慢;(b)这个资源太大了;(c)这个资源使用的域名有问题。
  4. 接收数据时间过长:大的图片进行压缩处理;
  5. Js阻塞请求:解析js花费太久;如果出现两个连续请求出现较大的空隙;
  • 系统的量级、pv、uv 等。

Pv:页面浏览量;通过url标识进行统计;

UV:访问人数:根据ip进行统计;

  • 分布式缓存的一致性,服务器如何扩容(哈希环)。

 一致性hash算法通过构造一个长度为2^32的整数环,根据节点名的hash值将缓存服务器节点放置在这个环上,然后计算要缓存的数据的key的hash值,顺时针找到最近的服务器节点,将数据放到该服务器上。

  • 观察者模式代码(设计模式有专门准备)

要创建的三个接口,分别为:https://blog.csdn.net/u014453898/article/details/79167927

1.Subject接口 :用于指定天气观测站(数据源)应该要具有的方法

addObserver() :用于加入一个气象报告板(观察站)到观察者列表中

deleteObserver() :用于从观察者列表中删除一个观察者

notifyObservers() :用于向观察者列表的所有观察者发送数据

setChanged() :当调用 notifyObserver() 之前,必须先调用一次setChanged()

2.Observer接口

update() :当从数据源处获得数据后,调用update()更新报告板(观察者)的数据。

3.DisplayElement接口

display() :用于显示报告板的数据

  • 聊分布式锁的实现
  1. 基于数据库实现分布式锁

基于数据库表,创建一张锁表,通过操作该表进行实现;

基于数据库排他锁:创建锁表,然后再结合排他锁;

  1. 基于缓存(redis,memcached,tair)实现分布式锁

解决单点问题;基于Tair的实现分布式锁其实和Redis类似;

  1. 基于Zookeeper实现分布式锁

基于zookeeper临时有序节点可以实现的分布式锁。

  • redis用的什么命令,问 redis 集群缓存数据不均衡怎么做。

增加一个间接的中间层来解决,我感觉在客户端和redis服务之间加一层就能解决;

缓存架构,使用的堆内缓存 + redis 缓存(二层缓存架构方案)。

  • 问了数据一致性怎么做的?有没有做过相关压测?指标是多少?熔断降级有没有做过?

1)消息队列;将票数资源存在redis中,将请求存入消息队列(redis下的list阻塞的,可以实现消息队列,还可以实现优先消息队列)中,依次处理。缺点 :这样会处理比较慢,等待时间比较长。

2)加锁:乐观锁+回滚;

6、在设计商品域的时候走的弯路

比如商品快照问题怎么解决的,因为当时我们做这一块的时候,所有涉及到商品域属性变更都会生成快照,造成数据量暴增。一些操作日志表有的表已经有分库分表上万张了。

7、详情页的设计,怎么做的缓存设计?(比如从不同的业务纬度拆分key,更新频率拆分key)

因为我们之前因为QPS都不算高,价格,库存都是直接实时查询数据的,结合兜底方案来解决。

8、下单要建几张表?我说订单主表,订单条目表(有的场景下,订单条目会创建很多条)。

9、面试官问我怎么优化?(针对创建的订单条目太多的问题)

首先订单表可以分库分表来解决单DB的写入瓶颈;面试官不满意,我说可以先创建订单主表,如果订单条目表是瓶颈那么梳理一下业务,看看订单条目是否可以异步创建,走MQ,然后面试官还是不满意,我说我只能这么优化了,暂时没想到更多的方案

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洋葱ycy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值