精华内容
下载资源
问答
  • 一个HashMap跟面试官扯了半个小时

    万次阅读 多人点赞 2020-03-15 23:37:16
    一个HashMap能跟面试官扯上半个小时 关注 安琪拉的博客 1.回复面试领取面试资料 2.回复书籍领取技术电子书 3.回复交流领取技术电子书 前言 HashMap应该算是Java后端工程师面试的必问题,因为其中的知识点太多,很...

    一个HashMap能跟面试官扯上半个小时

    《安琪拉与面试官二三事》系列文章
    一个HashMap能跟面试官扯上半个小时
    一个synchronized跟面试官扯了半个小时
    一个volatile跟面试官扯了半个小时

    《安琪拉教鲁班学算法》系列文章

    安琪拉教鲁班放技能之动态规划

    前言

    HashMap应该算是Java后端工程师面试的必问题,因为其中的知识点太多,很适合用来考察面试者的Java基础。

    开场

    面试官: 你先自我介绍一下吧!

    安琪拉: 我是安琪拉,草丛三婊之一,最强中单(钟馗不服)!哦,不对,串场了,我是**,目前在–公司做–系统开发。

    面试官: 看你简历上写熟悉Java集合,HashMap用过的吧?

    安琪拉: 用过的。(还是熟悉的味道)

    面试官: 那你跟我讲讲HashMap的内部数据结构?

    安琪拉: 目前我用的是JDK1.8版本的,内部使用数组 + 链表红黑树;

    安琪拉: 方便我给您画个数据结构图吧:

    面试官: 那你清楚HashMap的数据插入原理吗?

    安琪拉: 呃[做沉思状]。我觉得还是应该画个图比较清楚,如下:

    在这里插入图片描述

    1. 判断数组是否为空,为空进行初始化;
    2. 不为空,计算 k 的 hash 值,通过(n - 1) & hash计算应当存放在数组中的下标 index;
    3. 查看 table[index] 是否存在数据,没有数据就构造一个Node节点存放在 table[index] 中;
    4. 存在数据,说明发生了hash冲突(存在二个节点key的hash值一样), 继续判断key是否相等,相等,用新的value替换原数据(onlyIfAbsent为false);
    5. 如果不相等,判断当前节点类型是不是树型节点,如果是树型节点,创造树型节点插入红黑树中;(如果当前节点是树型节点证明当前已经是红黑树了)
    6. 如果不是树型节点,创建普通Node加入链表中;判断链表长度是否大于 8并且数组长度大于64, 大于的话链表转换为红黑树;
    7. 插入完成之后判断当前节点数是否大于阈值,如果大于开始扩容为原数组的二倍。

    面试官: 陷入沉默,讲的这么清楚,难道是也关注了微信公众号【安琪拉的博客】,我继续按照套路问,刚才你提到HashMap的初始化,那HashMap怎么设定初始容量大小的吗?

    安琪拉: [这也算问题??] 一般如果new HashMap() 不传值,默认大小是16,负载因子是0.75, 如果自己传入初始大小k,初始化大小为 大于k的 2的整数次方,例如如果传10,大小为16。(补充说明:实现代码如下)

    static final int tableSizeFor(int cap) {
      int n = cap - 1;
      n |= n >>> 1;
      n |= n >>> 2;
      n |= n >>> 4;
      n |= n >>> 8;
      n |= n >>> 16;
      return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }
    

    补充说明:下图是详细过程,算法就是让初始二进制右移1,2,4,8,16位,分别与自己位或,把高位第一个为1的数通过不断右移,把高位为1的后面全变为1,最后再进行+1操作,111111 + 1 = 1000000 = 2 6 2^6 26 (符合大于50并且是2的整数次幂 )

    在这里插入图片描述

    面试官: 你提到hash函数,你知道HashMap的哈希函数怎么设计的吗?

    安琪拉: [问的还挺细] hash函数是先拿到 key 的hashcode,是一个32位的int值,然后让hashcode的高16位和低16位进行异或操作。

    面试官: 那你知道为什么这么设计吗?

    安琪拉: [这也要问],这个也叫扰动函数,这么设计有二点原因:

    1. 一定要尽可能降低hash碰撞,越分散越好;
    2. 算法一定要尽可能高效,因为这是高频操作, 因此采用位运算;

    面试官: 为什么采用hashcode的高16位和低16位异或能降低hash碰撞?hash函数能不能直接用key的hashcode?

    [这问题有点刁钻], 安琪拉差点原地💥了,恨不得出biubiubiu 二一三连招。

    安琪拉: 因为key.hashCode()函数调用的是key键值类型自带的哈希函数,返回int型散列值。int值范围为**-2147483648~2147483647**,前后加起来大概40亿的映射空间。只要哈希函数映射得比较均匀松散,一般应用是很难出现碰撞的。但问题是一个40亿长度的数组,内存是放不下的。你想,如果HashMap数组的初始大小才16,用之前需要对数组的长度取模运算,得到的余数才能用来访问数组下标。(来自知乎-胖君)

    源码中模运算就是把散列值和数组长度-1做一个"与"操作,位运算比取余%运算要快。

    bucketIndex = indexFor(hash, table.length);
    
    static int indexFor(int h, int length) {
         return h & (length-1);
    }
    

    顺便说一下,这也正好解释了为什么HashMap的数组长度要取2的整数幂。因为这样(数组长度-1)正好相当于一个“低位掩码”。“与”操作的结果就是散列值的高位全部归零,只保留低位值,用来做数组下标访问。以初始长度16为例,16-1=15。2进制表示是00000000 00000000 00001111。和某散列值做“与”操作如下,结果就是截取了最低的四位值。

      10100101 11000100 00100101
    & 00000000 00000000 00001111
    ----------------------------------
      00000000 00000000 00000101    //高位全部归零,只保留末四位
    

    但这时候问题就来了,这样就算我的散列值分布再松散,要是只取最后几位的话,碰撞也会很严重。更要命的是如果散列本身做得不好,分布上成等差数列的漏洞,如果正好让最后几个低位呈现规律性重复,就无比蛋疼。

    时候“扰动函数”的价值就体现出来了,说到这里大家应该猜出来了。看下面这个图,

    img

    右移16位,正好是32bit的一半,自己的高半区和低半区做异或,就是为了混合原始哈希码的高位和低位,以此来加大低位的随机性。而且混合后的低位掺杂了高位的部分特征,这样高位的信息也被变相保留下来。

    最后我们来看一下Peter Lawley的一篇专栏文章《An introduction to optimising a hashing strategy》里的的一个实验:他随机选取了352个字符串,在他们散列值完全没有冲突的前提下,对它们做低位掩码,取数组下标。

    img

    结果显示,当HashMap数组长度为512的时候( 2 9 2^9 29),也就是用掩码取低9位的时候,在没有扰动函数的情况下,发生了103次碰撞,接近30%。而在使用了扰动函数之后只有92次碰撞。碰撞减少了将近10%。看来扰动函数确实还是有功效的。

    另外Java1.8相比1.7做了调整,1.7做了四次移位和四次异或,但明显Java 8觉得扰动做一次就够了,做4次的话,多了可能边际效用也不大,所谓为了效率考虑就改成一次了。

    下面是1.7的hash代码:

    static int hash(int h) {
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }
    

    面试官: 看来做过功课,有点料啊!是不是偷偷看了公众号安琪拉的博客, 你刚刚说到1.8对hash函数做了优化,1.8还有别的优化吗?

    安琪拉: 1.8还有三点主要的优化:

    1. 数组+链表改成了数组+链表或红黑树;
    2. 链表的插入方式从头插法改成了尾插法,简单说就是插入时,如果数组位置上已经有元素,1.7将新元素放到数组中,原始节点作为新节点的后继节点,1.8遍历链表,将元素放置到链表的最后;
    3. 扩容的时候1.7需要对原数组中的元素进行重新hash定位在新数组的位置,1.8采用更简单的判断逻辑,位置不变或索引+旧容量大小;
    4. 在插入时,1.7先判断是否需要扩容,再插入,1.8先进行插入,插入完成再判断是否需要扩容;

    面试官: 你分别跟我讲讲为什么要做这几点优化;

    安琪拉: 【咳咳,果然是连环炮】

    1. 防止发生hash冲突,链表长度过长,将时间复杂度由O(n)降为O(logn);

    2. 因为1.7头插法扩容时,头插法会使链表发生反转,多线程环境下会产生环;

      A线程在插入节点B,B线程也在插入,遇到容量不够开始扩容,重新hash,放置元素,采用头插法,后遍历到的B节点放入了头部,这样形成了环,如下图所示:

      在这里插入图片描述

      1.7的扩容调用transfer代码,如下所示:

      void transfer(Entry[] newTable, boolean rehash) {
        int newCapacity = newTable.length;
        for (Entry<K,V> e : table) {
          while(null != e) {
            Entry<K,V> next = e.next;
            if (rehash) {
              e.hash = null == e.key ? 0 : hash(e.key);
            }
            int i = indexFor(e.hash, newCapacity);
            e.next = newTable[i]; //A线程如果执行到这一行挂起,B线程开始进行扩容
            newTable[i] = e;
            e = next;
          }
        }
      }
      
      
    3. 扩容的时候为什么1.8 不用重新hash就可以直接定位原节点在新数据的位置呢?

      这是由于扩容是扩大为原数组大小的2倍,用于计算数组位置的掩码仅仅只是高位多了一个1,怎么理解呢?

      扩容前长度为16,用于计算(n-1) & hash 的二进制n-1为0000 1111,扩容为32后的二进制就高位多了1,为0001 1111。

      因为是& 运算,1和任何数 & 都是它本身,那就分二种情况,如下图:原数据hashcode高位第4位为0和高位为1的情况;

      第四位高位为0,重新hash数值不变,第四位为1,重新hash数值比原来大16(旧数组的容量)

      在这里插入图片描述

    面试官: 那HashMap是线程安全的吗?

    安琪拉: 不是,在多线程环境下,1.7 会产生死循环、数据丢失、数据覆盖的问题,1.8 中会有数据覆盖的问题,以1.8为例,当A线程判断index位置为空后正好挂起,B线程开始往index位置的写入节点数据,这时A线程恢复现场,执行赋值操作,就把A线程的数据给覆盖了;还有++size这个地方也会造成多线程同时扩容等问题。

    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
      Node<K,V>[] tab; Node<K,V> p; int n, i;
      if ((tab = table) == null || (n = tab.length) == 0)
        n = (tab = resize()).length;
      if ((p = tab[i = (n - 1) & hash]) == null)  //多线程执行到这里
        tab[i] = newNode(hash, key, value, null);
      else {
        Node<K,V> e; K k;
        if (p.hash == hash &&
            ((k = p.key) == key || (key != null && key.equals(k))))
          e = p;
        else if (p instanceof TreeNode) // 这里很重要
          e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
        else {
          for (int binCount = 0; ; ++binCount) {
            if ((e = p.next) == null) {
              p.next = newNode(hash, key, value, null);
              if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                treeifyBin(tab, hash);
              break;
            }
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k))))
              break;
            p = e;
          }
        }
        if (e != null) { // existing mapping for key
          V oldValue = e.value;
          if (!onlyIfAbsent || oldValue == null)
            e.value = value;
          afterNodeAccess(e);
          return oldValue;
        }
      }
      ++modCount;
      if (++size > threshold) // 多个线程走到这,可能重复resize()
        resize();
      afterNodeInsertion(evict);
      return null;
    }
    

    面试官: 那你平常怎么解决这个线程不安全的问题?

    安琪拉: Java中有HashTable、Collections.synchronizedMap、以及ConcurrentHashMap可以实现线程安全的Map。

    HashTable是直接在操作方法上加synchronized关键字,锁住整个数组,粒度比较大,Collections.synchronizedMap是使用Collections集合工具的内部类,通过传入Map封装出一个SynchronizedMap对象,内部定义了一个对象锁,方法内通过对象锁实现;ConcurrentHashMap使用分段锁,降低了锁粒度,让并发度大大提高。

    面试官: 那你知道ConcurrentHashMap的分段锁的实现原理吗?

    安琪拉: 【天啦撸! 俄罗斯套娃,一个套一个】ConcurrentHashMap成员变量使用volatile 修饰,免除了指令重排序,同时保证内存可见性,另外使用CAS操作和synchronized结合实现赋值操作,多线程操作只会锁住当前操作索引的节点。

    如下图,线程A锁住A节点所在链表,线程B锁住B节点所在链表,操作互不干涉。

    面试官: 你前面提到链表转红黑树是链表长度达到阈值,这个阈值是多少?

    安琪拉: 阈值是8,红黑树转链表阈值为6

    面试官: 为什么是8,不是16,32甚至是7 ?又为什么红黑树转链表的阈值是6,不是8了呢?

    安琪拉: 【你去问作者啊!天啦撸,biubiubiu 真想213连招】因为作者就这么设计的,哦,不对,因为经过计算,在hash函数设计合理的情况下,发生hash碰撞8次的几率为百万分之6,概率说话。。因为8够用了,至于为什么转回来是6,因为如果hash碰撞次数在8附近徘徊,会一直发生链表和红黑树的互相转化,为了预防这种情况的发生。

    面试官: HashMap内部节点是有序的吗?

    安琪拉: 是无序的,根据hash值随机插入

    面试官: 那有没有有序的Map?

    安琪拉: LinkedHashMap 和 TreeMap

    面试官: 跟我讲讲LinkedHashMap怎么实现有序的?

    安琪拉: LinkedHashMap内部维护了一个单链表,有头尾节点,同时LinkedHashMap节点Entry内部除了继承HashMap的Node属性,还有before 和 after用于标识前置节点和后置节点。可以实现按插入的顺序或访问顺序排序。

    /**
     * The head (eldest) of the doubly linked list.
    */
    transient LinkedHashMap.Entry<K,V> head;
    
    /**
      * The tail (youngest) of the doubly linked list.
    */
    transient LinkedHashMap.Entry<K,V> tail;
    //链接新加入的p节点到链表后端
    private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
      LinkedHashMap.Entry<K,V> last = tail;
      tail = p;
      if (last == null)
        head = p;
      else {
        p.before = last;
        last.after = p;
      }
    }
    //LinkedHashMap的节点类
    static class Entry<K,V> extends HashMap.Node<K,V> {
      Entry<K,V> before, after;
      Entry(int hash, K key, V value, Node<K,V> next) {
        super(hash, key, value, next);
      }
    }
    

    示例代码:

    public static void main(String[] args) {
      Map<String, String> map = new LinkedHashMap<String, String>();
      map.put("1", "安琪拉");
      map.put("2", "的");
      map.put("3", "博客");
    
      for(Map.Entry<String,String> item: map.entrySet()){
        System.out.println(item.getKey() + ":" + item.getValue());
      }
    }
    //console输出
    1:安琪拉
    2:3:博客
    

    面试官: 跟我讲讲TreeMap怎么实现有序的?

    安琪拉:TreeMap是按照Key的自然顺序或者Comprator的顺序进行排序,内部是通过红黑树来实现。所以要么key所属的类实现Comparable接口,或者自定义一个实现了Comparator接口的比较器,传给TreeMap用于key的比较。

    面试官: 前面提到通过CAS 和 synchronized结合实现锁粒度的降低,你能给我讲讲CAS 的实现以及synchronized的实现原理吗?

    安琪拉: 下一期咋们再约时间,OK?

    面试官: 好吧,回去等通知吧!


    回复评论区的几个问题:

    1. @掌心一点微笑: put方法时候,指定位置存在数据->否->存放节点 -> 放入红黑树节点吗?不应该是存放节点->节点数是否大于阈值?这里不懂,求大佬解释
      这个地方图画的确实有问题,感谢指正,已更新。
    2. @海淀好男孩:初始容量不是2的幂会自动改成2的幂那里有些错误吧,50的二进制和下面的无符号右移4位不对啊
      这里是以50做初始值演示的,先进行-1 操作然后开始二进制运算的。

    参考资料

    1. An introduction to optimising a hashing strategy
    2. JDK 源码中 HashMap 的 hash 方法原理是什么?
    3. 淡腾的枫-HashMap中的hash函数

    关注Wx公众号:【安琪拉的博客】 —揭秘Java后端技术,还原技术背后的本质

    《安琪拉与面试官二三事》系列文章 持续更新中
    一个HashMap能跟面试官扯上半个小时
    一个synchronized跟面试官扯了半个小时

    展开全文
  • 面试官,不要再问我三次握手和四次挥手

    万次阅读 多人点赞 2019-10-08 09:55:58
    三次握手和四次挥手是各个公司常见的考点,也具有一定的水平区分度,也被一些面试官作为热身题。很多小伙伴说这个问题刚开始回答的挺好,但是后面越回答越冒冷汗,最后就歇菜了。 见过比较典型的面试场景是这样的: ...

    温馨提示:本篇文章会长期维护及更新,详情见:https://yuanrengu.com/2020/77eef79f.html

    面试相关文章推荐:

    三次握手和四次挥手是各个公司常见的考点,也具有一定的水平区分度,也被一些面试官作为热身题。很多小伙伴说这个问题刚开始回答的挺好,但是后面越回答越冒冷汗,最后就歇菜了。

    见过比较典型的面试场景是这样的:

    面试官:请介绍下三次握手
    求职者:第一次握手就是客户端给服务器端发送一个报文,第二次就是服务器收到报文之后,会应答一个报文给客户端,第三次握手就是客户端收到报文后再给服务器发送一个报文,三次握手就成功了。
    面试官:然后呢?
    求职者:这就是三次握手的过程,很简单的。
    面试官:。。。。。。
    番外篇:一首凉凉送给你

    记住猿人谷一句话:面试时越简单的问题,一般就是隐藏着比较大的坑,一般都是需要将问题扩展的。上面求职者的回答不对吗?当然对,但距离面试官的期望可能还有点距离。

    希望大家能带着如下问题进行阅读,收获会更大。

    1. 请画出三次握手和四次挥手的示意图
    2. 为什么连接的时候是三次握手?
    3. 什么是半连接队列?
    4. ISN(Initial Sequence Number)是固定的吗?
    5. 三次握手过程中可以携带数据吗?
    6. 如果第三次握手丢失了,客户端服务端会如何处理?
    7. SYN攻击是什么?
    8. 挥手为什么需要四次?
    9. 四次挥手释放连接时,等待2MSL的意义?

    三次握手和四次挥手.png

    1. 三次握手

    三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换TCP窗口大小信息。

    刚开始客户端处于 Closed 的状态,服务端处于 Listen 状态。
    进行三次握手:

    • 第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 ISN。此时客户端处于 SYN_SENT 状态。

      首部的同步位SYN=1,初始序号seq=x,SYN=1的报文段不能携带数据,但要消耗掉一个序号。

    • 第二次握手:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN(s)。同时会把客户端的 ISN + 1 作为ACK 的值,表示自己已经收到了客户端的 SYN,此时服务器处于 SYN_RCVD 的状态。

      在确认报文段中SYN=1,ACK=1,确认号ack=x+1,初始序号seq=y。

    • 第三次握手:客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也是一样把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 ESTABLISHED 状态。服务器收到 ACK 报文之后,也处于 ESTABLISHED 状态,此时,双方已建立起了连接。

      确认报文段ACK=1,确认号ack=y+1,序号seq=x+1(初始为seq=x,第二个报文段所以要+1),ACK报文段可以携带数据,不携带数据则不消耗序号。

    发送第一个SYN的一端将执行主动打开(active open),接收这个SYN并发回下一个SYN的另一端执行被动打开(passive open)。

    在socket编程中,客户端执行connect()时,将触发三次握手。

    三次握手.png

    1.1 为什么需要三次握手,两次不行吗?

    弄清这个问题,我们需要先弄明白三次握手的目的是什么,能不能只用两次握手来达到同样的目的。

    • 第一次握手:客户端发送网络包,服务端收到了。
      这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
    • 第二次握手:服务端发包,客户端收到了。
      这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
    • 第三次握手:客户端发包,服务端收到了。
      这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。

    因此,需要三次握手才能确认双方的接收与发送能力是否正常。

    试想如果是用两次握手,则会出现下面这种情况:

    如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要服务端发出确认,就建立新的连接了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端一致等待客户端发送数据,浪费资源。

    1.2 什么是半连接队列?

    服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列

    当然还有一个全连接队列,就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。

    这里在补充一点关于SYN-ACK 重传次数的问题:
    服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传。如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。
    注意,每次重传等待的时间不一定相同,一般会是指数增长,例如间隔时间为 1s,2s,4s,8s…

    1.3 ISN(Initial Sequence Number)是固定的吗?

    当一端为建立连接而发送它的SYN时,它为连接选择一个初始序号。ISN随时间而变化,因此每个连接都将具有不同的ISN。ISN可以看作是一个32比特的计数器,每4ms加1 。这样选择序号的目的在于防止在网络中被延迟的分组在以后又被传送,而导致某个连接的一方对它做错误的解释。

    三次握手的其中一个重要功能是客户端和服务端交换 ISN(Initial Sequence Number),以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果 ISN 是固定的,攻击者很容易猜出后续的确认号,因此 ISN 是动态生成的。

    1.4 三次握手过程中可以携带数据吗?

    其实第三次握手的时候,是可以携带数据的。但是,第一次、第二次握手不可以携带数据

    为什么这样呢?大家可以想一个问题,假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。

    也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。

    1.5 SYN攻击是什么?

    服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪泛攻击。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。

    检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstat 命令来检测 SYN 攻击。

    netstat -n -p TCP | grep SYN_RECV
    

    常见的防御 SYN 攻击的方法有如下几种:

    • 缩短超时(SYN Timeout)时间
    • 增加最大半连接数
    • 过滤网关防护
    • SYN cookies技术

    2. 四次挥手

    建立一个连接需要三次握手,而终止一个连接要经过四次挥手(也有将四次挥手叫做四次握手的)。这由TCP的半关闭(half-close)造成的。所谓的半关闭,其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。

    TCP 连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),客户端或服务端均可主动发起挥手动作。

    刚开始双方都处于ESTABLISHED 状态,假如是客户端先发起关闭请求。四次挥手的过程如下:

    • 第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于 FIN_WAIT1 状态。
      即发出连接释放报文段(FIN=1,序号seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT1(终止等待1)状态,等待服务端的确认。
    • 第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。
      即服务端收到连接释放报文段后即发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),服务端进入CLOSE_WAIT(关闭等待)状态,此时的TCP处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态,等待服务端发出的连接释放报文段。
    • 第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。
      即服务端没有要向客户端发出的数据,服务端发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。
    • 第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。
      即客户端收到服务端的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。

    收到一个FIN只意味着在这一方向上没有数据流动。客户端执行主动关闭并进入TIME_WAIT是正常的,服务端通常执行被动关闭,不会进入TIME_WAIT状态。

    在socket编程中,任何一方执行close()操作即可产生挥手操作。
    image.png

    2.1 挥手为什么需要四次?

    因为当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,“你发的FIN报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次挥手。

    2.2 2MSL等待状态

    TIME_WAIT状态也成为2MSL等待状态。每个具体TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment Lifetime),它是任何报文段被丢弃前在网络内的最长时间。这个时间是有限的,因为TCP报文段以IP数据报在网络内传输,而IP数据报则有限制其生存时间的TTL字段。

    对一个具体实现所给定的MSL值,处理的原则是:当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WAIT状态停留的时间为2倍的MSL。这样可让TCP再次发送最后的ACK以防这个ACK丢失(另一端超时并重发最后的FIN)。

    这种2MSL等待的另一个结果是这个TCP连接在2MSL等待期间,定义这个连接的插口(客户的IP地址和端口号,服务器的IP地址和端口号)不能再被使用。这个连接只能在2MSL结束后才能再被使用。

    2.3 四次挥手释放连接时,等待2MSL的意义?

    MSL是Maximum Segment Lifetime的英文缩写,可译为“最长报文段寿命”,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。

    为了保证客户端发送的最后一个ACK报文段能够到达服务器。因为这个ACK有可能丢失,从而导致处在LAST-ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK,接着客户端再重传一次确认,重新启动时间等待计时器。最后客户端和服务器都能正常的关闭。假设客户端不等待2MSL,而是在发送完ACK之后直接释放关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态。

    两个理由:

    1. 保证客户端发送的最后一个ACK报文段能够到达服务端

      这个ACK报文段有可能丢失,使得处于LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认,服务端超时重传FIN+ACK报文段,而客户端能在2MSL时间内收到这个重传的FIN+ACK报文段,接着客户端重传一次确认,重新启动2MSL计时器,最后客户端和服务端都进入到CLOSED状态,若客户端在TIME-WAIT状态不等待一段时间,而是发送完ACK报文段后立即释放连接,则无法收到服务端重传的FIN+ACK报文段,所以不会再发送一次确认报文段,则服务端无法正常进入到CLOSED状态。

    2. 防止“已失效的连接请求报文段”出现在本连接中

      客户端在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。

    2.4 为什么TIME_WAIT状态需要经过2MSL才能返回到CLOSE状态?

    理论上,四个报文都发送完毕,就可以直接进入CLOSE状态了,但是可能网络是不可靠的,有可能最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文

    3. 总结

    《TCP/IP详解 卷1:协议》有一张TCP状态变迁图,很具有代表性,有助于大家理解三次握手和四次挥手的状态变化。如下图所示,粗的实线箭头表示正常的客户端状态变迁,粗的虚线箭头表示正常的服务器状态变迁。

    TCP状态变迁图.jpg

    以后面试官再问你三次握手和四次挥手,直接把这一篇文章丢给他就可以了,他想问的都在这里。

    参考:《TCP/IP详解 卷1:协议》


    个人公众号:猿人谷
    公众号会有更多关于面试、源码解读、架构设计、程序人生等干货!
    期待您的关注

    在这里插入图片描述

    展开全文
  • 面试必备之反问面试官

    千次阅读 2020-10-31 21:08:17
    求职面试,一般在面试快结束的时候面试官都会客气的问: 你有什么问题想问我的吗? 这时候可不要傻白甜的说:“没有了” 最后一问看似简单,实则非常重要的,问的好后面谈薪资都会更有优势,甚至是你的一根救命...

    求职面试,一般在面试快结束的时候面试官都会客气的问:
    你有什么问题想问我的吗?

    这时候可不要傻白甜的说:“没有了”
    最后一问看似简单,实则非常重要的,问的好后面谈薪资都会更有优势,甚至是你的一根救命稻草。

    下面就针对最后一问如何回答,本人参考网络做了一些补充说明,如有帮助欢迎三连
    读者可以从以下几个方面,结合自身实际情况,挑一两个问题即可,最多三个,不宜再多,尊重面试官的时间,切记!

    准备工作

    • 检查一下哪些问题你感兴趣
    • 检查一下哪些是你可以自己在网上找到答案的
    • 找不到的话就向面试官提问

    绝对不要想把这个列表里的每个问题都问一遍。(尊重面试官的时间,而且你可以通过查找已经发布的答案来显示
    你的主动性)

    请记住事情总是灵活的,组织的结构调整也会经常发生。拥有一个 bug 追踪系统并不会保证高效处理 bug。
    CI/CD (持续集成系统) 也不一定保证交付时间会很短。

    职责

    • On-call (电话值班)的计划或者规定是什么?值班或者遇到问题加班时候有加班费吗?
    • 我的日常工作是什么?
    • 有给我设定的特定目标吗?
    • 团队里面初级和高级工程师的比例是多少?(有计划改变吗)
    • 入职培训 (onboarding) 会是什么样的?
    • 每个开发者有多大的自由来做出决定?
    • 在你看来,这个工作做到什么程度算成功?
    • 你期望我在最初的一个月 / 三个月能够完成什么?
    • 试用期结束的时候,你会怎么样衡量我的绩效?
    • 自己单独的开发活动和按部就班工作的比例大概是怎样的?
    • 一个典型的一天或者一周的工作是怎样安排的?
    • 对我的申请你有什么疑虑么?
    • 在这份工作上,我将会和谁紧密合作?
    • 我的直接上级他们的上级都是什么样的管理风格?(事无巨细还是着眼宏观)
    • 我在这个岗位上应该如何发展?会有哪些机会?
    • 每天预期 / 核心工作时间是多少小时?
    • 我入职的岗位是新增还是接替之前离职的同事?(是否有技术债需要还)?(zh)
    • 入职之后在哪个项目组,项目是新成立还是已有的?(zh)

    技术

    • 公司常用的技术栈是什么?
    • 你们怎么使用源码控制系统?
    • 你们怎么测试代码?
    • 你们怎么追踪 bug?
    • 你们怎样监控项目?
    • 你们怎么集成和部署代码改动?是使用持续集成和持续部署吗 (CI/CD)?
    • 你们的基础设施搭建在版本管理系统里吗?或者是代码化的吗?
    • 从计划到完成一项任务的工作流是什么样的?
    • 你们如何准备故障恢复?
    • 有标准的开发环境吗?是强制的吗?
    • 你们需要花费多长时间来给产品搭建一个本地测试环境?(分钟 / 小时 / 天)
    • 你们需要花费多长时间来响应代码或者依赖中的安全问题?
    • 所有的开发者都可以使用他们电脑的本地管理员权限吗?
    • 介绍一下你们的技术原则或者展望。
    • 你们的代码有开发文档吗?有没有单独的供消费者阅读的文档?
    • 你们有更高层次的文档吗?比如说 ER 图,数据库范式
    • 你们使用静态代码分析吗?
    • 你们如何管理内部和外部的数字资产?
    • 你们如何管理依赖?
    • 公司是否有技术分享交流活动?有的话,多久一次呢?(zh)
    • 你们的数据库是怎么进行版本控制的?(zh)
    • 业务需求有没有文档记录?是如何记录的?(zh)

    团队

    • 工作是怎么组织的?
    • 团队内 / 团队间的交流通常是怎样的?
    • 你们时候使用工具来做项目组织?你的实际体会是什么?
    • 如果遇到不同的意见怎样处理?
    • 谁来设定优先级 / 计划?
    • 如果团队没能赶上预期发布日期怎么办?
    • 每周都会开什么类型的会议?
    • 会有定期的和上级的一对一谈话吗?
    • 产品 / 服务的规划是什么样的?(n 周一发布 / 持续部署 / 多个发布流 / …)
    • 生产环境发生事故了怎么办?是否有不批评人而分析问题的文化?
    • 有没有一些团队正在经历还尚待解决的挑战?
    • 你们如何跟踪进度?
    • 预期和目标是如何设定的?谁来设定?
    • Code Review 如何实施?
    • 给我介绍下团队里一个典型的 sprint
    • 你们如何平衡技术和商业目标?
    • 你们如何共享知识?
    • 团队有多大?
    • 公司技术团队的架构和人员组成?(zh)
    • 团队内开发、产品、运营哪一方是需求的主要提出方?哪一方更强势?(zh)

    同事

    • 开发者倾向于从哪里学习?
    • 你对在这里工作最满意的地方是?
    • 最不满意的呢?
    • 如果可以的话,你想改变哪里?
    • 团队最老的成员在这里多久了?

    公司

    • 公司为什么在招人?(产品发展 / 新产品 / 波动…)
    • 有没有会议 / 旅行预算?使用的规定是什么?
    • 晋升流程是怎样的?要求 / 预期是怎样沟通的?
    • 绩效评估流程是怎样的?
    • 技术和管理两条职业路径是分开的吗?
    • 对于多元化招聘的现状或者观点是什么?
    • 有公司级别的学习资源吗?比如电子书订阅或者在线课程?
    • 有获取证书的预算吗?
    • 公司的成熟度如何?(早期寻找方向 / 有内容的工作 / 维护中 / …)
    • 我可以为开源项目做贡献吗?是否需要审批?
    • 你认为公司未来五年或者十年会发展成什么样子?
    • 公司的大多数员工是如何看待整洁代码的?
    • 你上次注意到有人成长是什么时候?他们在哪方面成长了?
    • 在这里成功的定义是什么?如何衡量成功?
    • 有体育活动或者团建么?
    • 有内部的黑客马拉松活动吗?
    • 公司支持开源项目吗?
    • 有竞业限制或者保密协议需要签吗?
    • 你们认为公司文化中的空白是什么?
    • 能够跟我说一公司处于不良情况,以及如何处理的故事吗?
    • 您在这工作了多久了?您觉得体验如何?(zh)
    • 大家为什么会喜欢这里?(zh)
    • 公司的调薪制度是如何的?(zh)

    社会问题

    • 你们关于多元化招聘什么看法?
    • 你们的公司文化如何?你认为有什么空白么?
    • 这里的工作生活平衡地怎么样?
    • 公司对气候变化有什么态度吗?

    冲突

    • 不同的意见如何处理?
    • 如果被退回了会怎样?(“这个在预计的时间内做不完”)
    • 当团队有压力并且在超负荷工作的时候怎么处理?
    • 如果有人注意到了在流程或者技术等其他方面又改进的地方,怎么办?
    • 当管理层的预期和工程师的绩效之间有差距的时候如何处理?
    • 能给我讲一个公司深处有毒环境以及如何处理的故事吗?

    商业

    • 你们现在盈利吗?
    • 如果没有的话,还需要多久?
    • 公司的资金来源是什么?谁影响或者制定高层计划或方向?
    • 你们如何挣钱?
    • 什么阻止了你们挣更多的钱?
    • 公司未来一年的增长计划怎样?五年呢?
    • 你们认为什么是你们的竞争优势?
    • 你们的竞争优势是什么?
    • 公司未来的商业规划是怎样的?有上市的计划吗?(zh)

    远程工作

    • 远程工作和办公室工作的比例是多少?
    • 公司提供硬件吗?更新计划如何?
    • 使用自己的硬件办公可以吗?现在有政策吗?
    • 额外的附件和家具可以通过公司购买吗?这方面是否有预算?
    • 有共享办公或者上网的预算吗?
    • 多久需要去一次办公室?
    • 公司的会议室是否一直是视频会议就绪的?

    办公室布局

    • 办公室的布局如何?(开放的 / 小隔间 / 独立办公室)
    • 有没有支持 / 市场 / 或者其他需要大量打电话的团队在我的团队旁边办公?

    终极问题

    • 这份工作 / 团队 / 公司最好和最坏的方面是?
    • 你最开始为什么选择了这家公司?
    • 你为什么留在这家公司?

    待遇

    • 如果有奖金计划的话,奖金如何分配?
    • 如果有奖金计划的话,过去的几年里通常会发百分之多少的奖金?
    • 有五险一金或者其他退休养老金等福利吗?如果有的话,公司有配套的商业保险吗?
    • 有什么医疗保险吗?如果有的话何时开始?
    • 更换工作地点,公司付费吗?

    休假

    • 带薪休假时间有多久?
    • 病假和事假是分开的还是一起算?
    • 我可以提前使用假期时间吗?也就是说应休假期是负的?
    • 假期的更新策略是什么样的?也就是说未休的假期能否滚入下一周期
    • 照顾小孩的政策如何?
    • 无薪休假政策是什么样的?
    • 学术性休假政策是怎么样的?

    参考文献:https://github.com/yifeikong/reverse-interview-zh

    展开全文
  • 如何做好一个面试官

    千次阅读 多人点赞 2020-02-20 21:42:56
    找到了我17年写的一篇关于面试官的思考,没有发在csdn上,经过三年的时间,今天看来某些想法不够成熟,所以整理修改后重新发出来。 首先声明一点,我没怎么面试过别人,只是参加过几场面试,经历的面试官只有小20个...

    找到了我17年写的一篇关于面试官的思考,没有发在csdn上,经过三年的时间,今天看来某些想法不够成熟,所以整理修改后重新发出来。

    首先声明一点,我没怎么面试过别人,只是参加过几场面试,经历的面试官只有小20个吧,所以根本没有资格去评判某个面试官是不是合格的面试官。但经过我最近的一些经历,以及朋友做面试官的体会,再加上自己对面试的思考,形成了一个自己对面试官好坏评判的标准。其实也算是最自己将来面试别人或者被面试积累一些经验。提前声明,这里只是我个人的体会,不一定正确,如有意见不合请轻喷。

    其实不可否认,好多面试官的专业技能水平很牛逼,像我司都是一线的主管,或者从业多年的资深老员工。在大公司里的面试官,往往都是受过专业培训,很多也都参加数百场的面试,往往能发现候选人真正的才能和潜力。但像一些小公司,可能就做不到这样了。我猜测很多新手面试官经常会觉得自己面试的人水平都很低?即便是从大公司出来的人,也看不出他们有什么出彩的亮点。然后很多时候面完心里冒出一句『原来xx公司出来的人其实也就是这么个水平啊!』 真的是这样吗?

    有些面试官喜欢出一些稀奇古怪的题目刁难候选人,或者是只局限问自己擅长的问题。我猜想这可能有两种动机。第一,面试官纯粹是想炫技,满足自己的优越感,这种人肯定很少。第二种,面试官其实想不到什么其他的问题问你了,只能拿自己擅长的东西来了,比如算法题,每个面试官都准备了几道自己很熟练的,但让他们互相换一下题可能都做不出来。当然可能有些两种成分都有。 如果让我和这样的面试官成为同事,我可能会拒绝的,不过你不熟悉他们的套路的话可能也过不了他们的面试。

    我这里不是说面试官人不行,我从来不轻易否认掉一个人,除非他没有丝毫的进取心。好多面试官都喜欢从自身的角度出发去问问题,或者是拿自己在工作中遇到的实际问题去考核候选人。这样当然没问题,你最终可以找到可以解决你们目前问题的人,或者是和你自身差不多的人。但如果我是管理层的话,我更希望新来的人能给整个团队带来大的变化,而不是单纯增加劳动力。如果项目紧,时间宝贵,这种情况倒是可以另说。但如果是希望团队能长期健康快速发展,面试过程中更应该站在候选人的角度去审视他的过去,判断他的能力和潜力。

    举几个我认为的反面例子,我曾经在面试过程中遇到过很知识性的问题,比如“你知道mysql有哪几种存储引擎吗?”,“你知道xx框架xx版本有什么新特性吗?”,“你知道xx命令的x参数是什么含义吗?”…………这些知识型的问题都有个共同点:看过的人就知道,没看过的人永远不知道。能答上来这些问题的人要么就是真研究过相关内容,要么就是认真准备过面试,作为面试官你肯定是想要前者。但反之答不上来的人就一定不行吗?我不是在反对用这些知识性的题,我只是反对用能否答对这些题作为评判一个人能力的标准。我的建议是可以用这些题做为引子,初步判断候选人的技能树,然后再深入了解。知识性问题的答案都很简单,学习成本也很低,但背后的原理、思路确实是要花很高的成本去理解的,只有原理性的内容才能评判出候选人真正的水平。

    类似的问题还有“xxx开源软件你了解吗?那xxx呢?” “啊,这你都不了解,你到底行不行啊?” 这个时候我只能反问一句,我为什么要了解这个?计算机领域的知识浩如烟海,谁都不可能对所有东西都有了解,如果你作为面试官只执着在你自己了解的领域,那么能通过你面试的只能是和你很相似的,但并不一定是优秀的。这就是大家所说的眼缘、气场,这就显得非常主观了。

    另外还有人喜欢问一些智力题,大家都喜欢招募一些聪明的人。哈,其实我也是这么想的。面试问智力题的始作俑者可能是微软、google这些国际大厂,网上也流传好多号称是当年google、微软、facebook的面试智力题,具体真假不可知。不过可以确定的是google曾经很喜欢拿智力题面试,注意这里我用了『曾经』两个字。后来google发现智力题对选取优秀的员工并没有任何实质的帮助,所以后来面试过程中就不再问了。具体可参考介绍google企业文化的书《重新定义团队:谷歌如何工作》。

    其实以上被问的问题都是我真实的经历。我发现,层级越高的人问的上面那些问题会更少、更深、更能发掘你的潜力,哈 我就不说为啥了。。说这么多,应该怎么正确提问呢?你没法保证候选人和你有相同的技能点,也不了解他的具体工作内容,你能快速掌握而且你肯定已经掌握的就是他的简历。如果你手里拿到的是一份好简历,你很容易从中看到候选人具体工作是啥,做了啥,拿到了怎么样的成果。由于简历篇幅有限,你看不到的是一些过程信息,这就是你面试问题的来源。

    前两天和同事讨论面试这个问题的时候,了解到有个star法则。以下内容引自百度百科。

    STAR法则,即为 __Situation Task Action Result__的缩写,具体含义是:

    • Situation: 事情是在什么情况下发生
    • Task: 你是如何明确你的任务的
    • Action: 针对这样的情况分析,你采用了什么行动方式
    • Result: 结果怎样,在这样的情况下你学习到了什么

    简而言之,STAR法则,就是一种讲述自己故事的方式,或者说,是一个清晰、条理的作文模板。不管是什么,合理熟练运用此法则,可以轻松的对面试官描述事物的逻辑方式,表现出自己分析阐述问题的清晰性、条理性和逻辑性。

    了解了star法则后,发现这是个非常有用的工具,尤其是在候选人经历和你经历大不相同的情况下。另外我觉得面试也是一个学习的过程,候选人在某方面并不比你差,主要是看你能不能看到这点。其实我觉得真正的面试是你去探索候选人是什么样的人,而不是确认他是不是你认为的人,应该本着客观公众的态度去面,不能夹杂太多主观感情

    YY一把。如果我是一个面试官,我会倾向于基础扎实,更具进取心的人,其实我觉得这是一个很高的要求了。因为基础扎实的人且有进取心的人会在技术成长上有更快的加速度,一定时间后很大几率能超越当前那些技术牛逼的人,当然这也不是绝对的,还得看mentor怎么样,能不能快速成长也是mentor的首要责任。其实如果你选择招这样的一个人进来,可能你得忍受短期没任何产出的后果,哈哈哈。。。

    最后吐槽下国内的面试。这两年来我一直都在坚持在csdn上写博客,所以平时也会稍微关注下热门的博文,发现很多热门网站出发点都是如何应对面试,而不是真正研究技术,热门标题都是《吊打面试官系列xxx》《xx公司面试题》《拿xx公司offer是因为看了这些》…………,网络上也充斥着大量的面试攻略、面试课程,这充分说明大家学习的主要驱动力是面试而不是对技术的热情,这是不是越来越像 应试教育。一个资深程序猿去某些公司能面过p8但面不过p5,这可能真不是什么笑话。

    展开全文
  • 本文的内容都是根据读者投稿的真实面试经历改编而来,首次尝试这种风格的文章,花了几天晚上才总算写完,希望对你有帮助。。已经收录自 Guide 哥开源的 JavaGuide 中。本文主要涵盖下面的内容: 分布式商城系统:...
  • 字节跳动这家公司,应该是所有秋招的公司中,...大部分情况下,面试官都会问一个不怎么难的问题,不过你千万别太开心,因为这道题往往可以拓展出更多有难度的问题,或者一道题看起来很简单,但是给出最优解,确实很...
  • 前言 很多小伙伴面试回来让我复盘自己是否通过面试,...很多学员去面试,面了一个半小时,回来问我会不会成,虽然面试时长并不能确保百分百通过,但一个面试官如果能够面试一个小时,基本上说明面试官对你还是很感兴趣
  • 前端面试官经验总结 | 前端面试小技巧

    千次阅读 多人点赞 2018-11-17 15:51:21
    历时2个多月,前后也面试了上百余人,个人能力并没有多强大,但出于公司需要也就厚着脸皮去面各种前端大佬(啊哈哈终于轮到劳资当家做主了!)。好景不长,从第一份电话面试的小紧张,到线下面试的小期待,再到后来...
  • 个人面经前言JVM篇计网篇Java基础篇多线程篇Spring框架篇MyBatis框架篇MySQL篇Redis篇 前言 不积跬步无以至千里,不积...面试官你好,我叫彭于晏,毕业于XX大学。今天来面试贵公司的Java开发。我从事这个行业已经两年
  • 再仔细分析下原因,面试中问的问题,虽然在职位介绍里已经给出了范围,但针对每个点,面试官的问题是随机想的,甚至同一个面试官在两场相似的面试里,提的问题也未必一样。 也就是说,如果让面试官自由提问,那么...
  • 最近面试了几家公司,都是java题,然后在面试过程中发现一般面试官会问的技术问题都可以在本文档找得到,一般会问servlet的生命周期、Struts和struts2的区别,hibernate、spring的认识、对象、修饰符的作用域、OOP的...
  • 如何做好一名技术面试官

    千次阅读 2020-09-22 18:40:45
    已经有几年开发经验的同学,不管是不是团队中的核心,多多少少都会被 Leader 安排去做面试官,帮团队招贤纳才。就拿我来说吧!这2年也是陆陆续续接到一些面试任务,有一些自己的收获,所以在这里分享给大家。
  • 技术面试官的9大误区

    千次阅读 2018-11-26 09:16:59
    如果你做过技术面试官,就至少犯过下面9大误区中的一个: 压制求职者 拿自己擅长的东西问求职者 寻找全才 根据自己喜好评判求职者 盲目相信求职者 自己说得太多,让求职者说得太少 不了解公司、团队、产品和岗位...
  • 前端面试(面试官篇)

    千次阅读 2018-06-10 14:36:46
    最近一直在接公司的面试,果然还是需要站在不同的位置才能看到更多的问题,总结一下面试者常见的一些错误还有一些建议。 紧张 这个是面试最常见的问题,不过说实话个人觉得影响不是特别大,属于加分项,只要你能...
  • 阿里巴巴面试官手册

    千次阅读 2020-11-06 11:28:25
    无意间在网上看到的,偏后端。 链接: https://pan.baidu.com/s/1FcBqE5fwCR_EavuhJWr_ww 密码: n525
  • 文章目录作为面试官被放鸽子的50个理由,论如何放面试官的鸽子不能帯饭的不去面试公司福利少不去太远的不去-路上时间浪费太多周围没商业街买外卖的不去面试公司门牌不好找不去太近的不去(怕家里人查岗)每次开会听...
  • 作为技术面试官,我在面试时考虑什么?

    万次阅读 多人点赞 2019-10-21 09:43:17
    作为一个面试官,我们也需要这样,我也会经常总结和反思自己的面试技巧,现分享如下,希望求职者能有反向的思维,下次面试成绩能更好。 机会是留给有针对性准备的人的 我觉得是这是最重要的一点,很多人可能觉得同伴...
  • 面试结束后,被面试官在朋友圈吐槽了(心塞)

    千次阅读 多人点赞 2021-04-02 21:43:34
    ​前阵子一个后辈小学弟向我诉苦,说自己在参加某大厂开发的时候被面试官怼得哑口无言,场面让他一度十分尴尬。 面试场景再现 面试官:说说你简历上这个项目的架构? 小学弟:组件化!(一口咬定) 面试官内心OS:...
  • 作为一个面试官如何准备一场面试

    千次阅读 2018-05-19 23:24:53
    本人工作年限不多,作为面试官次数也不多,以下只是自己的思考和记录,不喜轻喷,经验老道的面试官以及非技术类的面试官就不要看了,浪费您的时间。 从一次经历说起 不知道第一次作为面试官去面试别人的时候,你...
  • 8年经验面试官详解 Java 面试秘诀

    万次阅读 多人点赞 2019-11-19 17:31:49
    本人目前在一家知名外企担任架构师,而且最近八年来,在多家外企和互联网公司担任Java技术面试官,前后累计面试了有两三百位候选人。在本文里,就将结合本人的面试经验,针对Java初学者、Java初级开发和Java开发,给...
  • 面试官的角度分享一些后端校招经验

    万次阅读 多人点赞 2018-07-01 16:24:46
    本来我也就是刚开始学着当面试官,不该妄谈经验,但是因为最近换了一份工作,未来几年都不会再有国内互联网公司的校招经验了,所以不如趁热分享一下,省得知识过期。本文是个人体会,而且经验不多,读者姑妄听之就好...
  • java面试官如何面试别人

    千次阅读 2018-02-20 15:11:26
    java面试官如何面试别人(一)  java面试官的“面试心得”  在公司当技术面试官几年间,从应届生到工作十几年的应聘者都遇到过。先表达一下我自己对面试的观点:  1.笔试、面试去评价一个人肯定是不够准确的,...
  • 我在阿里做技术面试官的一些经验

    千次阅读 2019-05-28 21:35:06
    一般阿里腾讯这样的大公司,校招面试的流程是一轮统一笔试+三轮技术面试+一轮HR面试,如果对候选人的水平有争议,技术面试有可能会增加一轮,以2019年春招(实习生招聘)为例: 统一的笔试。 技术初面,一般这一轮...
  • 今天,西安鸥鹏小编就和大家聊聊面试java工程师,面试官一般问什么问题? 如果可以的话,“建议以一个和面试官交流的心态去面试“。而且普通面试大部分问答都是有一些套路的。 面试的过程中,肯定会有答不上来的...
  • 面试官最容易提出的20个问题

    千次阅读 2018-08-22 14:27:57
    一、 请谈谈你自己。 考点提示:了解应聘者的自我评价能力、表达能力和基本思维能力。...也可以说说自己的座右铭,加深面试对你的印象。 再一次,个人介绍要与简历一致,不可出现矛盾之处,否则你人被直接淘汰。...
  • 面试当中,有时候会问到你在项目中用过多线程么? 对于普通的应届生或者工作时间不长的初级开发 ???—— crud仔流下了没有技术的眼泪。 博主这里整理了项目中用到了多线程的一个简单的实例,希望能对你有所...
  • 面了三次了,总算虐了一次面试官
  • Java面试Offer直通车

    万人学习 2019-12-18 15:19:52
    1、68讲视频课,500道大厂Java常见面试题+100个Java面试技巧与答题公式+10万字核心知识解析+授课老师1对1面试指导+无限次回放 2、这门课程基于胡书敏老师8年Java面试经验,调研近百家互联网公司及面试官的问题打造...
  • 面试官到底是何方神圣?相信对于很多校招、实习萌新一直都不清楚屏幕另一端的面试官到底是怎么样一个人?是打分机器?技术大牛?还是……本文便是博主从各个面试官那里挖来的面试猛料,带你直击面试官内心世界,让你...
  • 如何做一名合格的面试官

    千次阅读 2018-07-20 23:40:13
    面试官需要具备专业素质:感受能力、心理能力、情绪能力、认知能力、发展意愿、岗位分析、量化评估、测评工具、学习能力、管理经验 心理测试的冰山模型,就是说在面试过程了解到候选人内在的东西只是很少一部分,这...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 287,459
精华内容 114,983
关键字:

面试官