2022-10-02大厂面经00
  1. 自我介绍,介绍一个项目(说了一个最新的),项目讨论(思路和实现方案),Java socket用在哪个部分(OT),OT实现过程(举例说A和B互相发送数据),socket属于TCP还是UDP,TCP和UDP的区别,Java写socket为什么比python快,小程序怎么采集信息(类似蓝牙时刻保持开启)
  2. 本硕专业,为什么选前端(经验,兴趣),计算机方面有什么优势(统筹,问题建模)
  3. 说一个之前的课设,怎么统筹的,负责什么部分,后端接口怎么实现,登陆注册怎么实现,cookie设置24h过期怎么实现
  4. 系统学习前端的时间,怎么学习前端(学习过程),react的虚拟DOM解释,有什么作用,文本框左侧添加文字过程,虚拟DOM发生了什么
  5. 介绍一下本科学的课程,哪门印象最深,介绍一下。
  6. js写深拷贝,js快排
  7. js数组原型方法
  8. CSS position,absolute一定相对父元素偏移吗,浏览器兼容,DOCTYPE作用
  9. 平常写html还是xml(html),小程序为什么是wxml(...)
  10. 反问(没有问的,已经累了)
2022-09-30JavaScript00

数组扁平化是指将一个多维数组变为一维数组

[1, [2, 3, [4, 5]]]------ > [1, 2, 3, 4, 5];

递归法:

function flatten(arr) {
  let res = [];
  arr.map((item) => {
    if (Array.isArray(item)) {
      res = res.concat(flatten(item));
    } else {
      res.push(item);
    }
  });
  return res;
}
2022-09-29JavaScript00

Service Worker

Service Worker 是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。使用 Service Worker 的话,传输协议必须为 HTTPS。因为 Service Worker 中涉及到请求拦截,所以必须使用 HTTPS 协议来保障安全。

Service Worker 实现缓存功能一般分为三个步骤:首先需要先注册 Service Worker,然后监听到 install 事件以后就可以缓存需要的文件,那么在下次用户访问的时候就可以通过拦截请求的方式查询是否存在缓存,存在缓存的话就可以直接读取缓存文件,否则就去请求数据。以下是这个步骤的实现:

// index.js
if (navigator.serviceWorker) {
  navigator.serviceWorker
    .register("sw.js")
    .then(function (registration) {
      console.log("service worker 注册成功");
    })
    .catch(function (err) {
      console.log("servcie worker 注册失败");
    });
}
// sw.js
// 监听 `install` 事件,回调中缓存所需文件
self.addEventListener("install", (e) => {
  e.waitUntil(
    caches.open("my-cache").then(function (cache) {
      return cache.addAll(["./index.html", "./index.js"]);
    })
  );
});

// 拦截所有请求事件
// 如果缓存中已经有请求的数据就直接用缓存,否则去请求数据
self.addEventListener("fetch", (e) => {
  e.respondWith(
    caches.match(e.request).then(function (response) {
      if (response) {
        return response;
      }
      console.log("fetch source");
    })
  );
});
2022-09-29JavaScript00

ES6

var、let 及 const 区别?

  • 全局申明的 var 变量会挂载在 window 上,而 let 和 const 不会
  • var 声明变量存在变量提升,let 和 const 不会
  • let、const 的作用范围是块级作用域,而 var 的作用范围是函数作用域
  • 同一作用域下 let 和 const 不能声明同名变量,而 var 可以
  • 同一作用域下在 let 和 const 声明前使用会存在暂时性死区
  • const
    • 一旦声明必须赋值,不能使用 null 占位
    • 声明后不能再修改
    • 如果声明的是复合类型数据,可以修改其属性

Proxy

Proxy 是 ES6 中新增的功能,它可以用来自定义对象中的操作。 Vue3.0 中将会通过 Proxy 来替换原本的 Object.defineProperty 来实现数据响应式。

let p = new Proxy(target, handler);

target 代表需要添加代理的对象,handler 用来自定义对象中的操作,比如可以用来自定义 set 或者 get 函数。

let onWatch = (obj, setBind, getLogger) => {
  let handler = {
    set(target, property, value, receiver) {
      setBind(value, property);
      return Reflect.set(target, property, value);
    },
    get(target, property, receiver) {
      getLogger(target, property);
      return Reflect.get(target, property, receiver);
    },
  };
  return new Proxy(obj, handler);
};

let obj = { a: 1 };
let p = onWatch(
  obj,
  (v, property) => {
    console.log(`监听到属性${property}改变为${v}`);
  },
  (target, property) => {
    console.log(`'${property}' = ${target[property]}`);
  }
);
p.a = 2; // 控制台输出:监听到属性a改变
p.a; // 'a' = 2
2022-09-29React00

自定义 hooks

因为可以自定义 Hooks, 我们可以非常方便的复用状态逻辑。

// 定时器DEMO
function useCount(defaultCount) {
  const [count, setCount] = useState(defaultCount);
  const timer = useRef();

  useEffect(() => {
    timer.current = setInterval(() => {
      setCount((count) => count + 1);
    }, 1000);
  }, []);

  useEffect(() => {
    if (count >= 10) {
      clearInterval(timer.current);
    }
  });
  return [count];
}

function App() {
  const [count] = useCount(0);
  return (
    <>
      <h1>count: {count}</h1>
    </>
  );
}