Όπως λένε, αν δεν ντρέπεσαι για τον παλιό σου κώδικα, τότε δεν μεγαλώνεις ως προγραμματιστής - και συμφωνώ με αυτήν την άποψη. Ξεκίνησα να προγραμματίζω για διασκέδαση πριν από 40 χρόνια και επαγγελματικά πριν από 30 χρόνια, οπότε έχω πολλά λάθη. πολύ. Ως καθηγητής επιστήμης υπολογιστών, διδάσκω στους μαθητές μου να μαθαίνουν από λάθη—τα δικά τους, τα δικά μου και άλλων. Νομίζω ότι ήρθε η ώρα να μιλήσω για τα λάθη μου για να μην χάσω τη σεμνότητά μου. Ελπίζω να είναι χρήσιμα σε κάποιον.
Τρίτη θέση - Microsoft C compiler
Ο δάσκαλος του σχολείου μου πίστευε ότι ο Ρωμαίος και η Ιουλιέτα δεν μπορούσαν να θεωρηθούν τραγωδία επειδή οι χαρακτήρες δεν είχαν τραγικές ενοχές - απλώς συμπεριφέρονταν ανόητα, όπως θα έπρεπε οι έφηβοι. Δεν συμφωνούσα μαζί του τότε, αλλά τώρα βλέπω έναν κόκκο ορθολογισμού στη γνώμη του, ειδικά σε σχέση με τον προγραμματισμό.
Όταν τελείωσα το δεύτερο έτος στο MIT, ήμουν νέος και άπειρος, τόσο στη ζωή όσο και στον προγραμματισμό. Το καλοκαίρι, έκανα πρακτική άσκηση στη Microsoft, στην ομάδα μεταγλωττιστή C. Στην αρχή έκανα καθημερινά πράγματα, όπως υποστήριξη δημιουργίας προφίλ, και μετά μου ανέθεσαν να δουλέψω στο πιο διασκεδαστικό μέρος του μεταγλωττιστή (όπως νόμιζα) - τη βελτιστοποίηση του backend. Συγκεκριμένα, έπρεπε να βελτιώσω τον κωδικό x86 για τις δηλώσεις υποκαταστημάτων.
Αποφασισμένος να γράψω τον βέλτιστο κωδικό μηχανής για κάθε πιθανή περίπτωση, πέταξα τον εαυτό μου στην πισίνα με τα μούτρα. Εάν η πυκνότητα κατανομής των τιμών ήταν υψηλή, τις εισήγαγα
Ήταν ένας εφιάλτης. Πολλά χρόνια αργότερα μου είπαν ότι ο προγραμματιστής που κληρονόμησε τον κώδικα μου με μισούσε.
Πήρα το μάθημα μου
Όπως γράφουν οι David Patterson και John Hennessy στο Computer Architecture and Computer Systems Design, μία από τις κύριες αρχές της αρχιτεκτονικής και του σχεδιασμού είναι γενικά να κάνουμε τα πράγματα να λειτουργούν όσο το δυνατόν γρηγορότερα.
Η επιτάχυνση των κοινών περιπτώσεων θα βελτιώσει την απόδοση πιο αποτελεσματικά από τη βελτιστοποίηση σπάνιων περιπτώσεων. Κατά ειρωνικό τρόπο, οι συνηθισμένες περιπτώσεις είναι συχνά πιο απλές από τις σπάνιες. Αυτή η λογική συμβουλή προϋποθέτει ότι γνωρίζετε ποια περίπτωση θεωρείται κοινή - και αυτό είναι δυνατό μόνο μέσω μιας διαδικασίας προσεκτικής δοκιμής και μέτρησης.
Προς υπεράσπισή μου, προσπάθησα να καταλάβω πώς έμοιαζαν οι δηλώσεις κλάδου στην πράξη (όπως πόσες διακλαδώσεις υπήρχαν και πώς κατανεμήθηκαν οι σταθερές), αλλά το 1988 αυτές οι πληροφορίες δεν ήταν διαθέσιμες. Ωστόσο, δεν θα έπρεπε να έχω προσθέσει ειδικές περιπτώσεις όποτε ο τρέχων μεταγλωττιστής δεν μπορούσε να δημιουργήσει τον βέλτιστο κώδικα για το τεχνητό παράδειγμα που βρήκα.
Χρειάστηκε να καλέσω έναν έμπειρο προγραμματιστή και, μαζί του, να σκεφτώ ποιες ήταν οι κοινές περιπτώσεις και να τις αντιμετωπίσω συγκεκριμένα. Θα έγραφα λιγότερο κώδικα, αλλά αυτό είναι καλό. Όπως έγραψε ο ιδρυτής του Stack Overflow, Jeff Atwood, ο χειρότερος εχθρός ενός προγραμματιστή είναι ο ίδιος ο προγραμματιστής:
Ξέρω ότι έχεις τις καλύτερες προθέσεις, όπως και όλοι μας. Δημιουργούμε προγράμματα και μας αρέσει να γράφουμε κώδικα. Έτσι είμαστε φτιαγμένοι. Νομίζουμε ότι οποιοδήποτε πρόβλημα μπορεί να λυθεί με κολλητική ταινία, ένα σπιτικό δεκανίκι και μια πρέζα κώδικα. Όσο κι αν πονάει οι κωδικοποιητές να το παραδεχτούν, ο καλύτερος κώδικας είναι ο κώδικας που δεν υπάρχει. Κάθε νέα γραμμή χρειάζεται εντοπισμό σφαλμάτων και υποστήριξη, πρέπει να γίνει κατανοητή. Όταν προσθέτετε νέο κώδικα, θα πρέπει να το κάνετε με απροθυμία και αηδία γιατί όλες οι άλλες επιλογές έχουν εξαντληθεί. Πολλοί προγραμματιστές γράφουν πάρα πολύ κώδικα, καθιστώντας τον εχθρό μας.
Αν είχα γράψει απλούστερο κώδικα που κάλυπτε συνηθισμένες περιπτώσεις, θα ήταν πολύ πιο εύκολο να ενημερώσω εάν χρειαζόταν. Άφησα πίσω μου ένα χάος που κανείς δεν ήθελε να αντιμετωπίσει.
Δεύτερη θέση: διαφήμιση στα κοινωνικά δίκτυα
Όταν εργαζόμουν στη Google για τη διαφήμιση μέσων κοινωνικής δικτύωσης (θυμάστε το Myspace;), έγραψα κάτι σαν αυτό στη C++:
for (int i = 0; i < user->interests->length(); i++) {
for (int j = 0; j < user->interests(i)->keywords.length(); j++) {
keywords->add(user->interests(i)->keywords(i)) {
}
}
Οι προγραμματιστές μπορεί να δουν αμέσως το σφάλμα: το τελευταίο όρισμα πρέπει να είναι j, όχι i. Η δοκιμή μονάδας δεν αποκάλυψε το σφάλμα, όπως και ο κριτής μου. Η εκκίνηση πραγματοποιήθηκε και ένα βράδυ ο κώδικάς μου πήγε στον διακομιστή και χάλασε όλους τους υπολογιστές στο κέντρο δεδομένων.
Δεν έγινε τίποτα κακό. Τίποτα δεν χάλασε για κανέναν, γιατί πριν από την παγκόσμια κυκλοφορία ο κώδικας δοκιμάστηκε σε ένα κέντρο δεδομένων. Εκτός κι αν οι μηχανικοί της SRE σταμάτησαν να παίζουν μπιλιάρδο για λίγο και έκαναν μια μικρή ανατροπή. Το επόμενο πρωί έλαβα ένα email με ένα crash dump, διόρθωσα τον κωδικό και πρόσθεσα δοκιμές μονάδας που θα έπιαναν το σφάλμα. Εφόσον ακολούθησα το πρωτόκολλο - διαφορετικά ο κώδικάς μου απλά δεν θα εκτελούσε - δεν υπήρχαν άλλα προβλήματα.
Πήρα το μάθημα μου
Πολλοί είναι σίγουροι ότι ένα τόσο μεγάλο λάθος θα κοστίσει σίγουρα την απόλυση του ένοχου, αλλά δεν είναι έτσι: πρώτον, όλοι οι προγραμματιστές κάνουν λάθη και δεύτερον, σπάνια κάνουν το ίδιο λάθος δύο φορές.
Στην πραγματικότητα, έχω έναν φίλο προγραμματιστή που ήταν εξαιρετικός μηχανικός και απολύθηκε επειδή έκανε ένα μόνο λάθος. Μετά από αυτό, προσλήφθηκε στη Google (και σύντομα προήχθη) - μίλησε ειλικρινά για το λάθος που έκανε σε μια συνέντευξη και δεν θεωρήθηκε μοιραίο.
Εδώ είναι τι
Ανακοινώθηκε κυβερνητική παραγγελία αξίας περίπου ενός εκατομμυρίου δολαρίων. Η IBM Corporation - ή μάλλον, ο Thomas Watson Sr. προσωπικά - ήθελε πολύ να το αποκτήσει. Δυστυχώς, ο αντιπρόσωπος πωλήσεων δεν μπόρεσε να το κάνει και η IBM έχασε την προσφορά. Την επόμενη μέρα, αυτός ο υπάλληλος μπήκε στο γραφείο του κυρίου Γουάτσον και τοποθέτησε έναν φάκελο στο γραφείο του. Ο κύριος Γουάτσον δεν μπήκε καν στον κόπο να το δει - περίμενε έναν υπάλληλο και ήξερε ότι ήταν επιστολή παραίτησης.
Ο Γουάτσον ρώτησε τι πήγε στραβά.
Ο πωλητής μίλησε αναλυτικά για την εξέλιξη του διαγωνισμού. Ονόμασε λάθη που έγιναν και θα μπορούσαν να είχαν αποφευχθεί. Τέλος, είπε: «Κύριε Γουάτσον, σας ευχαριστώ που με επιτρέψατε να εξηγήσω. Ξέρω πόσο χρειαζόμασταν αυτή την παραγγελία. Ξέρω πόσο σημαντικός ήταν» και ετοιμάστηκε να φύγει.
Ο Γουάτσον τον πλησίασε στην πόρτα, τον κοίταξε στα μάτια και του επέστρεψε τον φάκελο με τις λέξεις: «Πώς μπορώ να σε αφήσω να φύγεις; Μόλις επένδυσα ένα εκατομμύριο δολάρια στην εκπαίδευσή σας.
Έχω ένα μπλουζάκι που λέει: «Αν πραγματικά μαθαίνεις από τα λάθη, τότε είμαι ήδη κύριος». Στην πραγματικότητα, όταν πρόκειται για λάθη, είμαι διδάκτωρ επιστημών.
Πρώτη θέση: App Inventor API
Πραγματικά τρομερά σφάλματα επηρεάζουν έναν τεράστιο αριθμό χρηστών, γίνονται γνωστά στο κοινό, χρειάζονται πολύ χρόνο για να διορθωθούν και γίνονται από αυτούς που δεν θα μπορούσαν να τα έχουν κάνει. Το μεγαλύτερο λάθος μου ταιριάζει με όλα αυτά τα κριτήρια.
Όσο χειρότερο τόσο το καλύτερο
διαβάζω
Πώς θα έπρεπε να είναι: ο σχεδιασμός πρέπει να είναι απλός στην υλοποίηση και στη διεπαφή. Η απλότητα της διεπαφής είναι πιο σημαντική από την απλότητα της υλοποίησης.
Όσο χειρότερο, τόσο το καλύτερο: ο σχεδιασμός θα πρέπει να είναι απλός στην υλοποίηση και στη διεπαφή. Η απλότητα της υλοποίησης είναι πιο σημαντική από την απλότητα της διεπαφής.
Ας το ξεχάσουμε για ένα λεπτό. Δυστυχώς, το ξέχασα για πολλά χρόνια.
Εφευρέτης εφαρμογών
Ενώ δούλευα στην Google, ήμουν μέλος της ομάδας
Υλοποιήσαμε το αντικειμενοστραφή App Inventor σε Java, επομένως υπάρχει μόνο ένα σωρό αντικείμενα εκεί. Δεδομένου ότι οι μπάλες και τα ξωτικά συμπεριφέρονται πολύ παρόμοια, δημιούργησα μια αφηρημένη κλάση sprite με ιδιότητες (πεδία) X, Y, Speed (ταχύτητα) και Heading (κατεύθυνση). Είχαν τις ίδιες μεθόδους για τον εντοπισμό συγκρούσεων, την αναπήδηση από την άκρη της οθόνης κ.λπ.
Η κύρια διαφορά μεταξύ μιας μπάλας και ενός ξωτικού είναι αυτό που σχεδιάζεται ακριβώς - ένας γεμάτος κύκλος ή ένα ράστερ. Εφόσον υλοποίησα πρώτα τα sprites, ήταν λογικό να προσδιορίσω τις συντεταγμένες x και y στην επάνω αριστερή γωνία του σημείου που βρισκόταν η εικόνα.
Μόλις δούλευαν τα sprites, αποφάσισα ότι μπορούσα να εφαρμόσω αντικείμενα μπάλας με πολύ λίγο κώδικα. Το μόνο πρόβλημα ήταν ότι πήρα την απλούστερη διαδρομή (από την άποψη του εφαρμοστή), υποδεικνύοντας τις συντεταγμένες x και y της επάνω αριστερής γωνίας του περιγράμματος που πλαισιώνει τη μπάλα.
Μάλιστα, ήταν απαραίτητο να υποδεικνύονται οι συντεταγμένες x και y του κέντρου του κύκλου, όπως διδάσκεται σε οποιοδήποτε σχολικό βιβλίο μαθηματικών και σε κάθε άλλη πηγή που αναφέρει κύκλους.
Σε αντίθεση με τα προηγούμενα λάθη μου, αυτό επηρέασε όχι μόνο τους συναδέλφους μου, αλλά και εκατομμύρια χρήστες του App Inventor. Πολλοί από αυτούς ήταν παιδιά ή εντελώς νέοι στον προγραμματισμό. Έπρεπε να κάνουν πολλά περιττά βήματα όταν εργάζονταν σε κάθε εφαρμογή στην οποία υπήρχε η μπάλα. Αν θυμάμαι τα άλλα λάθη μου με το γέλιο, τότε αυτό με κάνει να ιδρώνω ακόμα και σήμερα.
Επιδιορθώσα τελικά αυτό το σφάλμα μόλις πρόσφατα, δέκα χρόνια αργότερα. "Patched", όχι "fixed", γιατί όπως λέει ο Joshua Bloch, τα API είναι αιώνια. Δεν ήταν δυνατή η πραγματοποίηση αλλαγών που θα επηρεάσουν τα υπάρχοντα προγράμματα, προσθέσαμε την ιδιότητα OriginAtCenter με την τιμή false στα παλιά προγράμματα και true σε όλα τα μελλοντικά. Οι χρήστες μπορεί να κάνουν μια λογική ερώτηση: ποιος σκέφτηκε να τοποθετήσει το σημείο εκκίνησης κάπου αλλού εκτός από το κέντρο. Σε ποιον? Σε έναν προγραμματιστή που ήταν πολύ τεμπέλης για να δημιουργήσει ένα κανονικό API πριν από δέκα χρόνια.
Διδάγματα
Όταν εργάζεστε σε API (κάτι που σχεδόν κάθε προγραμματιστής πρέπει να κάνει μερικές φορές), θα πρέπει να ακολουθείτε τις καλύτερες συμβουλές που περιγράφονται στο βίντεο του Joshua Bloch "
- Ένα API μπορεί να σας φέρει και μεγάλα οφέλη και μεγάλη ζημιά.. Ένα καλό API δημιουργεί επαναλαμβανόμενους πελάτες. Ο κακός γίνεται ο αιώνιος εφιάλτης σου.
- Τα δημόσια API, όπως τα διαμάντια, διαρκούν για πάντα. Δώστε τα όλα: δεν θα υπάρξει ποτέ άλλη ευκαιρία να τα κάνετε όλα σωστά.
- Τα περιγράμματα του API πρέπει να είναι σύντομες — μία σελίδα με υπογραφές και περιγραφές κλάσεων και μεθόδων, που δεν καταλαμβάνει περισσότερο από μία γραμμή. Αυτό θα σας επιτρέψει να αναδιαρθρώσετε εύκολα το API εάν δεν αποδειχθεί τέλειο την πρώτη φορά.
- Περιγράψτε περιπτώσεις χρήσηςπριν από την εφαρμογή του API ή ακόμη και την επεξεργασία των προδιαγραφών του. Με αυτόν τον τρόπο θα αποφύγετε την υλοποίηση και τον καθορισμό ενός εντελώς μη λειτουργικού API.
Αν είχα γράψει έστω και μια σύντομη περίληψη με τεχνητό σενάριο, πιθανότατα θα είχα εντοπίσει το λάθος και θα το διόρθωνα. Αν όχι, τότε σίγουρα θα το έκανε κάποιος από τους συναδέλφους μου. Οποιαδήποτε απόφαση έχει εκτεταμένες συνέπειες πρέπει να ληφθεί υπόψη για τουλάχιστον μια μέρα (αυτό δεν ισχύει μόνο για τον προγραμματισμό).
Ο τίτλος του δοκιμίου του Ρίτσαρντ Γκάμπριελ, «Worse Is Better», αναφέρεται στο πλεονέκτημα που οδηγεί στο να είσαι πρώτος στην αγορά —ακόμα και με ένα ατελές προϊόν— ενώ κάποιος άλλος ξοδεύει μια αιωνιότητα κυνηγώντας το τέλειο. Αναλογιζόμενος τον κώδικα sprite, συνειδητοποιώ ότι δεν χρειάστηκε καν να γράψω περισσότερο κώδικα για να τον κάνω σωστά. Ό,τι και να πει κανείς, έκανα μεγάλο λάθος.
Συμπέρασμα
Οι προγραμματιστές κάνουν λάθη κάθε μέρα, είτε γράφουν buggy κώδικα είτε δεν θέλουν να δοκιμάσουν κάτι που θα βελτιώσει τις δεξιότητες και την παραγωγικότητά τους. Φυσικά, μπορείς να είσαι προγραμματιστής χωρίς να κάνεις τόσο σοβαρά λάθη όπως έκανα εγώ. Αλλά είναι αδύνατο να γίνεις καλός προγραμματιστής χωρίς να αναγνωρίζεις τα λάθη σου και να μαθαίνεις από αυτά.
Συνεχώς συναντώ μαθητές που νιώθουν ότι κάνουν πάρα πολλά λάθη και ως εκ τούτου δεν έχουν αποκοπεί στον προγραμματισμό. Ξέρω πόσο συχνό είναι το σύνδρομο απατεώνων στην πληροφορική. Ελπίζω να μάθετε τα μαθήματα που απαρίθμησα - αλλά να θυμάστε το κύριο: ο καθένας μας κάνει λάθη - ντροπιαστικά, αστεία, τρομερά. Θα εκπλαγώ και θα στενοχωρηθώ αν στο μέλλον δεν έχω αρκετό υλικό για να συνεχίσω το άρθρο.
Πηγή: www.habr.com