Compartilhamento de tecnologia

Perguntas sobre o código da entrevista inicial

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Este artigo resume as questões de codificação encontradas durante o processo de entrevista.

1. Promoção variável

2. Métodos relacionados a array

Observe que o verdadeiro valor retornado é para retenção, não para filtragem, então não se esqueça disso. Não é nada, só que vou esquecer se não escrever pessoalmente por meio ano. . .

arr.filter((item, índice, atual) => {return arr.indexOf(item) == índice});.Pode remover peso

A essência do filtro é criar um novo array e, se a função de retorno de chamada retornar verdadeiro, ele será retido. A linha de código acima significa que apenas a primeira vez é colocada dentro.

Desduplicação de ponteiro duplo:

Use ponteiros duplos para reordenar o array. Se forem iguais, o ponteiro rápido se moverá uma posição para a direita. Se não forem iguais, o ponteiro lento se moverá uma posição para a direita. o ponteiro rápido à direita para comparação com a próxima vez:

  1. function doublePointer(nums) {
  2. if(nums.length < 2) {
  3. return nums;
  4. }
  5. let slow = 0;
  6. let fast = 1;
  7. let result = [nums[0]];
  8. while(fast < nums.length) {
  9. if (result[slow] == nums[fast]) {
  10. fast++;
  11. } else {
  12. slow++;
  13. result[slow] = nums[fast];
  14. fast++;
  15. }
  16. }
  17. return result;
  18. }
  19. const arr = [1,1,2,2,4,4];
  20. console.log(doublePointer(arr));

Entrada [1,1,2,2,4,4] e saída [1,2,4].

Se a matriz for um objeto:

const arr2 = [{id:1,tempo: 2},{id:1,tempo: 4},{id:2,tempo: 2},{id:2,tempo: 4},{id:3,tempo: 5},

{id:3,tempo: 2}];

Agora precisamos remover duplicatas com base no ID. Se os IDs forem iguais, apenas o objeto com maior tempo será retido.

[{"id":1,"hora":4},{"id":2,"hora":4},{"id":3,"hora":5}]

  1. function doublePointerByorder(nums) {
  2. if(nums.length < 2) {
  3. return nums;
  4. }
  5. let slow = 0;
  6. let fast = 1;
  7. let result = [nums[0]];
  8. while(fast < nums.length) {
  9. if (result[slow].id == nums[fast].id) {
  10. if(result[slow].time < nums[fast].time) {
  11. result[slow] = nums[fast];
  12. }
  13. fast++;
  14. } else {
  15. slow++;
  16. result[slow] = nums[fast];
  17. fast++;
  18. }
  19. }
  20. return result;
  21. }

console.log(doublePointerByorder(arr2));

Claro, você pode usar um objeto vazio para lembrá-lo. A cada vez, compare o tempo correspondente ao ID no objeto e escolha se deseja substituí-lo. Após percorrer, use um loop for in para converter o objeto em um array. Porém, ponteiros duplos são muito eficientes. Se a quantidade de dados for grande, seria mais apropriado usar ponteiros duplos.

3. Referência relacionada

A atribuição de sinal de igual de variáveis ​​de tipo de referência não afetará uma à outra.

No entanto, será afetado pelo uso de ab, que é considerado uma cópia superficial, conforme mostrado abaixo.

  1. person1 = {name: 3};
  2. members = person1;
  3. members.name = 4;   // person1.name=4

Vamos dar uma olhada em um caso clássico relacionado a citações. Também foi uma pergunta que não anotei quando a encontrei pela primeira vez durante a entrevista. Converta o array em uma estrutura de árvore:

  1. function arrayToTree(items) {
  2. const tree = {};
  3. const map = {};
  4. items.forEach((item, index) => {
  5. const { id, parentId } = item;
  6. if (!map[id]) map[id] = { children: [] };
  7. const node = { ...item, children: map[id].children};
  8. map[id] = node;
  9. if (parentId) {
  10. if (!map[parentId]) {
  11. map[parentId] = { children: [] };
  12. } map[parentId].children.push(node);
  13. } else {
  14. tree[id] = node;
  15. }
  16. });
  17. console.log(map);
  18. }
  19. // 示例数组
  20. const items = [
  21. { id: 1, parentId: null, value: "A" },
  22. { id: 2, parentId: 1, value: "B" },
  23. { id: 3, parentId: 1, value: "C" },
  24. { id: 4, parentId: 2, value: "D" },
  25. { id: 5, parentId: 3, value: "E" }
  26. ];
  27. // 转换为树
  28. const tree = arrayToTree(items);

Você pode copiá-lo diretamente para ver o efeito, assim como uma boneca matryoshka russa. É fácil entender quando a segunda camada é adicionada à primeira camada. A dificuldade é que quando a terceira camada é adicionada à segunda camada, há. também uma terceira camada abaixo da segunda camada da primeira camada. Na verdade, se você pensar bem, poderá entender que há a["1"].children["2"] abaixo de a["1"], e seu valor não é apenas igual a a["2"], mas também uma referência são todos iguais, e execute a["1"].children.push(a["2"]);. Este benefício surge quando a["3"]={...item, children:[]} é executado, a["2"].children.push(a["3"]) é executado, porque está dentro os dados da operação, portanto, locais com a mesma referência (por exemplo, a=b, b.push também afetará a.push) também serão enviados, então você verá a["1"].children["2"] .crianças a["3"]. Esta é a estrutura de árvore correta.

Se você ainda não entendeu, você pode tentar o seguinte:

Conforme mostrado acima: b1 é considerado o nó de primeiro nível de a1, e a modificação de b1 afetará a1. Embora o texto acima seja um loop, as referências em cada escopo são as mesmas.

3. Macro tarefas e micro tarefas

2 4 5 código síncrono, 3 micro tarefas, 1 macro tarefa.A única armadilha é que 4 será impresso, mas o retorno 3 não será executado.

4. Operadores de comparação

Durante a comparação de conversão implícita, a matriz chama o método toString.

5. Escrita anti-vibração e estrangulamento

Você mesmo terá que escrevê-lo. Se nunca o escreveu antes, terá que rasgá-lo durante a entrevista e provavelmente não conseguirá arrancá-lo.Os seguintes são: execução imediata anti-vibração e execução atrasada, estrangulamento da execução imediata e execução atrasada

  1. function debounce(fn, delay) {
  2. let timer = null;
  3. return function (...args) {
  4. timer && clearTimeout(timer);
  5. timer = setTimeout(() => {
  6. fn.apply(this, args);
  7. }, delay);
  8. }
  9. }
  10. function debounce_immediate(fn, delay, immediate = false) {
  11. let timer = null;
  12. let flag = true;
  13. return function (...args) {
  14. timer && clearTimeout(timer);
  15. if (immediate) {
  16. if (flag) {
  17. fn.apply(this, args);
  18. flag = false;
  19. }
  20. timer = setTimeout(() => {
  21. flag = true;
  22. }, delay);
  23. } else {
  24. timer = setTimeout(() => {
  25. fn.apply(this, args);
  26. }, delay);
  27. }
  28. }
  29. }
  30. function throttle(fn, delay) {
  31. let lastTime = 0;
  32. let timer = null;
  33. return function (...args) {
  34. const nowTime = Date.now();
  35. if (nowTime - lastTime > delay) {
  36. fn.apply(this, args);
  37. lastTime = nowTime;
  38. }
  39. }
  40. }
  41. function throttle_D(func, delayTime) {
  42. let delay = delayTime || 1000;
  43. let timer = null;
  44. return function (...args) {
  45. if (!timer) {
  46. timer = setTimeout(function () {
  47. func.apply(this, args);
  48. timer = null;
  49. }, delay);
  50. }
  51. }
  52. }

Lembre-se de trazer argumentos. A diferença essencial entre anti-shake e throttling é que o anti-shake sempre zera o temporizador, enquanto o throttling não o faz. Se o throttling for sempre acionado, ele será executado dentro de um determinado intervalo de tempo e executado apenas uma vez. Se o anti-shake for acionado por um minuto, ele será executado apenas uma vez (execução imediata ou execução retardada acionada pelo último clique).