首页 > 其他分享 >js面试(防抖)

js面试(防抖)

时间:2024-03-17 14:22:18浏览次数:22  
标签:防抖 const debounceClickEvent debounce timer js 面试 fun

一、什么是防抖

防抖(Debounce)是一种用于减少特定事件触发频率的技术。在编程中,它通常用于确保函数或方法不会在很短的时间内被频繁调用,这有助于优化性能并避免不必要的计算或操作。

防抖的实现原理是,在事件被触发后,一个定时器会被设置。如果在定时器完成之前,相同的事件再次被触发,那么原来的定时器会被取消,并重新设置一个新的定时器。这样,只有在最后一次事件触发后的一定时间内没有再次触发,定时器才会执行其回调函数。

应用场景:

  1. 登录与发送短信:在连续点击登录按钮或发送短信时,防抖技术能够确保不会因用户点击过快而发送多次请求。
  2. 表单验证:在用户输入表单信息时,防抖技术可以确保不会因为频繁触发验证逻辑而导致性能降低。
  3. 实时搜索与保存:在文本编辑器或搜索框中实现实时搜索和保存功能时,防抖技术可以确保在用户停止输入一段时间后执行搜索或保存操作,避免用户连续输入导致的频繁触发。
  4. 窗口大小调整:在调整浏览器窗口大小时,resize事件可能会被频繁触发,防抖技术可以确保只执行一次操作,避免不必要的计算。
  5. 鼠标移动事件:实现一些需要用户停止移动鼠标后再执行的功能时,如拖拽功能,防抖技术可以减少事件的处理频率。

二、前置准备

  1. 准备一个html文件和一个debounce.js文件,debounce.js文件用来编写防抖函数

    <!-- test.html -->
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>防抖</title>
    </head>
    
    <body>
      <div class="debounce">触发防抖事件</div>
      <script src="./debounce.js"></script>
    </body>
    
    </html>
    
    // debounce.js
    const debounce = () => {};
    
  2. div绑定点击事件

    <!-- test.html -->
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>防抖</title>
    </head>
    
    <body>
      <div class="debounce">触发防抖事件</div>
      <script src="./debounce.js"></script>
    
      <script>
        const clickEvent = (e) => { console.log("点击事件触发", e, this) }
        document.querySelector(".debounce").addEventListener("click", clickEvent)
      </script>
    </body>
    
    </html>
    

    image-20240317023413975

    进行点击测试,发现目前this指向的是Window,因为箭头函数没有this,通过作用域链往外找,就找到Window了。

    将箭头函数改为普通函数,就能将this指向改为div。但是这里暂时先不改,后面遇到问题再说。

  3. 将clickEvent方法传递给debounce进行处理

    <!-- test.html -->
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>防抖</title>
    </head>
    
    <body>
      <div class="debounce">触发防抖事件</div>
      <script src="./debounce.js"></script>
    
      <script>
        const clickEvent = (e) => { console.log("点击事件触发", e, this) }
        const debounceClickEvent = debounce(clickEvent, 2000)
        document.querySelector(".debounce").addEventListener("click", debounceClickEvent)
      </script>
    </body>
    
    </html>
    

    现在再进行点击测试,发现控制台什么也没有输出。因为目前debounce方法还没写方法体,没有返回值,所以debounceClickEvent是undefined,所以什么也不会触发。

    下面我们就一步步写防抖函数

三、基础防抖实现

  1. 思考防抖函数需要接收什么参数,又需要返回什么

    • 接收参数:一个点击事件的处理方法、延迟执行的时间
    • 返回值:做了防抖处理的方法

    根据以上条件,可以先写出如下代码

    // debounce.js
    const debounce = (fun, time) => {
      return fun;
    };
    

    上面代码接收了一个方法,又直接将该方法返回了。等于什么也没做,至少也得做个延时处理吧

    // debounce.js
    const debounce = (fun, time) => {
      return () => {
        setTimeout(fun, time);
      };
    };
    

    上面的方法虽然做了延时处理,但还是造成了处理方法被多次调用

    那我们应该怎样让前面的处理方法被取消执行呢?既然处理方法都放进了定时器,那我们就把定时器清除就行了。

    // debounce.js
    const debounce = (fun, time) => {
      let timer;
      return () => {
        timer && clearTimeout(timer);
        timer = setTimeout(fun, time);
      };
    };
    

    image-20240317025923041

    这下多次点击,就只触发了最后一次处理方法了。但是通过打印可以发现,this指向的是Window,事件源也是undefined。

    我们如何将this指向变成调用方法的div,又如何获取事件源呢

  2. 改变this指向

    我们先分析一下,为什么this指向的是window?

    const clickEvent = (e) => { console.log("点击事件触发", e, this) }
    const debounceClickEvent = debounce(clickEvent, 2000)
    
    // debounce.js
    const debounce = (fun, time) => {
      let timer;
      return () => {
        timer && clearTimeout(timer);
        timer = setTimeout(fun, time);
      };
    };
    

    上面的写法,其实等价于下面的写法

    // debounce.js
    const debounce = (fun, time) => {
      let timer;
      return () => {
        timer && clearTimeout(timer);
        timer = setTimeout((e) => { console.log("点击事件触发", e, this) }, time);
      };
    };
    
    

    那再来分析一下this指向,箭头函数没有this,它通过作用域链往外找,就找到Window了

    那我们在哪里能获取到正确的this指向呢?来看看哪个方法是被div调用的,是不是return 后面那个方法

    既然这个方法是div调用的,那我们应该可以拿到this,但是这里也是箭头函数,没有this。所以我们先将它修改为普通函数

    // debounce.js
    const debounce = (fun, time) => {
      let timer;
      return function () {
        console.log(this);
        timer && clearTimeout(timer);
        timer = setTimeout(fun, time);
      };
    };
    

    我们打印一下this,看看是不是div

    image-20240317031539559

    这里的this指向确实是指向div的,那我们就可以通过call、apply、bind等方法修改fun的this指向了

    // debounce.js
    const debounce = (fun, time) => {
      let timer;
      return function () {
        timer && clearTimeout(timer);
        timer = setTimeout(fun.bind(this), time);
      };
    };
    

    再来看看能打印出正确的this吗

    image-20240317031756029

    结果this还是指向的Window,别忘了fun是一个箭头函数,它没有this,又怎么能去修改呢。

    所以我们需要将这个fun(clickEvent)也改为普通函数

    const clickEvent = function (e) {
        console.log("点击事件触发", e, this)
    }
    const debounceClickEvent = debounce(clickEvent, 2000)
    document.querySelector(".debounce").addEventListener("click", debounceClickEvent)
    

    这下再来看看this指向正确了吗

    image-20240317032129969

  3. 获取事件源

    为什么这里的e打印出来是undefined?

    我们来看看div调用的是哪个方法,是不是debounce函数中return的那个方法。那这个方法应该是可以接收到事件源的。

    再看看fun,我们使用bind的时候,根本就没有给它设置参数,所以e打印出来是undefined

    // debounce.js
    const debounce = (fun, time) => {
      let timer;
      return function (e) {
        console.log(e);
        timer && clearTimeout(timer);
        timer = setTimeout(fun.bind(this), time);
      };
    };
    

    image-20240317032714448

    从返回的方法里面确实可以拿到事件源,那我们将这个 e 传递给bind 的第二个参数就好了

    // debounce.js
    const debounce = (fun, time) => {
      let timer;
      return function (e) {
        timer && clearTimeout(timer);
        timer = setTimeout(fun.bind(this, e), time);
      };
    };
    

    image-20240317032857839

四、接收多个参数

  1. 上面已经实现了最基本的防抖函数,但还有一些地方需要优化

    • 如果传递了多个参数又如何接收
    • 每次触发新的点击事件,会清空定时器。那最后一次执行完了,又怎么清空呢?这个对象始终没有释放掉
  2. 接收多个参数

    // debounce.js
    const debounce = (fun, time) => {
      let timer;
      return function (...args) {
        timer && clearTimeout(timer);
        timer = setTimeout(fun.bind(this, ...args), time);
      };
    };
    
  3. 最后一次执行完毕,将timer释放掉

    // debounce.js
    const debounce = (fun, time) => {
      let timer;
      return function (...args) {
        timer && clearTimeout(timer);
        timer = setTimeout(() => {
          fun.apply(this, args);
          timer = null;
        }, time);
      };
    };
    

五、取消处理方法

  1. 怎么将最后一次的处理方法给取消呢?

    想办法拿到定时器timer,然后使用clearTimeout(timer)就可以了

  2. 准备一个div,作为取消按钮

    <!-- test.html -->
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>防抖</title>
    </head>
    
    <body>
      <div class="debounce">触发防抖事件</div>
      <div class="cancle">取消</div>
      <script src="./debounce.js"></script>
    
      <script>
        const clickEvent = function (e) {
          console.log("点击事件触发", e, this)
        }
    
        const debounceClickEvent = debounce(clickEvent, 2000)
        const cancle = () => { }
    
        document.querySelector(".debounce").addEventListener("click", debounceClickEvent)
        document.querySelector(".cancle").addEventListener("click", cancle)
      </script>
    </body>
    
    </html>
    
  3. 在返回的函数身上再绑定一个方法用来清除定时器

    // debounce.js
    const debounce = (fun, time) => {
      let timer;
      const debounceEvent = function debounceEvent(...args) {
        timer && clearTimeout(timer);
        timer = setTimeout(() => {
          fun.apply(this, args);
          timer = null;
        }, time);
      };
    
      debounceEvent.cancle = () => {
        timer && clearTimeout(timer);
        timer = null;
      };
    
      return debounceEvent;
    };
    

    image-20240317035101187

  4. 给取消按钮绑定方法

    <!-- test.html -->
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>防抖</title>
    </head>
    
    <body>
      <div class="debounce">触发防抖事件</div>
      <div class="cancle">取消</div>
      <script src="./debounce.js"></script>
    
      <script>
        const clickEvent = function (e) {
          console.log("点击事件触发", e, this)
        }
    
        const debounceClickEvent = debounce(clickEvent, 2000)
        const cancle = () => { debounceClickEvent.cancle() }
    
        document.querySelector(".debounce").addEventListener("click", debounceClickEvent)
        document.querySelector(".cancle").addEventListener("click", cancle)
      </script>
    </body>
    
    </html>
    

六、立即执行

  1. 如何让第一次处理函数立即执行,后面再做防抖处理

    可以通过一个变量来控制,第一次立即执行,然后将该变量取反,后面执行的时候,使用原来的逻辑

  2. 为debounce函数添加参数,用来标志是否第一次立即执行

    // debounce.js
    const debounce = (fun, time, immediately = false) => {
      let timer;
      const debounceEvent = function debounceEvent(...args) {
        timer && clearTimeout(timer);
        timer = setTimeout(() => {
          fun.apply(this, args);
          timer = null;
        }, time);
      };
    
      debounceEvent.cancle = () => {
        console.log("清除定时器");
        timer && clearTimeout(timer);
        timer = null;
      };
    
      return debounceEvent;
    };
    
  3. 修改第一次执行的逻辑

    // debounce.js
    const debounce = (fun, time, immediately = false) => {
      let timer;
      // 是否已经立即执行
      let running = false;
      const debounceEvent = function debounceEvent(...args) {
        timer && clearTimeout(timer);
        // 开启了立即执行并且还没有立即执行,则说明这是第一次,直接立即执行
        if (immediately && !running) {
          // 第一次已经立即执行了,后面再次触发就不能再立即执行了
          running = true;
          fun.apply(this, args);
        } else {
          timer = setTimeout(() => {
            fun.apply(this, args);
            timer = null;
            // 最后一次防抖方法完成后,下一次还可以立即执行
            running = false;
          }, time);
        }
      };
    
      debounceEvent.cancle = () => {
        console.log("清除定时器");
        timer && clearTimeout(timer);
        timer = null;
        // 取消最后一次防抖方法后,恢复下一次的立即执行
        running = false;
      };
    
      return debounceEvent;
    };
    

    上面的代码实现了第一次触发时立即执行,然后每次触发做防抖处理。最后一次防抖方法处理完成(或被取消)后,在下一次触发时,又可以立即执行。

    但是这仍然存在一个小问题,如果第一次立即执行后不触发频繁的点击操作,而是等第一次完成之后,再点击,这时还会立即执行吗?很明显不能。目前第一次立即执行后,想要恢复立即执行,就必须经过频繁触发事件,让最后一次防抖方法被处理了,才能再次恢复立即执行。

    在下面的代码中,我们使用了一个定时器。在第一次立即执行完成后,开启一个定时器,在一段时间后恢复立即执行,使再次点击时,可以立即执行。但是,如果在这一段时间内,频繁的触发了点击事件,那就清除定时器,在最后一次防抖处理方法完成后,再恢复立即执行。

    // debounce.js
    const debounce = (fun, time, immediately = false) => {
      let timer;
      // 是否已经立即执行
      let running = false;
      // 恢复立即执行的定时器
      let timerRunning;
      const debounceEvent = function debounceEvent(...args) {
        timer && clearTimeout(timer);
        // 开启了立即执行并且还没有立即执行,则说明这是第一次,直接立即执行
        if (immediately && !running) {
          // 第一次已经立即执行了,后面再次触发就不能再立即执行了
          running = true;
          fun.apply(this, args);
          // 第一次立即执行已经完成了,我们在一段时间后恢复立即执行
          timerRunning = setTimeout(() => {
            running = false;
          }, time);
        } else {
          // 如果频繁触发了事件,则不恢复立即执行,而是等最后一次处理方法完成再恢复立即执行
          timerRunning && clearTimeout(timerRunning);
          timer = setTimeout(() => {
            fun.apply(this, args);
            timer = null;
            // 最后一次防抖方法完成后,下一次还可以立即执行
            running = false;
          }, time);
        }
      };
    
      debounceEvent.cancle = () => {
        console.log("清除定时器");
        timer && clearTimeout(timer);
        timer = null;
        // 取消最后一次防抖方法后,恢复下一次的立即执行
        running = false;
      };
    
      return debounceEvent;
    };
    

七、获取防抖函数的返回值

  1. 先来手动调用一下点击处理函数

    <!-- test.html -->
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>防抖</title>
    </head>
    
    <body>
      <div class="debounce">触发防抖事件</div>
      <div class="cancle">取消</div>
      <script src="./debounce.js"></script>
    
      <script>
        const clickEvent = function (e) {
          console.log("点击事件触发", e, this)
        }
    
        const debounceClickEvent = debounce(clickEvent, 2000, true)
        const cancle = () => { debounceClickEvent.cancle() }
    
        document.querySelector(".debounce").addEventListener("click", debounceClickEvent)
        document.querySelector(".cancle").addEventListener("click", cancle)
    
        // 手动调用点击处理函数
        debounceClickEvent()
        debounceClickEvent()
        debounceClickEvent()
        debounceClickEvent()
      </script>
    </body>
    
    </html>
    

    我们在上面手动调用了4次点击事件的处理函数,查看控制台也发现了打印了两次,一次是立即执行,一次是防抖处理的最后一次执行

    image-20240317134911297

  2. 给点击处理函数设置返回值

    下面,我们给clickEvent方法设置一个返回值。

    <!-- test.html -->
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>防抖</title>
    </head>
    
    <body>
      <div class="debounce">触发防抖事件</div>
      <div class="cancle">取消</div>
      <script src="./debounce.js"></script>
    
      <script>
        const clickEvent = function (e) {
          console.log("点击事件触发", e, this)
          const result = "请求结果数据"
          return result
        }
    
        const debounceClickEvent = debounce(clickEvent, 2000, true)
        const cancle = () => { debounceClickEvent.cancle() }
    
        document.querySelector(".debounce").addEventListener("click", debounceClickEvent)
        document.querySelector(".cancle").addEventListener("click", cancle)
    
        // 手动调用点击处理函数
        console.log(debounceClickEvent())
        console.log(debounceClickEvent())
        console.log(debounceClickEvent())
        console.log(debounceClickEvent())
      </script>
    </body>
    
    </html>
    

    然后需要在debounceEvent方法中将结果返回

    // debounce.js
    const debounce = (fun, time, immediately = false) => {
      let timer;
      // 是否已经立即执行
      let running = false;
      // 恢复立即执行的定时器
      let timerRunning;
      const debounceEvent = function debounceEvent(...args) {
        // 返回结果
        let result;
        timer && clearTimeout(timer);
        // 开启了立即执行并且还没有立即执行,则说明这是第一次,直接立即执行
        if (immediately && !running) {
          // 第一次已经立即执行了,后面再次触发就不能再立即执行了
          running = true;
          // 获取方法执行的返回结果
          result = fun.apply(this, args);
          // 第一次立即执行已经完成了,我们在一段时间后恢复立即执行
          timerRunning = setTimeout(() => {
            running = false;
          }, time);
        } else {
          // 如果频繁触发了事件,则不恢复立即执行,而是等最后一次处理方法完成再恢复立即执行
          timerRunning && clearTimeout(timerRunning);
          timer = setTimeout(() => {
            // 获取方法执行的返回结果
            result = fun.apply(this, args);
            timer = null;
            // 最后一次防抖方法完成后,下一次还可以立即执行
            running = false;
          }, time);
        }
        // 返回结果
        return result;
      };
    
      debounceEvent.cancle = () => {
        console.log("清除定时器");
        timer && clearTimeout(timer);
        timer = null;
        // 取消最后一次防抖方法后,恢复下一次的立即执行
        running = false;
      };
    
      return debounceEvent;
    };
    

    查看控制输出

    image-20240317140343576

    第一次是立即执行的,所以可以拿到返回值。但最后一次是异步执行的,所以拿不到。可以使用Promise来处理

    // debounce.js
    const debounce = (fun, time, immediately = false) => {
      let timer;
      // 是否已经立即执行
      let running = false;
      // 恢复立即执行的定时器
      let timerRunning;
      const debounceEvent = function debounceEvent(...args) {
        return new Promise((resolve, reject) => {
          // 返回结果
          let result;
          timer && clearTimeout(timer);
          // 开启了立即执行并且还没有立即执行,则说明这是第一次,直接立即执行
          if (immediately && !running) {
            // 第一次已经立即执行了,后面再次触发就不能再立即执行了
            running = true;
            result = fun.apply(this, args);
            resolve(result);
            // 第一次立即执行已经完成了,我们在一段时间后恢复立即执行
            timerRunning = setTimeout(() => {
              running = false;
            }, time);
          } else {
            // 如果频繁触发了事件,则不恢复立即执行,而是等最后一次处理方法完成再恢复立即执行
            timerRunning && clearTimeout(timerRunning);
            timer = setTimeout(() => {
              result = fun.apply(this, args);
              resolve(result);
              timer = null;
              // 最后一次防抖方法完成后,下一次还可以立即执行
              running = false;
            }, time);
          }
        });
      };
    
      debounceEvent.cancle = () => {
        console.log("清除定时器");
        timer && clearTimeout(timer);
        timer = null;
        // 取消最后一次防抖方法后,恢复下一次的立即执行
        running = false;
      };
    
      return debounceEvent;
    };
    
    <!-- test.html -->
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>防抖</title>
    </head>
    
    <body>
      <div class="debounce">触发防抖事件</div>
      <div class="cancle">取消</div>
      <script src="./debounce.js"></script>
    
      <script>
        const clickEvent = function (e) {
          console.log("点击事件触发", e, this)
          const result = "请求结果数据"
          return result
        }
    
        const debounceClickEvent = debounce(clickEvent, 2000, true)
        const cancle = () => { debounceClickEvent.cancle() }
    
        document.querySelector(".debounce").addEventListener("click", debounceClickEvent)
        document.querySelector(".cancle").addEventListener("click", cancle)
    
        // 手动调用点击处理函数
        // console.log(debounceClickEvent())
        // console.log(debounceClickEvent())
        // console.log(debounceClickEvent())
        // console.log(debounceClickEvent())
        debounceClickEvent().then(res => console.log(res))
        debounceClickEvent().then(res => console.log(res))
        debounceClickEvent().then(res => console.log(res))
        debounceClickEvent().then(res => console.log(res))
      </script>
    </body>
    
    </html>
    

    查看控制台输出,这下就没问题了

    image-20240317140944835

八、完整代码

<!-- test.html -->
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>防抖</title>
</head>

<body>
  <div class="debounce">触发防抖事件</div>
  <div class="cancle">取消</div>
  <script src="./debounce.js"></script>

  <script>
    const clickEvent = function (e) {
      console.log("点击事件触发", e, this)
      const result = "请求结果数据"
      return result
    }

    const debounceClickEvent = debounce(clickEvent, 2000, true)
    const cancle = () => { debounceClickEvent.cancle() }

    document.querySelector(".debounce").addEventListener("click", debounceClickEvent)
    document.querySelector(".cancle").addEventListener("click", cancle)

    // 手动调用点击处理函数
    // console.log(debounceClickEvent())
    // console.log(debounceClickEvent())
    // console.log(debounceClickEvent())
    // console.log(debounceClickEvent())
    debounceClickEvent().then(res => console.log(res))
    debounceClickEvent().then(res => console.log(res))
    debounceClickEvent().then(res => console.log(res))
    debounceClickEvent().then(res => console.log(res))
  </script>
</body>

</html>
// debounce.js
const debounce = (fun, time, immediately = false) => {
  let timer;
  // 是否已经立即执行
  let running = false;
  // 恢复立即执行的定时器
  let timerRunning;
  const debounceEvent = function debounceEvent(...args) {
    return new Promise((resolve, reject) => {
      // 返回结果
      let result;
      timer && clearTimeout(timer);
      // 开启了立即执行并且还没有立即执行,则说明这是第一次,直接立即执行
      if (immediately && !running) {
        // 第一次已经立即执行了,后面再次触发就不能再立即执行了
        running = true;
        result = fun.apply(this, args);
        resolve(result);
        // 第一次立即执行已经完成了,我们在一段时间后恢复立即执行
        timerRunning = setTimeout(() => {
          running = false;
        }, time);
      } else {
        // 如果频繁触发了事件,则不恢复立即执行,而是等最后一次处理方法完成再恢复立即执行
        timerRunning && clearTimeout(timerRunning);
        timer = setTimeout(() => {
          result = fun.apply(this, args);
          resolve(result);
          timer = null;
          // 最后一次防抖方法完成后,下一次还可以立即执行
          running = false;
        }, time);
      }
    });
  };

  debounceEvent.cancle = () => {
    console.log("清除定时器");
    timer && clearTimeout(timer);
    timer = null;
    // 取消最后一次防抖方法后,恢复下一次的立即执行
    running = false;
  };

  return debounceEvent;
};

标签:防抖,const,debounceClickEvent,debounce,timer,js,面试,fun
From: https://www.cnblogs.com/finish/p/18078538

相关文章

  • 全栈的自我修养 ———— js如何处理并发的大量请求??
    假如一个事件段内传过来一百多个请求,我们该处理大量并发请求呢过程实现验证假如现在允许的并发量为4,有一百个请求!假如现在允许的并发量为1,有一百个请求!源码过程实现定义一个方法,这个方法会放入你在这个时间段接收到的请求,这里100位例!consturlArr=[]......
  • Java面试题:假设你正在开发一个Java后端服务,该服务需要处理高并发的用户请求,并且对内存
    Java内存优化、线程安全与并发框架:综合面试题解析Java作为一种广泛使用的编程语言,其内存管理、多线程和并发处理是开发者必须掌握的核心技能。为了全面评估候选人在这些领域的知识水平和实际应用能力,我们设计了一道综合性的面试题。本文将对这道题目进行深入分析,从核心知识......
  • Java面试题:详解单例模式与内存泄漏?内存模型与volatile关键字的实操?并发工具包与并发框
    Java核心技术:设计模式、内存管理与并发编程深度解析在Java技术领域,设计模式、内存管理和并发编程是构建高效、稳定系统的关键。本文将通过三道综合性面试题,深入探讨这些核心知识点,帮助读者理解其背后的原理,并在实际编程中避免常见错误。面试题一:单例模式与内存泄漏问题核......
  • 【面试精讲】String是如何实现的?String源码分析
    【面试精讲】String是如何实现的?String源码分析目录一、String实现机制二、String不可变性(使用final修饰)三、String和 StringBuilder、StringBuffer 的区别四、==和equals的区别五、String创建对象与JVM辨析六、String源码解析1、compareTo()2、 equals() 总结......
  • 微信小程序uniapp+vue+nodejs宝宝成长记录系统的设计与实现
    本文先通过对相关系统的调研,提出开发基于微信小程序的宝宝成长记录系统的意义,然后使用当前主流的技术进行开发,满足基于微信小程序的宝宝成长记录系统的技术要求,分析系统需要实现的功能并进行设计。梳理业务流程,并根据功能设计数据库,最后通过编码实现,介绍实现的关键算法逻辑。在......
  • C++ 简单使用Json库与muduo网络库
    C++简单使用Json库与muduo网络库C++使用Json库测试代码均在Ubuntu20上运行首先下载json.hpp的代码链接然后和你的测试代码放在同一目录下面导入方式#include"json.hpp"usingjson=nlohmann::json;json序列化代码测试1voidtest1(){jsonjs;js["id"]={1......
  • 智能酒店管理系统(JSP+java+springmvc+mysql+MyBatis)
    本项目包含程序+源码+数据库+LW+调试部署环境,文末可获取一份本项目的java源码和数据库参考。项目文件图 项目介绍随着科技的进步和旅游业的繁荣,酒店行业正面临着前所未有的机遇与挑战。为了提高服务质量、运营效率以及顾客满意度,智能酒店管理系统应运而生。这种系统利用......
  • 灾情信息管理系统(JSP+java+springmvc+mysql+MyBatis)
    本项目包含程序+源码+数据库+LW+调试部署环境,文末可获取一份本项目的java源码和数据库参考。项目文件图 项目介绍随着自然灾害频发,及时有效的灾情信息管理对于灾害应对和救援工作至关重要。一个专业的灾情信息管理系统能够帮助政府和救援组织快速收集、处理和分析灾区数......
  • 今日头条Linux 运维工程师面试真题
    今日头条Linux运维工程师面试真题首先我们来看下今日头条Linux运维工程师招聘岗位要求:【岗位定义】系统运维工程师【岗位薪资】10K-24K【基本要求】北京/经验3-5年/本科及以上/全职【职位描述】1、负责业务系统日常运行维护,线上故障紧急处理;2、监控平台的搭建......
  • Linux 运维工程师面试真题-2-Linux 命令及文件操作
    Linux运维工程师面试真题-2-Linux命令及文件操作1.在/tmp/目录下创建test.txt文件,内容为:Hello,World!,用一个命令写出来。2.给test.txt文件除所有者之外增加执行权限,最终以数字写出文件的权限。3.用vi命令编辑test.txt,如何跳转到末行,首行,行首、行末,如何在光标行下一......