字节跳动广告后台开发面试经历

机会只留给那些准备充分的人

Posted by irving.gx on February 23, 2020

前言

疫情期间在家办公的时候突然接到一个电话,说把从池子中捞起来了,问我要不要面试一下字节的广告后台。在接到电话之后有点犹豫,距离上一次面试已经过了一个月之久,这期间已经停止复习了,该忘的也都忘得差不多了,不知道到时候面试的时候能拿出几分功力。不过最终还是想试试吧,然后就答应了。

面试(基础+算法)

这次是在家视频面试,面试官看起来年轻也挺友善的,自我介绍之后就开始了正式的技术面。之前去现场面试的时候三位面试官都没有问过java方面的问题,所以这次面试之前就没有做过java相关的准备。然而。。。虽然字节跳动后台是以go为主的,但是面试官问了相当多的java的问题。

1.ping用的是什么协议,ttl是什么意思?

ICMP(Internet控制报文协议),位于网络层,和IP协议位于同一层。TTL(time to live)表示生存时间,每当一个数据包经过一个路由器的时候这个数值就会减1,起始是有一个总数的。

2.http get与post区别是什么?

get规范用于获取数据,而post规范用于修改数据,但是get也可以修改数据。有一个误区是get比post提交的数据量要小,这是一个误区,get是因为参数会附加在url后面,浏览器对于参数长度会有限制,http本身并没有对get的携带信息量做限制。

3.如何获取域名的ip?

可以ping域名,会从结果中看到对应域名的ip;可以通过nslookup命令来查找(查询dns记录,域名解析是否正常)

4.http能复用TCP吗?

tcp可以将前端的多个http请求复用到后端一个tcp请求上,可以减小服务器性能负载。

5.常用的垃圾回收算法以及垃圾回收器?

6.hashtable与ConcurrentHashMap的区别?

7.多线程同步的几种方法?

  • 加锁(包括synchronized关键字以及java.util.concurrent包当中的ReentrantLock)
  • 使用ThreadLocal本地变量实现线程同步
  • semaphore信号量
  • wait/notify机制 上述的是一些比较基础的类,juc提供了一些并发工具类来实现线程的同步,比如CountDownLatch以及CyclicBarrier

8.MySQL有哪几种引擎?MyISAM与InnoDB有什么区别?

1 InnoDB引擎

  • 支持事务
  • 使用行级锁
  • 支持热备份,也就是说数据库在正常运行时进行备份
  • InnoDB的主索引是聚簇索引,缓存机制是不仅会缓存索引还会缓存数据
  • 支持外键关联
  • 灾难恢复性好

2 MyISAM引擎

  • 不支持事务
  • 使用表级锁,并发比较差
  • 支持热备份,也就是说数据库在正常运行时进行备份
  • InnoDB的主索引是聚簇索引,缓存机制是不仅会缓存索引还会缓存数据
  • 支持外键关联
  • 灾难恢复性不佳
  • 只缓存索引

3 Memory存储引擎

  • 不支持事务
  • 提供内存表,可以显著提高访问速度
  • 只支持固定大小的行

9.限流有哪些算法?

  • 计数器算法。就是简单地记录请求的总数,比如qps=100,设定1s只通过100个请求,如果达到了100个,那么后面的请求都会被拒绝。这样的算法有一个弊端,就是如果出现突刺的话(比如1s中的前10ms出现一个高峰,已经达到了100,那么后面的990ms就只能等待。
  • 漏桶算法。就是无论进来的请求有多么不稳定,处理请求的速度都是固定的,正如它的名字所说的那样,像漏桶那样输出的速度是固定的。具体实现是采用一个队列来保存请求,采用线程池来定时处理请求。这种算法也是无法解决短时间的突发流量。
  • 令牌桶算法。这种算法是对漏桶算法的改进,有一个令牌工厂会以一定的速度生产令牌,并且令牌桶中令牌数目是一定的,如果令牌数目超过上限,那么令牌就会被丢弃掉,请求只有当拿到令牌的时候才会继续进行。该算法可以抵挡瞬时的令牌桶上限的请求数目。

10.设计一个熔断器

Hytrix是熔断领域的一个佼佼者,熔断器分为三个状态,close,open,half-open。close表示熔断器关闭,有一个计数器会进行调用失败次数的计数,达到一定阈值会将熔断器开启。open状态是开启熔断器,在这个状态中会对请求进行拒绝,有一个时钟选项,是平均故障处理时间,如果过了这个时间会进入half-open状态。这个状态会允许一定量的请求进来,如果一定数目或者比例的请求成功了,就将熔断器关闭,否则认为故障仍然存在,会将熔断器重新开启。

11.设全局唯一的id生成器?如果需要自增又该怎么办?

如果仅仅需要全局唯一的话,那么UUID就能够满足需求,UUID保证每台机器在不同时间生成的id不会与其他生成的id重复,因为这个生成的id包含了生成机器的信息。但是生成的字符串占用空间比较多,而且索引效率会比整型要低。所以生成整型的是较优的一种策略:

  • MySQL自增id。这种方式就是用MySQL的唯一自增主键作为id,这种方式能保证每个表都是唯一的,在生成之前需要读取这个表的id,然后插入到数据库一条记录。这种方式在生成之前拿不到最新的id,需要读取与插入两次操作,而且数据库要加锁来保证id的唯一性,效率会比较低。
  • Redis或者Zookeeper。这种方式就是采用开源的中间件来生成唯一自增id,能够满足要求。
  • 采用Twitter snowflake的思想,就是将时间戳+机器编号标识+自增id作为唯一的表示来生成自增id。

如果对你有帮助,请作者喝一杯牛奶吧