Προγραμματισμός και Τεχνολογία Λογισμικού Programming and Software Engineering Αλέξανδρος Χατζηγεωργίου Τμήμα Εφαρμοσμένης Πληροφορικής Πανεπιστήμιο Μακεδονίας Τμήμα Διοίκησης Τεχνολογίας, 25 Απριλίου 2007
Παραγωγικότητα Προγραμματιστών ... Έστω ένας τυπικός προγραμματιστής .... με μέση παραγωγικότητα productivity = average; που εργάζεται σε μια μεγάλη εταιρεία ανάπτυξης λογισμικού: Πόσες γραμμές κώδικα γράφει κατά μέσο όρο ανά ημέρα ?? (LOC/day)
Προγραμματισμός ... στην πράξη Εταιρεία Ανάπτυξης Λογισμικού: SuperSoftware SA (300 empl), CMM level = 1 Δευτέρα 8:00 π.μ. Boss -> Bob (programmer): "Γράψε ένα πρόγραμμα που να διαβάζει το χρώμα από το πληκτρολόγιο και να σχεδιάζει έναν κύκλο" Bob …. hmm (λιγότερο από 10 γραμμές κώδικα) Bob ….. 1 ώρα σχεδίαση, κώδικας, 1 ώρα testing, meetings, εκπαίδευση, καφές, φαγητό, τηλέφωνα κλπ κλπ (1 εβδομάδα) Bob -> Boss: "Τρεις εβδομάδες" Boss: OK !!!
Προγραμματισμός ... στην πράξη Αρχικό Σχέδιο σε 5 λεπτά (3 μονάδες λογισμικού)
Προγραμματισμός ... στην πράξη Παρασκευή 10:00 πμ: Μετά από πολλαπλά meetings, σεμινάρια, compiling, debugging, ανάκτηση της βάσης δεδομένων, επικοινωνία με πελάτες ....., ολοκλήρωση του εγχειριδίου χρήσης. Εύσημα από τον Boss διάδοση της φήμης του Bob ως εξαιρετικού προγραμματιστή σε όλη την εταιρεία !!!
Προγραμματισμός ... στην πράξη Τρεις μήνες μετά…: Boss: "Οι απαιτήσεις τροποποιήθηκαν, το πρόγραμμα θέλουμε να σχεδιάζει και τετράγωνα. Bob: Διαμαρτύρεται γιατί άλλαξαν οι απαιτήσεις, και προειδοποιεί τον Boss ότι θα χαλάσει όλη η καλή σχεδίαση που έκανε Ποιά θα ήταν η ιδανική τροποποίηση του προγράμματος ?? Bob: …… θα προσθέσω μία boolean παράμετρο στη μονάδα DrawColoredShape. true: Σχεδίαση Κύκλου, false: σχεδίαση τετραγώνου.
Προγραμματισμός ... στην πράξη ProgramM ProgramN Program1 DrawColoredShape Program2 Bob: …..hmmm, το interface δεν μπορεί να αλλάξει Bob:…..Aha, θα προσθέσω μία καθολική (global) μεταβλητή !!!
Προγραμματισμός ... στην πράξη // remember to reset the flag αν κάποιος θέλει να σχεδιάσει τετράγωνα πρέπει να θέσει την τιμή false για να μην σχεδιάζουν όλοι οι επόμενοι τετράγωνα πρέπει να επαναφέρει την τιμή true γι’ αυτό ο Bob είναι ευτυχής που θυμήθηκε να βάλει σχόλιο !!!
Προγραμματισμός ... στην πράξη Μερικές εβδομάδες μετά: o Boss (που παραμένει boss παρόλο που έγιναν ανακατατάξεις στην εταιρεία), λέει ότι ορισμένοι πελάτες "Θέλουν να μπορούν να διαβάζουν το χρώμα και από οθόνη αφής" Bob: …. Πελάτες !!! αυτοί πάντοτε καταστρέφουν τα σχέδια μου. Ο προγραμματισμός θα ήταν πολύ ευκολότερος αν δεν υπήρχαν πελάτες Anyway…. Λύση με ακόμη μία καθολική μεταβλητή !!!
Προγραμματισμός ... στην πράξη // remember to reset the flags η αξία του Bob φαίνεται από το γεγονός ότι θυμήθηκε να τροποποιήσει το σχόλιο !!!
Προγραμματισμός ... στην πράξη Η έλευση και δύο μόνο απαιτήσεων υποβάθμισε την ποιότητα. (Ο Bob αρχίζει να ξεσκονίζει το βιογραφικό του !!) Δίδαγμα: Οι απαιτήσεις πάντοτε αλλάζουν ! Ο σχεδιαστής – προγραμματιστής λογισμικού πρέπει να αναγνωρίζει ότι οι απαιτήσεις πρόκειται να αλλάξουν και να εξασφαλίζει ότι το λογισμικό θα μπορέσει να "επιβιώσει" όταν οι απαιτήσεις αλλάξουν.
Προγραμματισμός ... στην πράξη Το γεγονός ότι ζητήθηκε αλλαγή του σχήματος υποδηλώνει έναν “άξονα αλλαγών” (axis of change) Επομένως, το σχέδιο πρέπει να γίνει ανθεκτικό σε αλλαγές ιδίου τύπου Το καλύτερο σχέδιο θα πρέπει να συμμορφώνεται με την Αρχή της Ανοικτής-Κλειστής Σχεδίασης (Open-Closed Principle) Μια καλή ομάδα ανάπτυξης δεν κάνει προσπάθεια πρόβλεψης των αλλαγών: “Θεραπεία μετά τη διάγνωση” Τέτοια προβλήματα καλείται να αντιμετωπίσει ...... η
Τεχνολογία Λογισμικού Software Engineering
Τεχνολογία Λογισμικού ...ορισμός Κλάδος της Πληροφορικής που ασχολείται με τη μελέτη και ανάπτυξη τεχνικών για την παραγωγή λογισμικού που ικανοποιεί τις προδιαγραφές του, με την καλύτερη δυνατή ποιότητα, παραδίδεται μέσα σε προδιαγεγραμμένα χρονικά όρια και το κόστος ανάπτυξής του βρίσκεται μέσα σε προδιαγεγραμμένα όρια
Τεχνολογία Λογισμικού ...είπαν Software Engineering is: David Parnas: "the multi-person construction of multi-version software" Ghezzi: "the application of engineering to software" IEEE: "the application of a systematic, disciplined, quantifiable approach to the development, operation and maintenance of software" Roberts: "the discipline of writing programs that can be understood and maintained by others" in contrast to: "Programming is the discipline of writing programs that cannot be understood and maintained by anyone else than the author"
Μείζον πρόβλημα: Έργα Λογισμικού μικρής κλίμακας Μείζον πρόβλημα: η κατάστρωση αλγορίθμων η μετατροπή αλγορίθμων σε κώδικα μεγάλης κλίμακας (Multi-person, multi-version projects) Μείζον πρόβλημα: η επικοινωνία μεταξύ των υπομονάδων του έργου η συντήρηση του λογισμικού
Τεχνολογία Λογισμικού Software Crisis (μέσα 1960 ... σήμερα ?) Software Hall of Shame Year Company Outcome - Costs in US $ 2005 FBI Virtual Case File abandoned after 170 million spent 2004 UK Revenue Software errors -> 3.45 billion tax overpayment HP Problems with ERP system -> 160 million loss 2002 McDonald’s Corp Information processing system canceled after 170million spent 2001 Nike Inc. Problems with supply chain management -> 100 million loss 2000 Kmart Corp. 1.4 billion IT modernization effort -> declared bankruptcy 1997 IRS (USA) Tax modernization effort canceled after 4 billion is spent 1993 London Stock Exchange Taurus stock settlement system abandoned after 600 million spent Συντηρητική Εκτίμηση: Στις ΗΠΑ, απώλειες 60 – 70 δις δολ / έτος
.. άλλες διάσημες αποτυχίες 1961, Mercury (NASA), ΗΠΑ ανεπαρκής ακρίβεια στον υπολογισμό τροχιάς FORTRAN DO 10 I=1.10 (εσφαλμένο) DO 10 I=1,10 (ορθό) 1962, Mariner1 (NASA), ΗΠΑ καταστροφή πυραύλου αξίας $12M O αλγόριθμος ιχνηλάτισης βασίζεται στη μέση ταχύτητα απαιτήσεις R (εσφαλμένο) (ορθό)
.. άλλες διάσημες αποτυχίες 1996, Ariane 5 (European Space Agency) καταστροφή πυραύλου αξίας $370M Γλώσσα: Ada Μετατροπή ενός 64-bit floating-point αριθμού σε 16-bit προσημασμένο ακέραιο -> υπερχείλιση -> έλλειψη χειρισμού εξαίρεσης 1985-1986, Therac (AECL), Καναδάς σύστημα ελέγχου ακτινοβολίας ασθενών Γλώσσα: Assembly Θάνατος ασθενών από υπερβολική δόση ακτινοβολίας !!
Ιδιαιτερότητες Έργων Λογισμικού Διαφέρουν τα έργα λογισμικού από τα άλλα τεχνικά έργα ? Test 1: Έστω ότι ένα έργο λογισμικού έχει καθυστερήσει σε σχέση με το χρονοδιάγραμμα του. Αν είσαστε ο project manager με τι τρόπους μπορείτε να το επιταχύνετε ? Αν απαντήσατε με αύξηση των ατόμων ή με χρήση νέων εργαλείων ….. wrong answer ! (Mythical Man-Month) Test 2: Έστω ότι είστε ο project manager σε ένα έργο λογισμικού (μη έχοντας σχέση με προγραμματισμό). Πώς θα παρακολουθήσετε την πορεία του ? Προφανώς εξαρτάστε από τις αναφορές των υπολοίπων !! Test 3: Πουλάτε ένα προϊόν λογισμικού και σας ρωτούν να προσδιορίσετε την ποιότητα του. Τι θα αναφέρατε ? Προφανώς δεν υπάρχουν σαφή χαρακτηριστικά ποιότητας !!!
Επαλήθευση συστήματος Κύκλος Ζωής Λογισμικού Έλεγχος Εφικτότητας Μοντέλο Καταρράκτη Καθορισμός απαιτήσεων Σχεδίαση λογισμικού Υλοποίηση και έλεγχος τμημάτων Ολοκλήρωση και Επαλήθευση συστήματος Λειτουργία και Συντήρηση
Προϊόντα Λογισμικού Προϊόν Λογισμικού (Software Product) Κώδικας (Code) Τεκμηρίωση (Documentation)
Προϊόντα Λογισμικού ERICSSON UNIVERSITIES Docs Code
Κόστος Λογισμικού Σε τι συνίσταται το κόστος λογισμικού ? (Τι πληρώνουμε) Μισθούς προγραμματιστών ως επί το πλείστον !! Η εκτίμηση του κόστους που απαιτείται για την ανάπτυξη λογισμικού πολύ δύσκολη: 50% υπό-εκτίμηση από managers (κόστος, χρονοδιάγραμμα, πόροι)
Κατανομή Κόστους Τυπικού Έργου Λογισμικού Συντήρηση Υλοποίηση - Επαλήθευση Σχεδίαση Προδιαγραφές
Τι είναι η Συντήρηση Λογισμικού ? Το λογισμικό δεν “φθείρεται” !! Η συντήρηση συνίσταται στις ενέργειες που είναι απαραίτητες λόγω της εξέλιξης του λογισμικού: διορθωτική συντήρηση (corrective maintenance) προσαρμοστική συντήρηση (adaptive maintenance) βελτιωτική συντήρηση (perfective maintenance)
Τεχνολογίας Λογισμικού Ο Προγραμματισμός ως δραστηριότητα στα πλαίσια της Τεχνολογίας Λογισμικού
Σχεδίαση / Προγραμματισμός Υλοποίηση Σχεδίαση λογισμικού Η υλοποίηση ενός έργου λογισμικού (προγραμματισμός) καθορίζεται άμεσα από τη σχεδίαση του συστήματος
Σχεδίαση Σχεδίαση (οποιουδήποτε τεχνικού έργου) είναι: Σύστημα Η αποσύνθεση ενός συστήματος σε τμήματα (μονάδες)
Σχεδίαση Σχεδίαση (οποιουδήποτε τεχνικού έργου) είναι: Σύστημα Η αποσύνθεση ενός συστήματος σε τμήματα (μονάδες) Ο καθορισμός των σχέσεων μεταξύ των τμημάτων
Σχεδίαση Σχεδίαση (οποιουδήποτε τεχνικού έργου) είναι: Σύστημα Functionality A Functionality B Σύστημα Η αποσύνθεση ενός συστήματος σε τμήματα (μονάδες) Ο καθορισμός των σχέσεων μεταξύ των τμημάτων Η ανάθεση αρμοδιοτήτων σε κάθε τμήμα
Σχεδίαση Σχεδίαση (οποιουδήποτε τεχνικού έργου) είναι: Σύστημα Requirements Functionality A Functionality B Σύστημα Η αποσύνθεση ενός συστήματος σε τμήματα (μονάδες) Ο καθορισμός των σχέσεων μεταξύ των τμημάτων Η ανάθεση αρμοδιοτήτων σε κάθε σχήμα Η επικύρωση ότι όλα τα τμήματα μαζί επιτυγχάνουν τους σκοπούς του συστήματος
Ποιότητα Σχεδίασης Μια σχεδίαση μπορεί να είναι “καλή” ή “κακή” Είναι εύκολο να εντοπίσει κανείς τα συμπτώματα μιας κακής σχεδίασης Είναι εξαιρετικά δύσκολο να καθορίσει κανείς ένα σαφές, πεπερασμένο και αποτελεσματικό σύνολο βημάτων για την επίτευξη καλής σχεδίασης Μετά το πέρας της σχεδίασης η ποιότητα αξιολογείται συνήθως από τους “γκουρού” της ομάδας ! Πλέον εμφανές επακόλουθο "κακής" σχεδίασης: Δυσκολία συντήρησης
Ποιότητα Σχεδίασης Συμπτώματα "κακής" σχεδίασης: Δυσκαμψία (Rigidity): Το σύστημα είναι δύσκολο να τροποποιηθεί διότι κάθε αλλαγή οδηγεί σε πληθώρα αλλαγών σε άλλα τμήματα του συστήματος Ευθραυστότητα (Fragility): Οι αλλαγές που πραγματοποιούνται στο λογισμικό προκαλούν σφάλματα σε διάφορα σημεία. Ακινησία (Immobility): Υπάρχει δυσκολία διαχωρισμού του συστήματος σε συστατικά τα οποία μπορούν να επαναχρησιμοποιηθούν σε άλλες εφαρμογές. Έλλειψη ρευστότητας (Viscosity): Η πραγματοποίηση τροποποιήσεων με λάθος τρόπο είναι ευκολότερη από την πραγματοποίησή τους με τον ορθό τρόπο. Περιττή Πολυπλοκότητα (Needless Complexity): Το λογισμικό περιλαμβάνει στοιχεία που δεν είναι (ούτε πρόκειται να γίνουν) χρήσιμα. Περιττή Επανάληψη (Needless Repetition): Η σχεδίαση περιλαμβάνει επαναλαμβανόμενες δομές που θα μπορούσαν να ενοποιηθούν υπό μία κοινή αφαίρεση. Αδιαφάνεια (Opacity): Δυσκολία κατανόησης μιας μονάδας (σε επίπεδο σχεδίου ή κώδικα).
Ποιότητα Σχεδίασης Τα δύο κυριότερα χαρακτηριστικά ενός σχεδίου λογισμικού είναι: σύζευξη (coupling): μέτρο του κατά πόσο οι μονάδες αλληλο-εξαρτώνται μεταξύ τους συνεκτικότητα (cohesion): μέτρο της εσωτερικής συνοχής μιας μονάδας
Σύζευξη Παράδειγμα σύζευξης μεταξύ δύο μονάδων functionA functionB void functionA() { int x; . . . x = functionB(); } int functionB() { int z; z = . . .; return z; } functionA functionB
Σύζευξη Στόχος Σχεδίασης: Ελαχιστοποίηση της σύζευξης Αν τροποποιηθεί η μονάδα Χρονόμετρο απαιτείται (τουλάχιστον) ο έλεγχος και (ενδεχομένως) η μεταγλώττιση των συσχετιζόμενων μονάδων Για να επαναχρησιμοποιηθεί η μονάδα Χρονόμετρο απαιτείται “μεταφορά” των συσχετιζόμενων μονάδων
Τύποι σύζευξης Υψηλή Σύζευξη Μή Σύζευξη Χαλαρή Σύζευξη Περιεχόμενη Σύζευξη Σύζευξη ελέγχου Σύζευξη Δεδομένων Σύζευξη από κοινού Σύζευξη αντιγράφου
Τύποι σύζευξης Περιεχόμενη Σύζευξη: Μία μονάδα επεμβαίνει και τροποποιεί μία άλλη Μονάδα Η Μονάδα G GOTO G1 G1 : Η μονάδα G είναι δυνατόν να τροποποιήσει τον κώδικα της μονάδας H (μόνο σε assembly, Basic, Cobol)
Τύποι σύζευξης Μπορούμε να μειώσουμε τη σύζευξη τοποθετώντας δεδομένα σε κοινή περιοχή (π.χ. καθολικές μεταβλητές) Η εξάρτηση συνεχίζει να υπάρχει (από κοινού σύζευξη), αφού αλλαγές στις καθολικές μεταβλητές επηρεάζουν όλες τις μονάδες που έχουν πρόσβαση σε αυτές global variables Μονάδα Η Μονάδα G
Τύποι σύζευξης Σύζευξη ελέγχου έχουμε όταν μία μονάδα περνά flags για να ελέγξει τη δραστηριότητα μιας άλλης μονάδας (Π.χ. μία μονάδα ξεκινά τη λειτουργία της όταν μία άλλη ολοκληρωθεί και η τιμή ενός flag τεθεί σε κατάλληλη τιμή) Συνήθως πρόκειται για μεταβλητές που εμπλέκονται σε παραστάσεις δομών ελέγχου (conditional statements) Σύζευξη αντιγράφου: Πέρασμα δομών δεδομένων Εάν μεταξύ των μονάδων ανταλλάσσονται δεδομένα έχουμε σύζευξη δεδομένων. Στην περίπτωση αυτή, μία μονάδα μπορεί να τροποποιήσει τα ίδια τα δεδομένα μιας άλλης μονάδος (κλήση κατ’ αναφορά) ή να δράσει επάνω σε αντίγραφα των δεδομένων μιας άλλης μονάδος (κλήση κατ’ αξία)
Συνεκτικότητα Παράδειγμα χαμηλής συνεκτικότητας σε μονάδα ATM void ΑΤΜ() { εντολές επικοινωνίας με το χρήστη εντολές κρυπτογράφησης δεδομένων εντολές επικύρωσης ταυτότητας χρήστη εντολές επικοινωνίας με την τράπεζα εντολές εκτύπωσης απόδειξης } Στόχος Σχεδίασης: Μεγιστοποίηση της συνεκτικότητας
Τύποι Συνεκτικότητας ΜΟΝΑΔΑ Α Συμπτωματική συνεκτικότητα Λειτουργία Α Λειτουργία Β Συμπτωματική συνεκτικότητα (Μέρη ασυσχέτιστα) Λειτουργία C Λειτουργία D
Τύποι Συνεκτικότητας ΜΟΝΑΔΑ Α Χρονική Χρόνος Τ0 συνεκτικότητα (Συσχέτιση μέσω χρόνου) Χρόνος Τ0+Δ Χρόνος Τ0+2Δ
Τύποι Συνεκτικότητας ΜΟΝΑΔΑ Α Επικοινωνιακή Λειτουργία Α συνεκτικότητα (Προσπέλαση στα ίδια δεδομένα) Λειτουργία Β Λειτουργία C
Τύποι Συνεκτικότητας ΜΟΝΑΔΑ Α Ακολουθιακή Λειτουργία Α συνεκτικότητα (Έξοδος ενός είσοδος σε άλλο) OUT IN Λειτουργία Β OUT IN Λειτουργία C
Τύποι Συνεκτικότητας ΜΟΝΑΔΑ Α = ΛΕΙΤΟΥΡΓΙΑ Α Λειτουργική συνεκτικότητα (Πλήρη και συσχετισμένα τμήματα που εκτελούν τμήματα της ίδια λειτουργίας) Λειτουργία Α, τμήμα 1 Λειτουργία Α, τμήμα 2 Λειτουργία Α, τμήμα 3
Fan-in, Fan-out Fan-out: 4 A B C D E F G H I Fan-in: 1 Fan-out: 3
Fan-in, Fan-out Στόχος 1: Ελαχιστοποίηση αριθμού μονάδων με υψηλό fan-out Μία μονάδα που ελέγχει πολλές άλλες, συνήθως εκτελεί πολλές εργασίες (κακή συνεκτικότητα). Δυσκολία στον εντοπισμό σφαλμάτων, στην τροποποίηση, στην επαναχρησιμοποίηση Στόχος 2: Μεγιστοποίηση αριθμού μονάδων με υψηλό fan-in Μία μονάδα που ελέγχεται από πολλές άλλες, είναι μονάδα γενικής χρησιμότητας και είναι σαφώς προτιμότερο μία λειτουργία που εκτελείται συχνά να βρίσκεται σε μία μονάδα, παρά κατανεμημένη ή υλοποιημένη σε πολλές μονάδες
Γενικές Συμβουλές (Fairley 1985) Χρήση περιορισμένων γλωσσικών δομικών στοιχείων ροής ελέγχου (Βοhm & Jacopini) Συνετή χρήση της εντολής GOTO Ορισμός καινούριων τύπων δεδομένων για την ευχερέστερη διάκριση οντοτήτων (OOP principle) Απόκρυψη δομών δεδομένων πίσω από διαδικασίες πρόσβασης (information hiding principle) Απομόνωση των τμημάτων του κώδικα που εξαρτώνται από το μηχάνημα σε ξεχωριστές (λίγες) συναρτήσεις Χρήση τυποποιημένων περιγραφικών προλόγων στην αρχή κάθε υποπρογράμματος
Γενικές Συμβουλές (Fairley 1985) Προσεκτική εξέταση συναρτήσεων με λιγότερες από 5 ή περισσότερες από 25 εντολές Χρήση μεταβλητής στοίχισης, παρενθέσεων, κενών, κενών γραμμών και τετράγωνα περιοχών σχολίων Αποφυγή χρήσης εντολών της μίας μέσα στην άλλη σε μεγάλο βάθος, π.χ. printf(“%d”, func1(s*3*func2(4*s))); Περιορισμός του πεδίου εμβέλειας όσο το δυνατόν περισσότερο “σπάσιμο” του προγράμματος σε αρχεία δήλωση συναρτήσεων static: (ορατότητα μόνο στο αρχείο) καθολικές μεταβλητές (αποφυγή ή δήλωση ως static) τοπικές μεταβλητές (στο μικρότερο δυνατό μπλοκ όπου απαιτούνται)
Γενικές Συμβουλές (Fairley 1985) Don’t be too smart (Ο κώδικας γίνεται δυσανάγνωστος) Χρήση shorthands int i=0; int x = i++; //x = 0
Γενικές Συμβουλές (Fairley 1985) Παράδειγμα smart programming: Χρήση macros #include <stdio.h> #define add(a,b) ( (a) + (b) ) void main() { int c=5,d=7; printf(“sum= %d",add(c,d)); } #include <stdio.h> #define max(a,b) ( (a) > (b) ? (a) : (b) ) void main() { int c=5,d=7; int x = max(++c, ++d); printf("%d",x); } 9 !!! Τι εκτυπώνει ?
Ακραία Σενάρια .... Σε όλους είναι γνωστό ότι τα κενά δεν είναι σημαντικά στη C Τι σημαίνει η ακόλουθη εντολή ανάθεσης ? z = y+++x; O προγραμματιστής μπορεί να εννοούσε: z = y + ++x; z = y++ + x; Στη C ισχύει το maximal munch strategy. Αν δηλαδή υπάρχουν περισσότερες της μιας ερμηνείας για το επόμενο σύμβολο (token) ο μεταγλωττιστής θα προσπαθήσει να “αποσπάσει” τη μεγαλύτερη ακολουθία χαρακτήρων. Επομένως ισχύει:
Ακραία Σενάρια .... και στην περίπτωση: z = y+++++x; Θα ισχύσει: το οποίο θα παράγει compilation error καθώς ο τελεστής ++ “βρίσκεται στον αέρα” - error C2105: '++' needs l-value
Obfuscated C Code Contest πρόγραμμα που υπολογίζει το π εξετάζοντας το ίδιο του το εμβαδό (Brian Westley, 1988)
Obfuscated C Code Contest εκτυπώνει ....
Obfuscated C Code Contest
Γενικές Συμβουλές Αποφυγή υπερβελτιστοποίησης (Καταβολή υπερβολικά μεγάλης προσπάθειας στο ραφινάρισμα ενός τμήματος κώδικα που έχει μικρή συμβολή στην όλη αποδοτικότητα του προγράμματος. Ούτως η άλλως η απόδοση περιορίζεται από το νόμο του Amdahl :
Νόμος του Amdahl Έστω ότι βελτίωση E επιταχύνει ένα ποσοστό F του συνολικού προγράμματος κατά S (Π.χ. σε ένα πρόγραμμα 100 γραμμών που εκτελείται σε 10 secs 10 γραμμές βελτιώνονται ώστε να τρέχουν x2 γρηγορότερα, S=2)
Νόμος του Amdahl 1.05
Νόμος του Amdahl Έστω ότι βελτιώνουμε έναν επεξεργαστή έτσι ώστε οι εντολές floating point να εκτελούνται στο μισό χρόνο (επιτάχυνση 2x) Αλλά οι εντολές κινητής υποδιαστολής αποτελούν το 10% του συνόλου των εντολών σε ένα μέσο πρόγραμμα.
Πιο συχνά λάθη στη C Θα εκτυπώσει x = 5 main() { int x = 5; setToZero(x); printf("x = %d\n", x); } void setToZero(int x) { x = 0; } Θα εκτυπώσει x = 5 1. Κλήση κατ’ αξία στη θέση κλήσης κατ’ αναφορά
Πιο συχνά λάθη στη C Θα εκτυπώσει Two Three int x = 2; switch(x) { case 2: printf("Two\n"); case 3: printf("Three\n"); } Θα εκτυπώσει Two Three 2. Παράλειψη ενός break σε μια εντολή switch
Πιο συχνά λάθη στη C Θα εκτυπώσει x equals 6 int x = 5; if ( x = 6) printf(“x equals 6\n”); Θα εκτυπώσει x equals 6 3. Χρήση του = αντί του == ένας καλός τρόπος αποφυγής του σφάλματος είναι να τοποθετούνται οι σταθερές στην αριστερή πλευρά. Τότε με την εντολή if ( 6 = x) θα προκύψει σφάλμα
Πιο συχνά λάθη στη C RunTime Error 4. Υπέρβαση των ορίων ενός πίνακα main() { int A[5]; int i; for(i=0; i<6; i++) A[i] = i; } RunTime Error 4. Υπέρβαση των ορίων ενός πίνακα
Πιο συχνά λάθη στη C half = 0; double half = 1/2; half = 0; 5. Διαίρεση ακεραίων (πράξεις μεταξύ τελεστέων ιδίου τύπου οδηγούν σε αποτέλεσμα ιδίου τύπου) Λύση: double half = 1.0 / 2;
Πιο συχνά λάθη στη C 6. Ατέρμονες βρόχοι int x = 5; while( x > 0 ); κενή_εντολή; x--; 6. Ατέρμονες βρόχοι
Πιο συχνά λάθη στη C RunTime Error (General Protection Fault) #include <string.h> int main() { char* st; strcpy(st, "abc"); return 0; } char st[20]; char* st = malloc(20); RunTime Error (General Protection Fault) 7. Μή αρχικοποίηση δεικτών
Πιο συχνά λάθη στη C char st1[] = "abc"; char st2[] = "abc"; if ( st1 == st2 ) printf("Yes"); else printf("No"); Νο 8. Σύγκριση αλφαριθμητικών με == ( o τελεστής συγκρίνει τις τιμές των δεικτών st1 και st2). Ορθή σύγκριση με συνάρτηση βιβλιοθήκης string.h if (strcomp(st1, st2) == 0)
Πιο συχνά λάθη στη C int x; char st[31]; printf("Enter an integer: "); scanf("%d", &x); printf("Enter a line of text: "); fgets(st, 30, stdin); προτού πληκτρολογήσουμε το δεύτερο text το πρόγραμμα τερματίζεται 9. Εναπομείναντες χαρακτήρες στην περιοχή προσωρινής αποθήκευσης H scanf() διαβάζει τον ακέραιο, αλλά αφήνει στον buffer το ‘\n’. H fgets() ξεκινά να διαβάσει χαρακτήρες από τον buffer αλλά συναντά το ‘\n’ και σταματά. Λύση: Άδειασμα του χώρου προσωρινής αποθήκευσης
Πιο συχνά λάθη στη C /* gets example (επιστρέφει string από stdin) */ #include <stdio.h> main() { char string [20]; printf ("Insert your full address: "); gets (string); printf ("Your address is: %s\n",string); } 10. Χρήση gets(). ΝΑ ΜΗΝ ΠΡΑΓΜΑΤΟΠΟΙΕΙΤΑΙ ΠΟΤΕ !!! Η συνάρτηση δεν ελέγχει για το μέγεθος του string που παρέχεται ως παράμετρος και μπορεί να προκληθεί buffer overflow Τα περισσότερα προβλήματα ασφαλείας στο Internet σχετίζονταν με την gets()
Πιο συχνά λάθη στη C στην αξιοποίηση της έλλειψης ελέγχου από την gets() οφείλεται και το Internet Worm το Νοέμβριο του 1988 από Cornell Univ. Το σενάριο είχε ως εξής: PC_A: εντολή finger με “πολύ μεγάλο string” σε άλλο PC_B PC_B: έναρξη της finger PC_B: κλήση της gets() και αντιγραφή του string στη στοίβα PC_B: το “πολύ μεγάλο string” επικαλύπτει τη διεύθυνση επιστροφής PC_B: μεταφορά του ελέγχου σε συνάρτηση του επιτιθέμενου PC_B: απόκτηση δικαιωμάτων (shell) PC_B: επίθεση σε άλλο μηχάνημα PC_xx: repeat until sent to prison
Επισκοπήσεις – Reviews - Inspections Λάθη όπως τα προηγούμενα μπορούν να εντοπιστούν κατά τη διάρκεια συστηματικών επισκοπήσεων του κώδικα Η διαδικασία των επισκοπήσεων ξεκίνησε από την IBM το 1972 Μέχρι τότε, επισκοπήσεις πραγματοποιούνταν μόνο στον κώδικα Ορισμός επισκόπησης κατά IEEE: Τυπική διαδικασία κατά την οποία οι απαιτήσεις, το σχέδιο ή ο κώδικας εξετάζονται λεπτομερώς από ένα ή περισσότερα άτομα με σκοπό την ανίχνευση σφαλμάτων, παραβιάσεων προτύπων και άλλων προβλημάτων
Επισκοπήσεις - Reviews Υπάρχουν αρκετοί λόγοι για την πραγματοποίηση των reviews ή inspections: εντοπισμός και απομάκρυνση σφαλμάτων αύξηση της παραγωγικότητας συλλογή πληροφοριών για παρακολούθηση του έργου βελτίωση της τεχνογνωσίας βελτίωση ηθικού προγραμματιστών Παρόλο που τα σφάλματα εμφανίζονται μόνο στο τελικό προϊόν, εισάγονται σε όλες τις φάσεις ανάπτυξης. Το κόστος διόρθωσης ενός σφάλματος αυξάνει δραματικά με την εξέλιξη του έργου. Για το λόγο αυτό σκοπός των επισκοπήσεων είναι ο εντοπισμός των σφαλμάτων όσο το δυνατόν πιο πρώιμα, στο τέλος κάθε φάσης
Review Process Τυπική Σύνθεση ομάδας επισκόπησης: Πρόεδρος ή Συντονιστής (Moderator) Συγγραφέας (Author) Ελεγκτές (Reviewers – Inspectors) Γραμματέας (Record keeper)
Review Process Μόλις ο συγγραφέας του προϊόντος ολοκληρώσει την εργασία του, απευθύνεται μέσω του project manager στον πρόεδρο που καθορίζεται (η παράδοση του προϊόντος θα πρέπει να πληροί ορισμένα entry criteria, π.χ. επιτυχής μεταγλώττιση)
Review Process Στη συνέχεια ο πρόεδρος επιλέγει τους ελεγκτές και μοιράζει το υλικό (προϊόν προς έλεγχο, υποστηρικτικά έγγραφα, φόρμες, checklists) και καθορίζει χώρο και ημερομηνία επισκόπησης
Review Process Ο κάθε ελεγκτής εξετάζει ανεξάρτητα το προϊόν , σημειώνοντας πιθανά λάθη, ερωτήσεις προς διευκρίνιση, χρόνο που κατανάλωσε, συμπληρώνει checklists Faults
Checklists (για Κώδικα) από (http://www.processimpact.com/pr_goodies.shtml) Τεκμηρίωση: Είναι τα σχόλια συνεπή με τον κώδικα ? Έχουν όλα τα τμήματα κώδικα (συναρτήσεις) περιγραφή ? Μεταβλητές: Είναι όλες οι μεταβλητές ορισμένες με συνεπή και ξεκάθαρα ονόματα ? Υπάρχουν περιττές ή μη χρησιμοποιούμενες μεταβλητές ? Αριθμητικές Λειτουργίες: Υπάρχουν έλεγχοι ισότητας μεταξύ αριθμών κινητής υποδιαστολής ? Ελέγχονται οι διαιρέτες αν λαμβάνουν ποτέ την τιμή 0 ? Βρόχοι και Διακλαδώσεις: Ελέγχονται οι πιο συνήθεις περιπτώσεις πρώτες σε δομές if_else ? Καλύπτονται όλες οι περιπτώσεις στις δομές if_else και switch ? Αρχικοποιούνται οι δείκτες σωστά ? Υπάρχουν εκφράσεις μέσα σε βρόχους που δεν τροποποιούνται ?
Checklists (για Κώδικα) Βρόχοι και Διακλαδώσεις: Οι συνθήκες τερματισμού είναι προφανείς ? Έχει κάθε έκφραση switch μία εξ’ορισμού περίπτωση ? Αμυντικός Προγραμματισμός: Εξασφαλίζεται ότι οι δείκτες δεν βγαίνουν εκτός ορίων πίνακα, record ή αρχείου ? Ελέγχονται εισαγόμενες παράμετροι για ορθότητα και πληρότητα ? Πραγματοποιείται απελευθέρωση κάθε δεσμευόμενης θέσης μνήμης ? Υπάρχουν χρονόμετρα για την πρόσβαση εξωτερικών διατάξεων ? Ελέγχονται τα αρχεία για ύπαρξη πριν την πρόσβαση σε αυτά ? Μένουν όλα τα αρχεία σε σωστή κατάσταση μετά το πέρας της εκτέλεσης ?
Review Process Επισκόπηση: Χώρος – Χρόνος Διαθέσιμος, Μετράται ως χρόνος εργασίας Διάρκεια: Μέχρι 2 ώρες Ο συγγραφέας διατρέχει το κείμενο ή τον κώδικα. Σε κάθε σημείο που επιθυμεί αναφέρει το λάθος ο ελεγκτής. Ο συγγραφέας είτε αποδέχεται το λάθος είτε αποσαφηνίζει γιατί δεν είναι λάθος. Προσοχή: Δεν γίνεται ιδιαίτερη συζήτηση για κάθε σημείο. Μέγιστη συζήτηση για ένα σημείο 1-2 λεπτά Τα λάθη καταγράφονται από τον γραμματέα, καθώς και τα στοιχεία από τον κάθε ελεγκτή (χρόνος που καταναλώθηκε, κατηγοριοποίηση σφαλμάτων).
Review Process Στο τέλος της επισκόπησης ο πρόεδρος αποφασίζει αν θα απαιτηθεί και νέα επισκόπηση. Μετά το rework ο συγγραφέας παρουσιάζει το προϊόν στον πρόεδρο για να επικυρώσει το προϊόν. Go Προτετοιμασία υλικού προς επισκόπηση Μοίρασμα υλικού στους ελεγκτές Σύσκεψη επισκόπησης Yes Διόρθωση σφαλμάτων Νέο review? No Stop
Αποτελεσματικότητα των Inspections Κατά τη διάρκεια των επισκοπήσεων εντοπίζεται μέχρι και το 90% των σφαλμάτων καθ'όλη τη διάρκεια ενός έργου λογισμικού [Laitenberger 2000] To Jet Propulsion Laboratory (προμηθευτής της NASA σε software) υπολόγισε εξοικονόμηση $7.5 million σε 300 επισκοπήσεις : εξοικονόμηση $25.000 ανά επισκόπηση Ποσοστό των σφαλμάτων που εξαλείφεται κατά τις επισκοπήσεις : παραπάνω από 70% (ΑΤ&Τ 1994). Μείωση του κόστους σε σχέση με άλλες τεχνικές ελέγχου: κατά 300% Σχέση κόστους-απόδοσης των επισκοπήσεων : τουλάχιστον 1 προς 10 [Grady & Slack, 1994, HP] [Bull 1992]: 2823 επισκοπήσεις κώδικα, 348 επισκοπήσεις άλλων εγγράφων: εντοπισμός και απομάκρυνση 5649 σφαλμάτων
Τυπική Μορφή Inspection Record ΣΧΟΛΙΑ Όνομα Εγγράφου: Κώδικας E: Έλλειψη, Λ: Λάθος, Π: Πλεονασμός, Β: Βελτίωση Με: Μείζον, Ελ: Ελλάσσον Θέση Τύπος Σημασία Ελεγκτής Ενέργεια Τοπικό Περιγραφή line: 127 Λ Με ΒΜΟΥ NAI Σάρωμα του πίνακα από θέση 1 και μετά line: 302 B Eλ ΚΟUS OXI Διόρθωση Σχολίου ως: …….. 5/ 3.3.2 JNTI Διόρθωση λειτ. απαίτησης σύμφωνα με το ΕΠΑΛ
Είναι η C μια νεκρή γλώσσα ? Οι δέκα γλώσσες που χρησιμοποιούνται περισσότερο σε έργα λογισμικού ανοικτού κώδικα (Spinellis 2005) και σήμερα Γλώσσα 2005 Αριθμός έργων Ποσοστό έργων C 8393 21.2 C++ 7632 19.2 Java 5970 15.1 PHP 4433 11.2 Perl 3618 9.1 Python 1765 4.5 Visual Basic 916 2.3 Unix Shell 835 2.1 Assembly 745 1.9 Javascript 738 Γλώσσα 2007 Αριθμός έργων Ποσοστό έργων Java 23666 22.2 C++ 20414 19.2 C 18285 17.2 PHP 16161 15.2 Perl 6717 6.3 Python 6489 6.1 C# 5402 5.1 JavaScript 4966 4.7 Unix Shell 2319 2.2 Visual Basic 2161 2.0
Λίγα λόγια για τη C++ H C++ είναι ένα υπερσύνολο της C βασίζεται στο ίδιο συντακτικό υποστηρίζει όμως το αντικειμενοστρεφές μοντέλο προγραμματισμού (object-oriented programming model) Στο μοντέλο αυτό, τόσο η περιγραφή ενός προβλήματος όσο και η λύση του, επιτυγχάνονται δια της συνεργασίας αντικειμένων Παράδειγμα 8 Queens Problem Κυρίαρχη η έννοια της κλάσης (ομαδοποίηση δεδομένων και συμπεριφοράς) Κυρίαρχη η έννοια της αφαίρεσης
Συμπερασματικά Η υλοποίηση του κώδικα δεν είναι μια μεμονωμένη δραστηριότητα – εντάσσεται στο σύνολο των δραστηριοτήτων που συνιστούν τον κύκλο ζωής λογισμικού Στη βιομηχανία λογισμικού τα προϊόντα συντηρούνται και εξελίσσονται σε πολλές γενιές Καλή υλοποίηση συνεπάγεται εύκολη συντήρηση Σε έργα μεγάλης κλίμακας η απόδοση δεν είναι κατ’ ανάγκη το μόνο επιθυμητό χαρακτηριστικό του κώδικα κατανοησιμότητα ελεγξιμότητα συντηρησιμότητα
Τεχνολογία Λογισμικού Προγραμματισμός και Τεχνολογία Λογισμικού Programming and Software Engineering Τμήμα Διοίκησης Τεχνολογίας, 25 Απριλίου 2007