广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >面试官问到ThreadLocal的问题怎么回答
  • 600
分享到

面试官问到ThreadLocal的问题怎么回答

2024-04-02 19:04:59 600人浏览 泡泡鱼
摘要

本篇内容主要讲解“面试官问到ThreadLocal的问题怎么回答”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“面试官问到ThreadLocal的问题怎么回答”吧

本篇内容主要讲解“面试官问到ThreadLocal的问题怎么回答”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“面试官问到ThreadLocal的问题怎么回答”吧!

开场

杭州某商务楼里,正发生着一起求职者和面试官的battle。

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

安琪拉:面试官你好,我是草丛三婊,最强中单(妲己不服),草地摩托车车手,第21套广播体操推广者,火的传人安琪拉,这是我的简历,请过目。

面试官:看你简历上写熟悉多线程编程,熟悉到什么程度?

安琪拉:精通。

对。。。,你没看错,问就是“精通”,把666打在评论区。

面试官:

[心想] 莫不是个憨批,上来就说自己精通,谁把精通挂嘴上,莫不是个愣头青嘞!

面试官:那我们开始吧。用过Threadlocal 吧?

安琪拉:用过。

面试官:那你跟我讲讲 ThreadLocal 在你们项目中的用法吧。

安琪拉:我们项目属于保密项目,无可奉告,你还是换个问题吧!

面试官:那说个不保密的项目,或者你直接告诉我Threadlocal 的实现原理吧。

正题

安琪拉:show time。。。

安琪拉:举个栗子,我们支付宝每秒钟同时会有很多用户请求,那每个请求都带有用户信息,我们知道通常都是一个线程处理一个用户请求,我们可以把用户信息丢到Threadlocal里面,让每个线程处理自己的用户信息,线程之间互不干扰。

面试官:等等,问你个私人问题,为什么从支付宝跑出来面试,受不了PUA了吗?

安琪拉:PUA我,不存在的,能PUA我的人还没出生呢!公司食堂吃腻了,想换换口味。

面试官:那你来给我讲讲Threadlocal是干什么的?

安琪拉:Threadlocal 主要用来做线程变量的隔离,这么说可能不是很直观。

还是说前面提到的例子,我们程序在处理用户请求的时候,通常后端服务器是有一个线程池,来一个请求就交给一个线程来处理,那为了防止多线程并发处理请求的时候发生串数据,比如AB线程分别处理安琪拉和妲己的请求,A线程本来处理安琪拉的请求,结果访问到妲己的数据上了,把妲己支付宝的钱转走了。

所以就可以把安琪拉的数据跟A线程绑定,线程处理完之后解除绑定。

面试官问到ThreadLocal的问题怎么回答

面试官:那把你刚才说的场景用伪代码实现一下,来笔给你!

安琪拉:ok

//存放用户信息的ThreadLocal private static final ThreadLocal<UserInfo> userInfoThreadLocal = new ThreadLocal<>();  public Response handleRequest(UserInfo userInfo) {   Response response = new Response();   try {     // 1.用户信息set到线程局部变量中     userInfoThreadLocal.set(userInfo);     doHandle();   } finally {     // 3.使用完移除掉     userInfoThreadLocal.remove();   }    return response; }      //业务逻辑处理 private void doHandle () {   // 2.实际用的时候取出来   UserInfo userInfo = userInfoThreadLocal.get();   //查询用户资产   queryUserAsset(userInfo); }

1.2.3 步骤很清楚了。

面试官:那你跟我说说Threadlocal 怎么实现线程变量的隔离的?

安琪拉:Oh, 这么快进入正题,我先给你画个图,如下:

面试官问到ThreadLocal的问题怎么回答

面试官:图我看了,那你对着前面你写的代码讲一下对应图中流程。

安琪拉:没问题

  • 首先我们通过ThreadLocal

    userInfoThreadLocal = new ThreadLocal()  初始化了一个Threadlocal 对象,就是上图中说的Threadlocal 引用,这个引用指向堆中的ThreadLocal 对象;
  • 然后我们调用userInfoThreadLocal.set(userInfo); 这里做了什么事呢?

我们把源代码拿出来,看一看就清晰了。

我们知道 Thread 类有个 ThreadLocalMap 成员变量,这个Map key是Threadlocal  对象,value是你要存放的线程局部变量。

# Threadlocal类 Threadlocal.class  public void set(T value) {   //获取当前线程Thread,就是上图画的Thread 引用   Thread t = Thread.currentThread();    //Thread类有个成员变量ThreadlocalMap,拿到这个Map   ThreadLocalMap map = getMap(t);   if (map != null)     //this指的就是Threadlocal对象     map.set(this, value);   else     createMap(t, value); }  ThreadLocalMap getMap(Thread t) {   //获取线程的ThreadLocalMap   return t.threadLocals; }  void createMap(Thread t, T firstValue) {   //初始化   t.threadLocals = new ThreadLocalMap(this, firstValue); }
# Thread类 Thread.class public class Thread implements Runnable {     //每个线程都有自己的ThreadLocalMap 成员变量     ThreadLocal.ThreadLocalMap threadLocals = null; }

这里是在当前线程对象的ThreadlocalMap中put了一个元素(Entry),key是Threadlocal对象,value是userInfo。

理解两件事就都清楚了:

ThreadLocalMap 类的定义在 Threadlocal中。

  • 第一,Thread 对象是Java语言中线程运行的载体,每个线程都有对应的Thread 对象,存放线程相关的一些信息,

  • 第二,Thread类中有个成员变量ThreadlocalMap,你就把他当成普通的Map,key存放的是Threadlocal对象,value是你要跟线程绑定的值(线程隔离的变量),比如这里是用户信息对象(UserInfo)。

面试官:你刚才说Thread 类有个 ThreadlocalMap 属性的成员变量,但是ThreadlocalMap 的定义却在Threadlocal  中,为什么这么做?

安琪拉:我们看下ThreadlocalMap的说明

class ThreadLocalMap * ThreadLocalMap is a customized hash map suitable only for * maintaining thread local values. No operations are exported * outside of the ThreadLocal class. The class is package private to * allow declaration of fields in class Thread.  To help deal with * very large and long-lived usages, the hash table entries use * WeakReferences for keys. However, since reference queues are not * used, stale entries are guaranteed to be removed only when * the table starts running out of space.

大概意思是ThreadLocalMap 就是为维护线程本地变量而设计的,只做这一件事情。

这个也是为什么 ThreadLocalMap 是Thread的成员变量,但是却是Threadlocal  的内部类(非public,只有包访问权限,Thread和Threadlocal都在java.lang  包下),就是让使用者知道ThreadLocalMap就只做保存线程局部变量这一件事的。

面试官:既然是线程局部变量,那为什么不用线程对象(Thread对象)作为key,这样不是更清晰,直接用线程作为key获取线程变量?

安琪拉:这样设计会有个问题,比如:  我已经把用户信息存在线程变量里了,这个时候需要新增加一个线程变量,比方说新增用户地理位置信息,我们ThreadlocalMap  的key用的是线程,再存一个地理位置信息,key都是同一个线程(key一样),不就把原来的用户信息覆盖了嘛。Map.put(key,value)  操作熟悉吧,所以网上有些文章说ThreadlocalMap使用线程作为key是瞎扯的。

面试官:那新增地理位置信息应该怎么做?

安琪拉:新创建一个Threadlocal对象就好了,因为ThreadLocalMap的key是Threadlocal 对象,比如新增地理位置,我就再  Threadlocal < Geo> geo = new Threadlocal(),  存放地理位置信息,这样线程的ThreadlocalMap里面会有二个元素,一个是用户信息,一个是地理位置。

面试官:ThreadlocalMap 是什么数据结构实现的?

安琪拉:跟HashMap 一样,也是数组实现的。

代码如下:

class ThreadLocalMap {  //初始容量  private static final int INITIAL_CAPACITY = 16;  //存放元素的数组  private Entry[] table;  //元素个数  private int size = 0; }

table  就是存储线程局部变量的数组,数组元素是Entry类,Entry由key和value组成,key是Threadlocal对象,value是存放的对应线程变量

我们前面举得例子,数组存储结构如下图:

面试官问到ThreadLocal的问题怎么回答

面试官:ThreadlocalMap 发生hash冲突怎么办?跟HashMap 有什么区别?

安琪拉:【心想】第一次碰到有问ThreadlocalMap哈希冲突的,这个面试越来越有意思了。

说道:有区别的,对待哈希冲突,HashMap采用的链表 + 红黑树的形式,如下图,链表长度过长(>8) 就会转成红黑树:

面试官问到ThreadLocal的问题怎么回答

ThreadlocalMap既没有链表,也没有红黑树,采用的是链地址法,  链地址法就是如果发生冲突,ThreadlocalMap直接往后找相邻的下一个节点,如果相邻节点为空,直接存进去,如果不为空,继续往后找,直到找到空的,把元素放进去,或者元素个数超过数组长度阈值,进行扩容。

如下图:还是以之前的例子讲解,ThreadlocalMap 数组长度是4,现在存地理位置的时候发生hash冲突(位置1已经有数据),那就把往后找,发现2  这个位置为空,就直接存放在2这个位置。

面试官问到ThreadLocal的问题怎么回答

源代码(如果阅读起来困难,可以看完后文回过头来阅读):

private void set(ThreadLocal<?> key, Object value) {   Entry[] tab = table;   int len = tab.length;   // hashcode & 操作其实就是 %数组长度取余数,例如:数组长度是4,hashCode % (4-1) 就找到要存放元素的数组下标   int i = key.threadLocalHashCode & (len-1);    //找到数组的空槽(=null),一般ThreadlocalMap存放元素不会很多   for (Entry e = tab[i];        e != null; //找到数组的空槽(=null)        e = tab[i = nextIndex(i, len)]) {     ThreadLocal<?> k = e.get();      //如果key值一样,算是更新操作,直接替换     if (k == key) {       e.value = value;       return;     }   //key为空,做替换清理动作,这个后面聊WeakReference的时候讲     if (k == null) {       replaceStaleEntry(key, value, i);       return;     }   }  //新new一个Entry   tab[i] = new Entry(key, value);   //数组元素个数+1   int sz = ++size;   //如果没清理掉元素或者存放元素个数超过数组阈值,进行扩容   if (!cleanSomeSlots(i, sz) && sz >= threshold)     rehash(); }  //顺序遍历 +1 到了数组尾部,又回到数组头部(0这个位置) private static int nextIndex(int i, int len) {   return ((i + 1 < len) ? i + 1 : 0); }  // get()方法,根据ThreadLocal key获取线程变量 private Entry getEntry(ThreadLocal<?> key) {   //计算hash值 & 操作其实就是 %数组长度取余数,例如:数组长度是4,hashCode % (4-1) 就找到要查询的数组地址   int i = key.threadLocalHashCode & (table.length - 1);   Entry e = table[i];   //快速判断 如果这个位置有值,key相等表示找到了,直接返回   if (e != null && e.get() == key)     return e;   else     return getEntryAfterMiss(key, i, e); //miss之后顺序往后找(链地址法,这个后面再介绍) }

面试官:我看你最前面图中画的ThreadlocalMap 中key是  WeakReference类型,能讲讲Java中有几种类似的引用,什么区别吗?

安琪拉:可以

  • 强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它,当内存空间不足时,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

  • 如果一个对象只具有软引用,则内存空间充足时,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。

  • 弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描内存区域时,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

  • 虚引用顾名思义,就是形同虚设。与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

妥妥的八股文啊!尴尬(─.─|||。

面试官:那你能讲讲为什么ThreadlocalMap 中key 设计成 WeakReference(弱引用)类型吗?

安琪拉:可以的,为了尽最大努力避免内存泄漏。

面试官:能详细讲讲吗?为什么是尽最大努力,你前面也讲被WeakReference 引用的对象会直接被GC(内存回收器)  回收,为什么不是直接避免了内存泄漏呢?

安琪拉:我们还是看下下面这张图:

面试官问到ThreadLocal的问题怎么回答

private static final ThreadLocal<UserInfo> userInfoThreadLocal = new ThreadLocal<>(); userInfoThreadLocal.set(userInfo);

这里的引用关系是userInfoThreadLocal  引用了ThreadLocal对象,这是个强引用,ThreadLocal对象同时也被ThreadlocalMap的key引用,这是个WeakReference引用,我们前面说GC要回收ThreadLocal对象的前提是它只被WeakReference引用,没有任何强引用。

为了方便大家理解弱引用,我写了段Demo程序

public static void main(String[] args) {   Object angela = new Object();   //弱引用   WeakReference<Object> weakReference = new WeakReference<>(angela);   //angela和弱引用指向同一个对象   System.out.println(angela);//java.lang.Object@4550017c   System.out.println(weakReference.get());//java.lang.Object@4550017c    //将强引用angela置为null,这个对象就只剩下弱引用了,内存够用,弱引用也会被回收   angela = null;    System.gc();//内存够用不会自动gc,手动唤醒gc   System.out.println(angela);//null   System.out.println(weakReference.get());//null }

可以看到一旦一个对象只被弱引用引用,GC的时候就会回收这个对象。

所以只要ThreadLocal对象如果还被  userInfoThreadLocal(强引用) 引用着,GC是不会回收被WeakReference引用的对象的。

面试官:那既然ThreadLocal对象有强引用,回收不掉,干嘛还要设计成WeakReference类型呢?

安琪拉:ThreadLocal的设计者考虑到线程往往生命周期很长,比如经常会用到线程池,线程一直存活着,根据JVM 根搜索算法,一直存在 Thread  -> ThreadLocalMap -> Entry(元素)这样一条引用链路,  如下图,如果key不设计成WeakReference类型,是强引用的话,就一直不会被GC回收,key就一直不会是null,不为null  Entry元素就不会被清理(ThreadLocalMap是根据key是否为null来判断是否清理Entry)

面试官问到ThreadLocal的问题怎么回答

所以ThreadLocal的设计者认为只要ThreadLocal  所在的作用域结束了工作被清理了,GC回收的时候就会把key引用对象回收,key置为null,ThreadLocal会尽力保证Entry清理掉来最大可能避免内存泄漏。

来看下代码:

//元素类 static class Entry extends WeakReference<ThreadLocal<?>> {      Object value; //key是从父类继承的,所以这里只有value    Entry(ThreadLocal<?> k, Object v) {     super(k);     value = v;   } }  //WeakReference 继承了Reference,key是继承了范型的referent public abstract class Reference<T> {   //这个就是被继承的key   private T referent;    Reference(T referent) {     this(referent, null);   } }

Entry 继承了WeakReference类,Entry 中的 key 是WeakReference类型的,在Java 中当对象只被  WeakReference 引用,没有其他对象引用时,被WeakReference 引用的对象发生GC 时会直接被回收掉。

面试官:那如果Threadlocal 对象一直有强引用,那怎么办?岂不是有内存泄漏风险。

安琪拉:最佳实践是用完手动调用remove函数。

我们看下源码

class Threadlocal {   public void remove() {       //这个是拿到线程的ThreadLocalMap       ThreadLocalMap m = getMap(Thread.currentThread());       if (m != null)         m.remove(this); //this就是ThreadLocal对象,移除,方法在下面   } }  class ThreadlocalMap {   private void remove(ThreadLocal<?> key) {     Entry[] tab = table;     int len = tab.length;     //计算位置     int i = key.threadLocalHashCode & (len-1);     for (Entry e = tab[i];          e != null;          e = tab[i = nextIndex(i, len)]) {       //清理       if (e.get() == key) {         e.clear();         expungeStaleEntry(i); //清理空槽         return;       }    }  } }  //这个方法就是做元素清理 private int expungeStaleEntry(int staleSlot) {   Entry[] tab = table;   int len = tab.length;    //把staleSlot的value置为空,然后数组元素置为空   tab[staleSlot].value = null;   tab[staleSlot] = null;   size--; //元素个数-1    // Rehash until we encounter null   Entry e;   int i;   for (i = nextIndex(staleSlot, len);        (e = tab[i]) != null;        i = nextIndex(i, len)) {     ThreadLocal<?> k = e.get();     //k 为null代表引用对象被GC回收掉了     if (k == null) {       e.value = null;       tab[i] = null;       size--;     } else {       //因为元素个数减少了,就把后面的元素重新hash       int h = k.threadLocalHashCode & (len - 1);       //hash地址不相等,就代表这个元素之前发生过hash冲突(本来应该放在这没放在这),       //现在因为有元素被移除了,很有可能原来冲突的位置空出来了,重试一次       if (h != i) {         tab[i] = null;          //继续采用链地址法存放元素         while (tab[h] != null)           h = nextIndex(h, len);         tab[h] = e;       }     }   }   return i; }

面试官:你有没有用Threadlocal的工程实际经历,给我讲讲。

安琪拉:有啊!

之前我跟你们一面面试官聊过,我是怎么把支付宝后台负责的系统四十几个核心rpc接口性能大幅度提升的,下面这个就是其中一个接口切流之后的效果,其中就用到了Threadlocal。图片

面试官问到ThreadLocal的问题怎么回答

面试官:嗯,说说。

安琪拉:我刚才说有四十多个接口要做技改优化,那风险是很高的,我需要保证接口切换后业务不受影响,也叫等效切换。

流程是这样的:

  • 把这四十多个接口按照业务含义定义了接口常量名称,比如接口名alipay.quickquick.follow.angela;

  • 按照接口的流量从低到高开始切流,提前配置中心配置好每个接口的切流比例和用户白名单;

  • 切流也有讲究,先按照userId白名单切,再按照userId尾号切百分比,完全没问题再完整切;

  • 在顶层抽象模版方法的入口通过ThreadLocal  Set 接口名,把接口名塞进去;

然后我在切流的地方通过ThreadLocal  获取接口名,用于接口切流判断切流;

面试官:最后一个问题,如果我有很多变量都要塞到ThreadlocalMap中,那岂不是要申明很多个Threadlocal  对象?有没有好的解决办法。

安琪拉:我们的最佳实践是搞个再封装一下,把ThreadLocalMap 的value  弄成Map就好了,这样只要一个Threadlocal 对象就好了。

面试官:能详细讲讲吗?

安琪拉:讲不动了,太累了。

面试官:讲讲。

安琪拉:真不想讲了。

面试官:那今天先到这,您出了这个门右拐,回去等通知吧!

到此,相信大家对“面试官问到ThreadLocal的问题怎么回答”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: 面试官问到ThreadLocal的问题怎么回答

本文链接: https://www.lsjlt.com/news/68465.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 面试官问到ThreadLocal的问题怎么回答
    本篇内容主要讲解“面试官问到ThreadLocal的问题怎么回答”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“面试官问到ThreadLocal的问题怎么回答”吧...
    99+
    2022-10-19
  • 面试官常问的 ASP 打包问题,你能回答吗?
    ASP 是一种广泛使用的服务器端脚本语言,它可以用于动态生成网页内容、处理表单数据等。在开发 ASP 网站时,我们通常需要将多个 ASP 文件打包成一个单独的组件,以便于在不同的页面中重复使用。这时,就会遇到一些打包相关的问题。在本文中,...
    99+
    2023-08-07
    打包 面试 unix
  • 面试官问到go http日志,你该如何回答?
    在使用Go语言开发Web应用时,日志记录是非常重要的一部分。通过记录日志,我们可以了解应用程序的运行状态,排查问题,优化性能等。而HTTP日志则是Web应用最基本的日志记录方式之一,记录了Web服务器接收和响应HTTP请求的详细信息。当面...
    99+
    2023-08-04
    http 面试 日志
  • 面试JAVA时,问到spring该怎么回答
    目录Spring面试十连问 1、谈谈对IOC的理解?2、多个AOP的顺序怎么定义3、springBean是线程安全的吗?4、Spring中的bean生命周期?5、Sprin...
    99+
    2022-11-12
  • 面试官问到ASP中的数据类型,你该如何回答?
    ASP是一种非常流行的Web开发语言,它的数据类型是ASP开发中一个非常重要的方面。在面试中,面试官可能会问到ASP中的数据类型,因此,本篇文章将为大家介绍ASP中的数据类型,并为大家提供相应的演示代码。 ASP中的数据类型 ASP支持多种...
    99+
    2023-07-28
    数据类型 面试 http
  • 面试官问你Java并发编程,如何回答?
    Java并发编程是Java程序员必须掌握的重要技能之一。在面试中,面试官可能会问到一些与Java并发编程相关的问题,例如线程安全、同步机制等。那么,如果面试官问你Java并发编程,你应该如何回答呢?本文将为大家提供一些指导性的建议。 首先,...
    99+
    2023-11-14
    响应 面试 并发
  • 面试官问到了PHP和大数据打包,你会如何回答?
    PHP和大数据打包是一个较为复杂的话题,在面试中被问到也是很正常的。如果你是一名PHP开发者,那么对于这个问题的回答应该是非常重要的。本文将探讨PHP和大数据打包的相关知识,并提供一些代码示例来帮助您更好地回答这个问题。 一、什么是PHP和...
    99+
    2023-07-07
    大数据 打包 面试
  • 面试官问你Vue2的响应式原理该如何回答?
    目录前言响应式对象响应式开始的地方Observer实现响应式的defineReactivedepwatcher依赖收集派发更新总结前言 可能很多小伙伴之前都了解过 Vue2实现响应式...
    99+
    2022-12-14
    Vue2响应式原理 Vue 响应式原理 Vue 响应式
  • 面试官问到 Spring,你是否能够自信地回答?Python 可以让你做到!
    在现代软件开发的世界中,Spring框架是一个广泛应用的Java框架,它提供了大量的库和工具,使得开发者可以更加高效地构建Web应用程序。在面试中,面试官经常会问到Spring框架相关的问题。如果你不熟悉Spring框架,你可能会失去机会。...
    99+
    2023-11-10
    响应 面试 spring
  • 面试官会问到哪些关于 Spring 同步的问题?
    Spring 是目前最流行的开源框架之一,它提供了丰富的功能和特性,可帮助开发人员更轻松地构建高质量的应用程序。在面试中,面试官经常会问关于 Spring 同步的问题,因此本文将介绍一些常见的问题及其答案。 什么是 Spring 同步? ...
    99+
    2023-09-22
    面试 同步 spring
  • 面试问Vue2与Vue3的区别怎么回答
    这篇文章主要讲解了“面试问Vue2与Vue3的区别怎么回答”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“面试问Vue2与Vue3的区别怎么回答”吧!Vue 内部根据功能可以被分为三个大的模块...
    99+
    2023-07-05
  • 2023 Android面试官 常问的问题以及答案(附最新的Android面试大厂必考174题 )
    前言 已经2023了 但是计算机的寒冬还没有过去 ,但是我们程序员的热情不会被磨灭(有钱就干 越多越有劲)。在这个金三银四的季节 许多公司也发布了更多的招聘岗位 面试机会多了 那我们跟要把握住。以下分享一些面试题给大家,希望能帮到大家找一份...
    99+
    2023-08-16
    android 面试 java
  • 面试官最常问的Java接口打包问题,你是否有答案?
    在Java开发领域中,接口是一个非常重要的概念。接口可以被视为一种契约,规定了类需要实现哪些方法。在实际开发中,我们经常会使用接口来实现多态,提高代码的可扩展性和可维护性。然而,在打包Java应用程序时,接口也经常会成为面试官考察的一个热...
    99+
    2023-11-04
    接口 打包 面试
  • ASP 面试:如何准备?面试官会问什么问题?
    ASP 面试:如何准备?面试官会问什么问题? ASP(Active Server Pages)是一种基于服务器端的动态网页技术,它使用一系列的脚本语言和组件来生成动态的网页。在ASP的职业领域,每年都有大量的工作机会。如果你是一名ASP开发...
    99+
    2023-10-27
    重定向 打包 面试
  • 面试官会问到哪些关于缓存和 Linux 的问题?
    在计算机系统中,缓存是一种常见的技术,它被广泛应用于各种场景中,例如数据库、网络通信、图形处理等。Linux 是一种常见的操作系统,因为它的高度定制性和开放性,也被广泛应用于各种场景中。因此,面试官经常会问到关于缓存和 Linux 的问题...
    99+
    2023-06-13
    面试 缓存 linux
  • 【面试】Java面试频繁问到的题最新整理(附答案)
    文章目录 一、Java基础部分面试题1.1. Java面向对象的三个特征1.2. Java中基本的数据类型有哪些 以及他们的占用字节1.3. int和Integer的区别1.4. String、StringBuilder、Strin...
    99+
    2023-08-30
    java 面试
  • Java开发岗位面试被问到嵌套类该怎么回答
    这篇文章将为大家详细讲解有关Java开发岗位面试被问到嵌套类该怎么回答,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。嵌套类分类静态内部类(静态嵌套类/静态成员类/静态类)内部类(非静态嵌套类)内部成员类本...
    99+
    2023-06-20
  • 面试官问你如何处理高并发,你会如何回答?
    在当今的互联网时代,高并发是每个软件工程师必须面对的挑战之一。无论是电商网站、社交网络还是金融系统,都需要能够处理大量的请求。因此,当面试官问你如何处理高并发时,你需要清楚地了解高并发的概念和解决方案。 什么是高并发? 在计算机科学中,高...
    99+
    2023-10-19
    load 并发 面试
  • ASP索引、JavaScript面试官会问到的问题?——如何在面试中应对ASP索引和JavaScript问题?
    在Web开发中,ASP索引和JavaScript是两个非常重要的概念。在面试中,面试官经常会询问关于这两个概念的问题。因此,了解这些问题并且知道如何应对它们,对于成功通过面试至关重要。 一、ASP索引 ASP索引是一种用于加快Web应用程...
    99+
    2023-07-21
    索引 面试 javascript
  • Node.js的面试问答题有哪些
    本篇内容主要讲解“Node.js的面试问答题有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Node.js的面试问答题有哪些”吧!问题什么是错误优先的回调函数?如何避免回调地狱?什么是Pro...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作