首页 > 快手运营 > 快手面经篇一据说看了面试通过率提升50%
2020
05-02

快手面经篇一据说看了面试通过率提升50%

  都说金三银四,对于找工作的人来说,因为每年的三月或四月是不少互联网公司的年终季,不少人都是拿到年终奖后不满意,或者感觉职业发展受限,之后跑路。这样不少部门因为人员流动,就会有hc空缺出来。

  ==这里要说的是每年3、4月份确实是hc最多的季节,但同时是跳槽旺季,竞争大,你要想找到好的坑位,那就需要绝对的实力才行。==

  相对来说,其实年底是个好时候,俗话说,铁打的营盘流水的兵,互联网的阵地上不少岗位是常年招人,常年缺人,当然hc并不富裕,但是年底的时候,看机会的人也少。毕竟不少人还是很在意“年终奖”的嘛。所以说,年底跳槽你可能会损失一部分年终奖,但换工作的竞争性相对来说也会少很多,竞争的人少了嘛,说不定你就可以凭“运气的实力”脱颖而出呢?

  分析这个题目其实很基础,可以理解为是以26为基准的进制转换,一个for循环,除了末尾的字符直接加到结果上之外,其他的字符位-A+1的结果乘以26*(该字符位置与末尾的差值)。做这种题目一定要先思考,自己手动实现一下。

  如果想看具体代码答案,可以扫码关注【程序员之道】,后台回复“快手列转换”。

  如果没有接触过高并发,或者没有使用过redis作为分布式锁,那这这个算法肯定是写不出来的,而且像这种算法,一般来说可能也就是让讲讲思路。具体实现确实有点难。

  思考了这些,你能写成正确的加锁,解锁方式吗?具体的坑及正确的加解锁方式,关注【程序员之道】,后台回复“redis分布式锁”。

  (1)尽量减少like,但不是绝对不可用,”xxxx%” 是可以用到索引的 (2)表的主键、外键必须有索引 (3 谁的区分度更高(同值的最少),谁建索引,区分度的公式是count(distinct(字段))/count(*) (4)单表数据太少,不适合建索引 (5)

  ,order by ,group by 等过滤时,后面的字段最好加上索引 (6)如果既有单字段索引,又有这几个字段上的联合索引,一般可以删除联合索引; (7)联合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替: (8)联合索引: mysql 从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index(a,b,c). 可以支持 aa,ba,b,c 3种组合进行查找,但不支持 b,c 进行查找.当最左侧字段是常量引用时,索引就十分有效。 (9)前缀索引: 有时候需要索引很长的字符列,这会让索引变得大且慢。通常可以索引开始的部分字符,这样可以大大节约索引空间,从而提高索引效率。其缺点是不能用于ORDER BY和GROUP BY操作,也不能用于覆盖索引 Covering index(即当索引本身包含查询所需全部数据时,不再访问数据文件本身)。 (10)NULL会导致索引形同虚设

  redis里有哪些数据结构,都用过什么?redis里Sorted Set怎么用,需要传什么参数?

  redis的数据结构:String,Hash、List、Set、Sorted Set,用过哪些就说哪些就行了,没用过的,估计你根据名词也能大概猜出是什么。

  面试官问Sorted Set大概是你听到你说了Sorted Set,所以问一下你命令,看你是不是真的知道啊,不知道的话,这下没法蒙混过关了吧。有序集合,设置每个key的时候需要传入一个score参数。具体命令zadd key score value。还有一些其他的命令google学习一下吧!

  volatile主要是保证多线程访问时的可见性。我们知道计算机为了提高访问内存的速度,引入了工作内存和主内存的概率,多线程访问数据时,访问的是工作内存的数据,各个线程之间的工作内存是分别隔离的。这就可能导致同一个变量,由于工作内存的存在,在不同线程“看到的值”是不一样的。但volatile关键字,强制了各线程读取变量时必须从主内存读取,同时对变量的修改也直接刷新到主内存,这样就保证了同一变量修改的同时可以立刻被其他线程“看到”。这里面使用了“内存屏障”的技术。

  对于count++,操作系统执行时,并不是一个原子操作,分为三步:1)将count变量load到内存。2)执行count+1。3)将结果存入内存。非原子性操作,任何一个步骤执行的时候,都可能被其他线程打断,所以多线程执行时会有问题。

  使用volatile修饰也是不可以的,因为始终不是原子操作,也只是保证可见性而已,原子性的问题无法解决。

  JVM内存分配几乎是每个java开发人员的面试必考点,单纯这部分的内容都够写几个篇章的了。这里只是简单的介绍一下。

  JVM内存分为年轻代和老年代,其中年轻代又分为S0、S1、Eden区,JVM采用分代垃圾回收算法,因为这样才能更充分的利用年轻代和老年代的对象特点,最大化的提高垃圾回收效率。

  常见的垃圾回收算法有复制算法、标记清除、标记整理,然后又引出不同的垃圾回收器,垃圾回收器的迭代是不断发现问题并优化的过程,新生代收集器使用的收集器:Serial、PraNew、Parallel Scavenge;老年代收集器使用的收集器:Serial Old、Parallel Old、CMS。然后结合自己的理解再说一下!

  JVM的栈是线程私有的,一些基本变量都是存储在栈中的,Java栈中存放的是一个个的栈帧,每个栈帧对应一个被调用的方法,在栈帧中包括局部变量表(Local Variables)、操作数栈(Operand Stack)、指向当前方法所属的类的运行时常量池(运行时常量池的概念在方法区部分会谈到)的引用(Reference to runtime constant pool)、方法返回地址(Return Address)和一些额外的附加信息。当线程执行一个方法时,就会随之创建一个对应的栈帧,并将建立的栈帧压栈。当方法执行完毕之后,便会将栈帧出栈。

  为什么有了堆之后还要有栈?栈的存在可以说是为了解决递归调用的问题。如果只有堆内存,那就不会有递归调用了。

  分布式自增id怎么实现,如果用redis实现,怎么保证与数据库的一致性?

  分布式自增id一般使用MySQL的自增id、redis的incr函数,还有比较经典的雪花算法。

  使用redis产生自增id,就要防止redis崩溃的可能性,一般在MySQL或hbase中记录当前最大的value值。或者如果你设计的是一个聊天室,那肯定是有持久化存储当前聊天室的最大seqId,如果redis集群出现崩溃,从持久化存储的地方取出最大seqId然后自增即可。

  ArrayList的底层实现是数组,数组的扩容是不断通过复制来完成的,所以存储的数据容量不断发生变化时,ArrayList的性能是比较差的。使用ArrayList时一般都是预知数据的最大容量。如果能直接使用数组,那使用数组当然是最好的了。

  LinkedList的底层实现是链表,发生数据扩容时,性能较好,但同容量情况下占用的空间比ArrayList要大。对于数据频繁扩容的情况,推荐使用LinkedList。

  程序员的小伙伴们,觉得自己孤单么,那就加入公众号[程序员之道],一起交流沟通,走出我们的程序员之道!

  Python量化投资网携手4326手游为资深游戏玩家推荐:《数字迷阵下载》

  看看这篇文章吧,有惊喜哦!&site=Python量化投资&summary=写给正在找工作的你 都说金三银四,对于找工作的人来说,因为每年的三月或四月是不少互联网公司的年终季,不少人都是拿到年终奖后不满意,或者感觉职业发展受...&pics=&title=快手面经篇一,据说看了面试通过率提升50%,weixin,500,500) class=qzone

  看看这篇文章吧,有惊喜哦!&title=快手面经篇一,据说看了面试通过率提升50%&summary=写给正在找工作的你 都说金三银四,对于找工作的人来说,因为每年的三月或四月是不少互联网公司的年终季,不少人都是拿到年终奖后不满意,或者感觉职业发展受...&pics=&site=Python量化投资,qq,1100,800) class=qq


本文》有 0 条评论

留下一个回复