Κοινή χρήση τεχνολογίας

Ερωτήσεις σχετικά με τον κώδικα συνέντευξης στο μπροστινό μέρος

2024-07-12

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

Αυτό το άρθρο συνοψίζει τις ερωτήσεις κωδικοποίησης που προέκυψαν κατά τη διαδικασία της συνέντευξης.

1. Μεταβλητή προώθηση

2. Μέθοδοι που σχετίζονται με πίνακες

Σημειώστε ότι η πραγματική τιμή που επιστρέφεται είναι για διατήρηση, όχι για φιλτράρισμα, οπότε μην το ξεχνάτε. Δεν είναι τίποτα, απλά θα το ξεχάσω αν δεν το γράψω από κοντά για μισό χρόνο. . .

arr.filter((item, index, current) => {return arr.indexOf(item) == index});.Μπορεί να αφαιρέσει βάρος

Η ουσία του φίλτρου είναι να δημιουργηθεί ένας νέος πίνακας και εάν η συνάρτηση επανάκλησης επιστρέψει true, θα διατηρηθεί. Η παραπάνω γραμμή κώδικα σημαίνει ότι μόνο η πρώτη φορά τοποθετείται μέσα.

Αφαίρεση διπλού δείκτη:

Χρησιμοποιήστε διπλούς δείκτες για να ταξινομήσετε ξανά τον πίνακα, ο γρήγορος δείκτης θα μετακινηθεί ένα bit προς τα δεξιά, ο αργός δείκτης θα μετακινηθεί ένα bit προς τα δεξιά μετακινήστε τον γρήγορο δείκτη προς τα δεξιά για να συγκρίνετε με την επόμενη φορά:

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

Είσοδος [1,1,2,2,4,4] και έξοδος [1,2,4].

Αν ο πίνακας είναι αντικείμενο:

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

{id:3,time: 2}];

Τώρα πρέπει να αφαιρέσουμε τα διπλότυπα με βάση το αναγνωριστικό εάν τα αναγνωριστικά είναι ίσα, θα διατηρηθεί μόνο το αντικείμενο με το μεγαλύτερο χρόνο

[{"id":1,"time":4},{"id":2,"time":4},{"id":3,"time":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));

Φυσικά, μπορείτε να χρησιμοποιήσετε ένα κενό αντικείμενο για να το θυμάστε κάθε φορά, να συγκρίνετε τον χρόνο που αντιστοιχεί στο αναγνωριστικό στο αντικείμενο και να επιλέξετε αν θα το αντικαταστήσετε. Μετά τη διέλευση, χρησιμοποιήστε έναν βρόχο for για να μετατρέψετε το αντικείμενο σε πίνακα. Ωστόσο, οι διπλοί δείκτες είναι πολύ αποτελεσματικοί εάν ο όγκος των δεδομένων είναι μεγάλος, θα ήταν πιο κατάλληλο να χρησιμοποιήσετε διπλούς δείκτες.

3. Σχετική αναφορά

Η εκχώρηση πρόσημου ίσου των μεταβλητών τύπου αναφοράς δεν θα επηρεάσει η μία την άλλη.

Ωστόσο, θα επηρεαστεί από τη χρήση του ab, το οποίο θεωρείται ρηχό αντίγραφο, όπως φαίνεται παρακάτω.

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

Ας ρίξουμε μια ματιά σε μια κλασική περίπτωση που σχετίζεται με παραπομπές, η οποία είναι επίσης μια ερώτηση που δεν την έγραψα όταν την αντιμετώπισα για πρώτη φορά κατά τη διάρκεια της συνέντευξης.

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

Μπορείτε να το αντιγράψετε απευθείας για να δείτε το αποτέλεσμα, ακριβώς όπως μια ρωσική κούκλα matryoshka Είναι εύκολο να καταλάβετε πότε προστίθεται το δεύτερο στρώμα στο πρώτο στρώμα επίσης ένα τρίτο στρώμα κάτω από το δεύτερο στρώμα του πρώτου στρώματος Στην πραγματικότητα, αν το σκεφτείτε προσεκτικά, μπορείτε να καταλάβετε ότι υπάρχει ένα ["1"].children["2"] κάτω από ένα ["1"], και η τιμή του δεν είναι μόνο ίση με a["2"], αλλά και μια αναφορά Όλα είναι ίδια και εκτελούν a["1"].children.push(a["2"]);. Αυτό το πλεονέκτημα έρχεται όταν εκτελείται ένα["3"]={...στοιχείο, παιδιά:[]}, εκτελείται ένα ["2"].children.push(a["3"]), επειδή είναι μέσα τα δεδομένα λειτουργίας, επομένως μέρη με την ίδια αναφορά (για παράδειγμα, το a=b, το b.push θα επηρεάσει επίσης το a.push) θα προωθηθούν επίσης, επομένως θα δείτε ένα ["1"].children["2"] .παιδιά α["3"]. Αυτή είναι η σωστή δομή δέντρου.

Αν πάλι δεν καταλαβαίνετε, μπορείτε να δοκιμάσετε τα εξής:

Όπως φαίνεται παραπάνω: ο b1 θεωρείται ως ο κόμβος πρώτου επιπέδου του a1 και η τροποποίηση του b1 θα επηρεάσει τον a1. Αν και τα παραπάνω είναι ένας βρόχος, οι αναφορές σε κάθε πεδίο εφαρμογής είναι οι ίδιες.

3. Εργασίες μακροεντολών και μικροεργασίες

2 4 5 σύγχρονος κώδικας, 3 micro tasks, 1 macro task.Η μόνη παγίδα είναι ότι το 4 θα εκτυπωθεί, αλλά η επιστροφή 3 δεν θα εκτελεστεί.

4. Συγκριτικοί τελεστές

Κατά τη σύγκριση σιωπηρής μετατροπής, ο πίνακας καλεί τη μέθοδο toString.

5. Αντικραδασμική και στραγγαλιστική γραφή

Πρέπει να το γράψετε μόνοι σας Εάν το έχετε ξαναδεί και δεν το έχετε γράψει ποτέ πριν, θα πρέπει να το σκίσετε με το χέρι κατά τη διάρκεια της συνέντευξης και πιθανότατα δεν θα μπορείτε να το σκίσετε.Τα ακόλουθα είναι: αντικραδασμική άμεση εκτέλεση και καθυστερημένη εκτέλεση, στραγγαλιστική άμεση εκτέλεση και καθυστερημένη εκτέλεση

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

Θυμηθείτε να φέρετε args Η ουσιαστική διαφορά μεταξύ του anti-shake και του throttling είναι ότι το anti-shake επαναφέρει πάντα το χρονόμετρο, ενώ το throttling όχι εάν το throttling ενεργοποιείται πάντα, θα εκτελεστεί μέσα σε ένα συγκεκριμένο χρονικό διάστημα και θα εκτελεστεί μόνο μία φορά. Εάν το anti-shake ενεργοποιηθεί για ένα λεπτό, θα εκτελεστεί μόνο μία φορά (άμεση εκτέλεση ή καθυστερημένη εκτέλεση όταν ενεργοποιηθεί το τελευταίο κλικ).