商汤科技面试总结(上)

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
简介: 一、kafka数据分区和消费者的关系,kafka的数据offset读取流程,kafka内部如何保证顺序,结合外部组件如何保证消费者的顺序

一、kafka数据分区和消费者的关系,kafka的数据offset读取流程,kafka内部如何保证顺序,结合外部组件如何保证消费者的顺序1、kafka数据分区和消费者的关系:1个partition只能被同组的一个consumer消费,同组的consumer则起到均衡效果2、kafka的数据offset读取流程a.连接ZK集群,从ZK中拿到对应topic的partition信息和partition的Leader的相关信息b.连接到对应Leader对应的brokerc.consumer将⾃己保存的offset发送给Leaderd.Leader根据offset等信息定位到segment(索引文件和⽇志⽂文件)e.根据索引文件中的内容,定位到日志文件中该偏移量对应的开始位置读 取相应⻓度的数据并返回给consumer3、kafka内部如何保证顺序:kafka只能保证partition内是有序的,但是partition间的有序是没办法的。爱奇艺的搜索架构,是从业务上把需要有序的打到同⼀个partition。二、cms垃圾回收机制

1、概念:CMS全称 Concurrent Mark Sweep,是一款并发的、使用标记-清除算法的垃圾回收器器,

2、使用场景:GC过程短暂停,适合对时延要求较高的服务,用户线程不允许⻓时间的停顿。

3、缺点:

a.服务长时间运⾏,造成严重的内存碎片化。

b.算法实现比较复杂(如果也算缺点的话)。

4、实现机制:根据GC的触发机制分为:

a.周期性Old GC(被动):2s执行一次;

b.主动Old GC:触发条件:

  i. YGC过程发⽣生Promotion Failed,进⽽对老年代进行回收

  ii.比如执行了System.gc(),前提是没有参数ExplicitGCInvokesConcurrent

  iii. 其它情况

三、springcloud各个组件功能,内部细节,与dubbo区别,dubbo架构,dubbo负载策略略

1、springcloud各个组件功能:

a. Ribbon,客户端负载均衡,特性有区域亲和、重试机制。

b. Hystrix,客户端容错保护,特性有服务降级、服务熔断、请求缓存、请求合并、依赖隔离。

c. Feign,声明式服务调用,本质上就是Ribbon+Hystrix

d. Stream,消息驱动,有Sink、Source、Processor三种通道,特性有订阅发布、消费组、消息分区。

e. Bus,消息总线,配合Config仓库修改的一种Stream实现,

f. Sleuth,分布式服务追踪,需要搞清楚TraceID和SpanID以及抽样,如何与ELK整合。

g. Eureka,服务注册中心,特性有失效剔除、服务保护。

h. Dashboard,Hystrix仪表盘,监控集群模式和单点模式,其中集群模式需要收集器Turbine配合。

i. Zuul,API服务网关,功能有路由分发和过滤。

j. Config,分布式配置中⼼,支持本地仓库、SVN、Git、Jar包内配置等模式,

2、dubbo负载策略:

Random LoadBalance

a.随机,按权重设置随机概率。

b.在一个截面上碰撞的概率高,但是调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

RoundRobin LoadBalance

a.轮询,按公约后的权重设置轮询比率。

b.存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

LeastActive LoadBalance

a.最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。

b.让慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差越大。

ConsistentHashLoadBalance

a.一致性Hash,相同参数的请求总是发到同一提供者。

b.当某一台提供者挂时,原本发生该提供者的请求,基于虚拟节点,平摊到其他提供者,不会引起剧烈变动。

c.缺省只对第一个参数Hash,如果要修改,请配置


<dubbo:parameter key="hash.arguments" value="0.1"/>

d.缺省用160份虚拟节点,如果要修改,请配置


<dubbo:parameter key="hash.nodes" value="320"/>

四、mapreduce原理

1、简介:mapreduce源⾃自google的一篇⽂章,将海量数据处理的过程拆分为map和reduce。mapreduce 成为了最早的分布式计算框架,这样即使不懂的分布式计算框架的内部运行机制的用户,也可以利用分布式的计算框架实现分布式的计算,并在hadoop上面运行。

2、设计思想:

hadoop ⽂件系统 ,提供了一个分布式的文件系统,但是hadoop文件系统读写的操作都涉及到大量的网络的操作,并不能很好的完成实时性比较强的任务。但是hadoop可以给上面的应用提供⼀个很好的支持。比如hadoop文件系统上⾯可以运行mapreduce。mapreduce是⼀个计算的框架,mapreduce是一个分布式的计算框架,这样mapreduce利用分布式的⽂件系统,将不同的机器上完成不同的计算,然后就计算结果返回。这样很好的利用了分布式的文件系统。数据分布式的存储,然后计算的时候,分布式的计算,然后将结果返回。这样的好处就是不会涉及到⼤量的⽹络传输数据。

3、优点:mapreduce的计算框架的优点是,极强的扩展能力,可以在数千台机器器上并发的执行。其次,有很好的容错性,另外,就是向上的接口简洁。⽤户只需要写map和reduce函数,即可完成大规模数据的并⾏处理。

4、缺点:mapreduce并不适合对实时性要求比较⾼的场景,比如交互式查询或者是流式计算。另外,也不适合迭代类的计算(⽐如机器学习类的应⽤)。

五、nio,bio,sellector/epoll,aio,netty自带编解码器,netty优势,java内存模型

Netty高性能:

1、NIO异步非阻塞通信

2、“零拷贝”

3、内存池ByteBuf

4、Netty提供了多种内存管理策略,通过在启动辅助类中配置相关参数,可以实现差异化的定制。

5、⾼效的Reactor线程模型:Reactor单线程(多线程、主从)模型,指的是所有的IO操作都在同⼀一个NIO线程上面完成

6、为了尽可能提升性能,Netty采⽤了串⾏⽆锁化设计,在IO线程内部进行串⾏操作,避免多线程竞争导致的性能下降。表⾯上看,串⾏化设计似乎CPU利用率不⾼,并发程度不够。但是,通过调整NIO线程池的线程参数,可以同时启动多个串行化的线程并行运行,这种局部无锁化的串行线程设计相比一个队列-多个工作线程模型性能更优。

7、高效的并发编程:Netty的⾼效并发编程主要体现在如下⼏点:

a.volatile的⼤量、正确使用;

b. CAS和原⼦类的广泛使用;

c. 线程安全容器的使用;

d. 通过读写锁提升并发性能。

e.高效的序列化框架:

f.灵活的TCP参数配置能力:合理设置TCP参数在某些场景下对于性能的提升可以起到显著的效果,例如SO_RCVBUF和SO_SNDBUF。如果设置不当,对性能的影响是非常⼤的。

六.akka模型

1、概念:Akka是一个构建在JVM上,基于Actor模型的的并发框架,为构建伸缩性强,有弹性的响应式并发应用提⾼更好的平台。

2、Actor模型:Akka的核心就是Actor,所以不得不说Actor,Actor模型我通俗的举个例⼦,假定现实中的两个人,他们只知道对⽅的地址,他们想要交流,给对⽅传递信息,但是又没有手机,电话,⽹络之类的其他途径,所以他们之间只能用信件传递消息,很像现实中的的邮政系统,你要寄一封信,只需根据地址把信投寄到相应的信箱中,具体它是如何帮你处理送达的,你就不需要了解了,你也有可能收到收信人的回复,这相当于消息反馈。上述例⼦中的信件就相当于Actor中的消息,Actor与Actor之间只能通过消息通信。

image.png

七、java arraylist,linkedlist区分及实现原理,hashmap和concurrenthashmap区分及实现原理,concurrenthashmap 1.7和1.8区分,实现细节linkedhashmap排序原理,应⽤如何保证数据幂等

       1、java arraylist,linkedlist区分及实现原理:

image.png

a. ArrayList是实现了基于动态数组的数据结构,⽽LinkedList是基于链表的数据构;

b. 对于随机访问get和set,ArrayList要优于LinkedList,因为LinkedList要移动指针;

c. 对于添加和删除操作add和remove,⼀般大家都会说LinkedList要比ArrayList快,因为ArrayList要移动数据。

2、concurrenthashmap 1.7和1.8区分:

去除 Segment + HashEntry + Unsafe的实现,改为 Synchronized + CAS + Node + Unsafe的实现。其实 Node 和 HashEntry 的内容一样,但是HashEntry是⼀个内部类。用 Synchronized + CAS 代替 Segment ,这样锁的粒度更⼩了,并且不是每次都要加锁了,CAS尝试失败了在加锁。put()⽅法中 初始化数组大小时,1.8不用加锁,因为⽤了个 sizeCtl变量,将这个变量置为-1,就表明table正在初始化。

3、linkedhashmap排序原理:







public linkedHashMap(){//调用HashMap的构造方法,其实就是初始化Entry[] tablesuper();//这里是指是否基于访问排序,默认为falseaccessOrder=false;}

a.LinkedHashMap存储数据是有序的,⽽且分为两种:插⼊顺序和访问顺序。默认为插入顺序。

b.LinkedHashMap有自⼰的静态内部类Entry,它继承了HashMap.Entry,定义如下:











/***LinkedHashMap entry*/private static class Entry<K,V>extends HashMap.Entry<K,V>{//These fieds comprise the doubly linked list used  for iteration.Entry<K,V>befor,after;Entry(int hash,K key,V value,HashMap.Entry<K,V>next){      super(hash,key,value,next);}}

c.所以LinkedHashMap构造函数,主要就是调⽤HashMap构造函数初始化了⼀个Entry[] table,然后调⽤⾃身的init初始化了⼀个只有头结点的双向链表。

八、web.xml listener,filter,servlet加载顺序。

web.xml listener,filter,servlet加载顺序:context-param -> listener -> filter -> servlet

九、无穷数就top K问题,提供多个方案

1、最简单且最容易想到的算法是对数组进行排序(快速排序),然后取最大或最⼩的K个元素。总的时间复杂度为

O(N*logN)+O(K)=O(N*logN)。该算法存在以下问题:

a. 快速排序的平均复杂度为O(N*logN),但最坏时间复杂度为O(n2),不不能始终保证较好的复杂度

b. 只需要前k大或k小的数,,实际对其余不需要的数也进行了排序,浪费了大量排序时间

总结:通常不会采取该⽅案。

2、虽然我们不会采用快速排序的算法来实现TOP-K问题,但我们可以利用快速排序的思想,在数组中随机找⼀一个元素key,将数组分成两部分Sa和Sb,其中Sa的元素>=key,Sb的元素<key,然后分析两种情况:

a. 若Sa中元素的个数大于或等于k,则在Sa中查找最大的k个数

b. 若Sa中元素的个数小于k,其个数为len,则在Sb中查找k-len个数字

如此递归下去,不断把问题分解为更小的问题,直到求出结果。

3、寻找N个数中的第K大的数,可以将问题转化寻找N个数中第K大的问题。对于一个给定的数p, 可以在O(N)的时间复杂度内找出

所有不小于P的数。

根据分析,可以使⽤二分查找的算法思想来寻找N个数中第K大的数。假设N个数中最⼤的数为Vmax,最⼩的数为Vmin, 那么N个数

中第K大的数⼀定在区间[Vmin,Vmax]之间。然后在这个区间使用二分查找算法。

总结:该算法实际应⽤效果不佳,尤其是不同的数据类型需要确定max - min > delta,因此时间复杂度跟数据分布有关。整个算法的时间复杂度为O(N * log(Vmax-Vmin)/delta),在数据分布平均的情况下,时间复杂度为O(N * logN)。

4、上⾯⼏种解法都会对数据访问多次,那么就有⼀个问题,当数组中元素个数⾮常⼤时,如:100亿,这时候数据不能全部加载到内存,就要求我们尽可能少的遍历所有数据。针对这种情况,下面我们介绍⼀种针对海量数据的解决方案。

在学习堆排序的过程中,我们知道了堆这种数据结构。为了查找Top k大的数,我们可以使用大根堆来存储最⼤的K个元素。大根堆的堆顶元素就是最大K个数中最小的⼀个。每次考虑下一个数x时,如果x比堆顶元素小,则不需要改变原来的堆。如果想x比堆顶元素大,那么用x替换堆顶元素, 同时,在替换之后,x可能破坏最⼩堆的结构,需要调整堆来维持堆的性质。

总结:该算法只需要扫描所有的数据一次,且不会占⽤太多内存空间(只需要容纳K个元素的空间),尤其适合处理海量数据的场景。算法的时间复杂度为O(N * logk),这实际上相当于执行了部分堆排序。

5、TOP-K问题是一个经典的问题,这个问题是存在线性算法的,只不过算法的使用范围有⼀定的限制。如果所有N个数都是正整数,且他们的取值范围并不大,可以考虑申请空间,记录每个整数出现的次数,然后再从大到小取最大的K个。实际就是利⽤计数排序的思想。假设所有整数都在(0,maxN)区间,利⽤用一个数组count[maxN]来记录每个整数出现的次数。count[i]表示整数i在N个数中出现的次数。只需要扫描⼀遍就可以得到count数组,然后寻找第K大的元素。

这是一个典型的以空间换取时间的做法。当数组中取值范围⽐较大时,是极其浪费空间的。如[3,1...9999],为了求出最大的K个元素,需要额外申请一个长度为10000的数组。

极端情况下,如果 N 个整数各不相同,我们甚⾄只需要⼀个 bit 来存储这个整数是否存在,这样可节省很大的内存空间。

目录
相关文章
|
13天前
|
SQL Java 数据库
【面经】亚信科技面试问题合集
【面经】亚信科技面试问题合集
|
28天前
|
人工智能 算法
来自科技时代的面试-AI面试
【5月更文挑战第19天】来自科技时代的面试-AI面试
|
1月前
|
前端开发 JavaScript
JavaScript新科技:PostCSS的安装和使用,2024年最新2024网易Web前端高级面试题总结
JavaScript新科技:PostCSS的安装和使用,2024年最新2024网易Web前端高级面试题总结
|
1月前
|
算法 定位技术 数据中心
中国工商银行数据中心科技菁英校园招聘面试经历与体检情况
中国工商银行数据中心科技菁英校园招聘面试经历与体检情况
113 2
|
机器学习/深度学习 人工智能 测试技术
大通银行CIO为科技求职者提供的顶级面试技巧
大通银行CIO为科技求职者提供的顶级面试技巧
|
芯片 异构计算
【数字设计】芯动科技|芯原科技_2023届_笔试面试题目分享
【数字设计】芯动科技|芯原科技_2023届_笔试面试题目分享
【数字设计】芯动科技|芯原科技_2023届_笔试面试题目分享
|
前端开发 芯片
【数字设计】哲库科技_2023届_笔试面试题目分享
【数字设计】哲库科技_2023届_笔试面试题目分享
【数字设计】哲库科技_2023届_笔试面试题目分享
|
3天前
|
设计模式 SQL JavaScript
java面试宝典全套含答案
java面试宝典全套含答案
18 3
|
3天前
|
存储 Java
java面试题大全带答案_面试题库_java面试宝典2018
java面试题大全带答案_面试题库_java面试宝典2018
17 3
|
3天前
|
SQL 前端开发 Java
2019史上最全java面试题题库大全800题含答案(面试宝典)(4)
2019史上最全java面试题题库大全800题含答案(面试宝典)
17 3