Partage de technologie

Questions de code d'entretien initial

2024-07-12

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

Cet article résume les questions de codage rencontrées au cours du processus d'entretien.

1. Promotion variable

2. Méthodes liées aux tableaux

Notez que la vraie valeur renvoyée est destinée à la rétention et non au filtrage, alors ne l'oubliez pas. Ce n'est rien, c'est juste que je l'oublierai si je ne l'écris pas en personne pendant six mois. . .

arr.filter((item, index, current) => {return arr.indexOf(item) == index});.Peut enlever du poids

L'essence du filtre est de créer un nouveau tableau, et si la fonction de rappel renvoie vrai, il sera conservé. La ligne de code ci-dessus signifie que seule la première fois est placée à l'intérieur.

Déduplication à double pointeur :

Utilisez des pointeurs doubles pour réorganiser le tableau. S'ils sont égaux, le pointeur rapide se déplacera d'un bit vers la droite, et s'ils ne sont pas égaux, le pointeur lent se déplacera d'un bit vers la droite. déplacez le pointeur rapide d'un bit vers la droite pour comparer avec la prochaine fois :

  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));

Entrée [1,1,2,2,4,4] et sortie [1,2,4].

Si le tableau est un objet :

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

{id:3,heure: 2}];

Nous devons maintenant supprimer les doublons en fonction de l'ID. Si les ID sont égaux, seul l'objet avec le temps le plus long sera conservé.

[{"id":1,"heure":4},{"id":2,"heure":4},{"id":3,"heure":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)); C'est tout.

Bien entendu, vous pouvez utiliser un objet vide pour vous en souvenir. A chaque fois, comparez l'heure correspondant à l'ID dans l'objet et choisissez de l'écraser. Après le parcours, utilisez une boucle for in pour convertir l'objet en tableau. Cependant, les doubles pointeurs sont très efficaces si la quantité de données est importante, il serait plus approprié d’utiliser des doubles pointeurs.

3. Référence liée

L'affectation du signe égal des variables de type référence ne s'affectera pas les unes les autres.

Cependant, cela sera affecté par l'utilisation de ab, qui est considérée comme une copie superficielle, comme indiqué ci-dessous.

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

Jetons un coup d'œil à un cas classique lié aux citations, qui est également une question que je n'ai pas écrite lorsque je l'ai rencontré pour la première fois lors de l'entretien. Convertissez le tableau en une structure arborescente :

  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);

Vous pouvez le copier directement pour voir l'effet, tout comme une poupée matriochka russe. Il est facile de comprendre quand la deuxième couche est ajoutée à la première couche. La difficulté est que lorsque la troisième couche est ajoutée à la deuxième couche. également un troisième calque en dessous du deuxième calque du premier calque. En fait, si vous y réfléchissez bien, vous pouvez comprendre qu'il y a un["1"].children["2"] sous un["1"], et sa valeur est non seulement égale à a["2"], mais aussi à une référence. Tous sont identiques et exécutent a["1"].children.push(a["2"]);. Cet avantage survient lorsque a["3"]={...item, children:[]} est exécuté, a["2"].children.push(a["3"]) est exécuté, car il est à l'intérieur les données d'opération, donc les endroits avec la même référence (par exemple, a=b, b.push affecteront également a.push) seront également poussés, vous verrez donc a["1"].children["2"] .enfants un["3"]. C’est la bonne arborescence.

Si vous ne comprenez toujours pas, vous pouvez essayer ce qui suit :

Comme indiqué ci-dessus : b1 est considéré comme le nœud de premier niveau de a1, et la modification de b1 affectera a1. Bien que ce qui précède soit une boucle, les références dans chaque portée sont les mêmes.

3. Macro-tâches et micro-tâches

2 4 5 code synchrone, 3 micro tâches, 1 macro tâche.Le seul écueil est que 4 sera imprimé, mais le retour 3 ne sera pas exécuté.

4. Opérateurs de comparaison

Lors d'une comparaison de conversion implicite, le tableau appelle la méthode toString.

5. Écriture manuscrite anti-tremblement et limitation

Vous devez l'écrire vous-même. Si vous l'avez déjà vu et ne l'avez jamais écrit auparavant, vous devrez le déchirer à la main pendant l'entretien et vous ne pourrez probablement pas le déchirer.Les éléments suivants sont : exécution immédiate anti-tremblement et exécution différée, exécution immédiate et exécution différée de limitation

  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. }

N'oubliez pas d'apporter des arguments. La différence essentielle entre l'anti-shake et la limitation est que l'anti-shake réinitialise toujours la minuterie, contrairement à la limitation. Si la limitation est toujours déclenchée, elle sera exécutée dans un certain intervalle de temps et exécutée une seule fois. Si l'anti-shake est déclenché pendant une minute, il ne sera exécuté qu'une seule fois (exécution immédiate ou exécution différée au déclenchement du dernier clic).