JavaRush /בלוג Java /Random-HE /רמות של שפות תכנות
Marat Sadykov
רָמָה

רמות של שפות תכנות

פורסם בקבוצה

מבוא

מהן שפות התכנות השונות? איזה סוג של מושגים מוטמעים בהם? איך הם התפתחו? במאמר זה, נבחן את סוגי שפות התכנות המבוססות על מה שנקרא רמות - מקודי מכונה (רמה נמוכה, קרוב לחומרת המחשב) ועד לשפות כמו Java או C# (רמה גבוהה). ככל שרישום הטקסט של התוכנית יעבור פחות טרנספורמציות בדרך של הפיכתו לסט של אפסים ואחדים, כך הרמה נמוכה יותר.
רמות של שפות תכנות - 1
בהמשך נסתכל על:
  1. שפות ברמה נמוכה (קודי מכונה והרכבה)
  2. רמת ביניים (C, Fortran...)
  3. רמה גבוהה (C++, Java, Python, Ruby, JavaScript...)
הרמה גם מאפיינת כמה פירוט צריך לפרט את רישום התוכנית העתידית כדי ליישם את היישום. עד כמה תהליך זה פשוט עבור בני אדם? אין לראות ברמת השפה כאינדיקטור חד משמעי ליכולותיה. שפת תכנות היא כלי יעיל בתחום אחד ופחות שימושי באחרים. גם הנגר וגם הנגר עובדים עם עץ. לראשון יש כלי עיקרי - סט של אזמלים, השני - גרזן. עם זאת, נגר יהפוך ארון מגולף לאלגנטי יותר, ונגר יבנה בית מהר יותר. למרות שכל אחד מסוגל לעשות את עבודתו של השני, הוא יעשה זאת הרבה פחות ביעילות. נתונים שונים במחשב מיוצגים כקבוצות של אפסים ואחדים. פקודות בקרה לעיבודו הן אותם נתונים המכילים הוראות הקובעות את מיקום המידע הדרוש ואת שיטת השינוי.

שפות מכונה (רמה הנמוכה ביותר)

נצטרך לערוך ביקור קצר מאזור התוכנה לאזור החומרה. בואו נסתכל על זה בצורה פשוטה. המעבד הוא ה"מוח" הראשי של המחשב. לוח האם עליו הוא מותקן מכיל בקרים המשמשים לאינטראקציה עם מכשירים אחרים באמצעות אוטובוסים (ערוצי נתונים לתקשורת).
רמות של שפות תכנות - 2
חלקם עובדים במהירות גבוהה (חצים אדומים): המעבד שואב פקודות מהזיכרון ומבצע מניפולציות בנתונים, כרטיס המסך, במיוחד במשחקי תלת מימד, צורך כמויות אדירות של מרקמים, צורות, קואורדינטות פיקסלים ואובייקטים אחרים כדי לבנות תמונה על מסך הצג . אחרים (בשל מגבלות במהירות חילופי המידע) אינם זקוקים לאינדיקטורים כה גבוהים. התקנים פנימיים וחיצוניים שונים מחוברים בתרשים עם חיצים ירוקים.

העולם הפנימי של המעבד

כל פקודות המעבד מגיעות מהזיכרון לביצוע בצורה בינארית. הפורמט, המספר, תת-קבוצת ההוראות תלויים בארכיטקטורה שלו. רובם אינם מתאימים זה לזה ועוקבים אחר אידיאולוגיות שונות. וגם סוג הפקודה תלוי מאוד במצב (8/16/32... עומק סיביות) ומקור הנתונים (זיכרון, רישום, מחסנית...) איתו עובד המעבד. אותה פעולה יכולה להיות מיוצגת על ידי הוראות שונות. למעבד יש הוראות להוספת שני אופרנדים (ADD X,Y) והוספת אחד לזה שצוין (INC X). הוספת משולש לאופרנד יכולה להתבצע כ-ADD X,3 או על ידי קריאה ל-INC X שלוש פעמים. ולגבי מעבדים שונים, אי אפשר לחזות איזו מהשיטות הללו תהיה אופטימלית מבחינת מהירות או טביעת זיכרון. מטעמי נוחות, מידע בינארי נכתב בצורה הקסדצימלית. בואו ניקח בחשבון חלק מתוכנית מוכרת (שפת C, שהתחביר שלה דומה ל-Java)
int func() {
    int i = getData("7") ;
    return ++i;
   ...
}
קוד שמיישם את אותן פעולות בצורה של רצף הוראות למעבד: ... 48 83 ec 08 bf bc 05 20 00 31 c0 e8 e8 fe ff ff 48 83 c4 08 83 c0 01 ... כך נראית למעשה שפת התכנות ברמה הנמוכה של המעבד של אינטל. קטע שקורא למתודה עם ארגומנט ומחזיר את התוצאה בתוספת אחת. זוהי שפת מכונה (קוד), המועברת ישירות, ללא טרנספורמציות, למעבד לצורך ביצוע. יתרונות:
  • אנחנו לגמרי אדונים במצב, יש לנו את האפשרויות הרחבות ביותר לשימוש במעבד ובחומרת המחשב.
  • כל האפשרויות לארגון ואופטימיזציה של הקוד עומדות לרשותנו.
מינוסים:
  • יש צורך בידע נרחב על תפקוד המעבדים ולקחת בחשבון מספר רב של גורמי חומרה בעת ביצוע קוד.
  • יצירת תוכניות שהן מעט יותר מורכבות מהדוגמה שניתנה מובילה לעלייה חדה בזמן המושקע בכתיבת קוד וניפוי באגים בו.
  • תלות בפלטפורמה: תוכנית שנוצרה עבור מעבד אחד בדרך כלל לא תתפקד על אחרים. ייתכן שעבור מעבד זה, במצבי פעולתו האחרים, תידרש עריכת קוד.
קודי מכונות היו בשימוש נרחב בשחר המחשבים; לא היו שיטות אחרות לתכנות בעידן חלוצי המחשבים. נכון לעכשיו, הם משמשים מדי פעם על ידי מהנדסי מיקרואלקטרוניקה בעת פיתוח או בדיקות ברמה נמוכה של מעבדים.

שפת הרכבה (רמה נמוכה)

בניגוד למחשב, אתה ואני תופסים מידע טוב יותר בצורה טקסט/סמנטית ולא בצורה דיגיטלית. אתה יכול בקלות למנות חמישים שמות אנשי קשר בטלפון החכם שלך, אבל לא סביר שתצליח לכתוב את מספרי הטלפון התואמים שלהם בעל פה. זה אותו דבר עם תכנות. אנו מתקדמים בסולם הסוג על ידי נקיטת שלושה שלבים בסיסיים:
  • הבה נקשר הוראה סמלית אחת לקבוצות של הוראות מעבד דיגיטלי שמבצעות פעולות מתאימות.
  • הבה נדגיש את הטיעונים של הוראות המעבד בנפרד.
  • בואו נציג את היכולת לתת שמות לאזורי זיכרון, משתנים ומיקום של פקודות בודדות.
בואו נשווה קטעים של התוכנית הקודמת בקוד מכונה (במרכז) ובשפת assembly (מימין):
2004b0     48 83 ec 08      sub    $0x8,%rsp
2004b4     bf bc 05 20 00   mov    $0x2005bc,%edi
2004b9     31 c0            xor    %eax,%eax
2004bb     e8 e8 fe ff ff   callq  getData
2004c0     48 83 c4 08      add    $0x8,%rsp
2004c4     83 c0 01         add    $0x1,%eax
כפי שאתה יכול לראות, תהליך כתיבת התוכנית פושט: אין צורך להשתמש בספרי עיון להפקת ערכי פקודות דיגיטליות, חישוב אורכי מעבר, הפצת נתונים בזיכרון על פני התאים שלו ותכונות מעבד אחרות. אנו מתארים את הפעולה הנדרשת מקבוצה של פקודות סמליות והארגומנטים הדרושים להיגיון של הביצוע, ולאחר מכן תוכנית המתרגמת מתרגמת את קובץ הטקסט לקבוצה של אפסים ואלה המובנים למעבד. יתרונות:
  • תהליך הכתיבה והשינוי של הקוד פושט.
  • השליטה על כל משאבי החומרה נשמרה.
  • קל יחסית להעביר את התוכנית לפלטפורמות אחרות, אך הן דורשות שינוי בהתאם לתאימות החומרה.
מינוסים:
  • שפת Assembly היא שפת תכנות ברמה נמוכה. קשה ליצור אפילו חלקים קטנים של קוד. בנוסף, יש צורך גם לקחת בחשבון את הפעולה הספציפית של הציוד.
  • תלות בפלטפורמה.
דוגמה ההדגמה הפופולרית ביותר של Java:
public static void main(String[] args) {
    System.out.println("Hello World!");
}
ייראה (תחביר NASM, באמצעות Windows API ו-kernel32.lib) באופן הבא:
global _main
	extern  _GetStdHandle@4
	extern  _WriteFile@20
	extern  _ExitProcess@4

	section .text
_main:
	; DWORD  bytes;
	mov 	ebp, esp
	sub 	esp, 4

	; hStdOut = GetstdHandle( STD_OUTPUT_HANDLE)
	push	-11
	call	_GetStdHandle@4
	mov 	ebx, eax

	; WriteFile( hstdOut, message, length(message), &bytes, 0);
    push	0
	lea 	eax, [ebp-4]
	push	eax
	push	(message_end - message)
	push	message
	push	ebx
	call	_WriteFile@20

	; ExitProcess(0)
	push	0
	call	_ExitProcess@4

	; never here
	hlt
message:
	db  	'Hello, World', 10
message_end:
כמו קודי מכונות, שפת ההרכבה משמשת לעתים קרובות יותר על ידי מהנדסים ומתכנתי מערכות. הוא משמש לכתיבת חלקים תלויי חומרה של ליבת מערכת ההפעלה שהם קריטיים לזמן או קריטיים לתכונות היישום של מנהלי התקנים עבור התקנים היקפיים שונים. אבל לאחרונה הם פונים אליו פחות ופחות, שכן השימוש בו מפחית מאוד את הניידות של תוכניות לפלטפורמות אחרות. לפעמים הם משתמשים בתהליך הפירוק - הם יוצרים רשימת הרכבה של תוכנית מקודים דיגיטליים כדי לנתח את ההיגיון של ביצוע פרגמנטים קטנים. במקרים נדירים, אם הקוד המקורי ברמה גבוהה אינו זמין: ניתוח וירוסים כדי להילחם בהם או אובדן קוד המקור. שפת אסמבלי נחשבת לדור הראשון/שני (לא נשקול בנפרד פסאודוקודים לפני הופעת האסמבלר וההבדל שלהם מפקודות סמליות). ברצוני להדגיש את השימוש ב-assembler ב-Demo Scene: מיזוג של אמנות, מתמטיקה וקידוד ברמה נמוכה, המגלם את הרעיונות האמנותיים של יוצריהם בצורה של תוכניות היוצרות קטעי וידאו עם מגבלות משאבים. לעתים קרובות הגודל הכולל של התוכנית וקובץ הנתונים לא יעלה על 256 בתים (פורמט 4/64 קילובייט הוא גם פופולרי). הנה דוגמה לתוכנית של 4 קילו-בייט:

שפות קבוצה C/Fortran (רמה בינונית/גבוהה)

עם התפתחות היכולות של טכנולוגיית המחשב, כמות הפונקציונליות והתזמון של יישום הקוד ב-Assembler כבר לא היו מספקים. העלויות של כתיבה, בדיקה ותחזוקה של תוכניות גדלו בסדר גודל מהר יותר מהיכולות שלהן. היה צורך לצמצם את הדרישות מהמתכנת מבחינת הידע על תפקוד הציוד, לתת לו כלי שיאפשר לו לכתוב בשפות הקרובות להיגיון האנושי. עבור לרמה חדשה של סוגי שפות תכנות. לספק את היכולת לפצל למודולים שונים עם קריאה רציפה נוספת (פרדיגמת תכנות פרוצדורלית), לספק סוגים שונים של נתונים עם יכולת לבנות אותם וכו'. בנוסף, אמצעים אלה הביאו לשיפור הניידות של הקוד לפלטפורמות אחרות, ארגון נוח יותר של עבודת צוות. אחת השפות הראשונות שתמכו בכל האמור לעיל הייתה Fortran, שפותחה בשנות ה-50 של המאה הקודמת . היכולת ליצור בצורת טקסט עם תיאור של היגיון הביצוע באמצעות לולאות, ענפים, תתי שגרות והפעלה עם מערכים והצגת נתונים בצורה של מספרים אמיתיים, שלמים ומרוכבים שימחו את המהנדסים והמדענים. תוך זמן קצר נוצרו "מסגרות" מדעיות וספריות. כל זה היה תולדה של העובדה שפורטרן רלוונטית גם היום, אם כי בסביבה מדעית צרה, ומתפתחת, מכיוון שמטען הפיתוחים גדול מאוד, ספריית IMSL לבדה מתפתחת באופן פעיל מאז 1970 (!), כיצד הרבה תוכנות רלוונטיות דומות האם אתה זוכר? - ותיקים? ענף נוסף של פיתוח שפות ברמה זו הוא C. אם Fortran הפכה לכלי עבור מדענים, אז C נוצרה כדי לעזור למתכנתים ליצור תוכנות אפליקציה: מערכות הפעלה, דרייברים וכו'. השפה מאפשרת לשלוט באופן ידני על הקצאת זיכרון ונותנת גישה ישירה למשאבי חומרה. מתכנתי C צריכים לשלוט בישויות ברמה נמוכה, ולכן רבים סבורים ש-C היא שפת assembly מתקדמת ולעיתים נקראת שפה "בינונית". לאחר שהכנסת הקלדת נתונים ל-Assembler, אלמנטים של תכנות פרוצדורלי ומודולרי, שפת C היא עדיין אחת השפות העיקריות לתכנות מערכת, מה שמאפשר גם ההתפתחות המהירה של המיקרו-אלקטרוניקה בשנים האחרונות. כל מיני גאדג'טים, בקרים, רשת והתקנים אחרים צריכים דרייברים, הטמעת פרוטוקולים לשיתוף פעולה ותוכנות אחרות ברמה נמוכה יחסית כדי ליישם אינטראקציה עם הציוד. כל האמור לעיל תורם לביקוש לשפה כיום. עקרונות מונחה עצמים ופונקציונליים פותחו בהמשך בצורה של C++, C#, Java, תוך שהם לוקחים הרבה מתחביר C. יתרונות:
  • פישוט תהליך יצירת הקוד: הכנסת סוגים, חלוקה למודולים, צמצום רשימות תוכניות.
  • Прозрачная логика заложенного алгоритма вследствие ухода от машинных codeов к более понятным для человека командам в семантически описательном стиле.
  • Переносимость. Стало достаточно перекомпorровать текст программы для выполнения на другой платформе (возможно, с небольшой модификацией).
  • Скорость откомпorрованных программ.
Минусы:
  • Отсутствие автоматического управления памятью и необходимость постоянного её контроля.
  • Отсутствие реализации концепций an objectно-ориентированного и функционального программирования.

Развитие языков высокого уровня

שפות תכנות ברמה גבוהה, במונחים של יצירת תוכנה, החלו להתרחק יותר ויותר מקודי מכונה וליישם פרדיגמות תכנות שונות בנוסף לאלו הפרוצדורליות. אלה כוללים גם יישום של עקרונות מונחה עצמים. C++, Java, Python, JavaScript, Ruby... - מגוון השפות מסוג זה הוא הפופולרי והמבוקש ביותר כיום. הם מספקים יותר הזדמנויות להטמעת מגוון תוכנות ואי אפשר לקבוע בבירור את ה"התמחות" של כל אחת מהן. אבל הפופולריות של אפליקציה בתחומים רלוונטיים נובעת מספריות/מסגרות לעבודה איתן, למשל: JavaScript - Frontend. השפה תוכננה לאינטראקציה בין דפדפן אינטרנט של לקוח למשתמש ושרת מרוחק. הספריות הפופולריות ביותר הן Angular, React ו-VUE. נכון לעכשיו, הוא נמצא בשימוש פעיל יחסית בשרתים אינטרנטיים ובשרתים אחרים (backend), Node.js פופולרי במיוחד. רובי - אחורי. הוא משמש ליצירת סקריפטים (קבצי שירות) ועל שרתי אינטרנט. המסגרת העיקרית היא Ruby On Rails. Python הוא תחום מדעי והנדסי (מלבד תחום האינטרנט). זוהי חלופה לחבילות מחשוב ומתמטיות סטנדרטיות (Mathematica, Octave, MatLab...), אך יש לה את הסמנטיקה הרגילה של השפה ומספר רב של ספריות. יש לו מעריצים רבים בתחום מערכות למידת מכונה, סטטיסטיקה ובינה מלאכותית. ספריות בשימוש תכוף כוללות django, numpy, pandas ו-tensorflow. C++ – פיתוח אוניברסלי, אבולוציוני של שפת C. מספק יכולות תכנות פונקציונליות ומונחה עצמים מבלי לאבד את היכולת לקיים אינטראקציה עם חומרה ברמה נמוכה. בשל כך, פרודוקטיביות וגמישות מתממשות בעת יצירת תוכנה, אך גם המחיר תואם: חסם כניסה גבוה בשל מפרט השפה המורכב, הצורך בשליטה עצמאית על משאבים בעת ביצוע התוכנית. תוכנות רבות למשתמש יחיד ומערכת נכתבות באמצעותה: מודולי מערכת הפעלה (Windows, Symbian...), משחקים, עורכים (Adobe Photoshop, Autodesk Maya...), מסדי נתונים (MSSQL, Oracle...), שחקנים ( WinAmp...) וכו' יש לציין שתוכנה מודרנית היא מוצר מורכב, שפיתוחו משתמש במספר שפות תכנות בו-זמנית, ויכול להיות קשה מאוד לקבוע את מידת ההשתתפות של כל אחת מהן. התוצאה הכוללת.

התקדמות נוספת

לאחרונה, סוג אחר של תכנות צובר פופולריות - פונקציונלי (פיתוח נוסף של רמת השפה) . הנה עוד סוג של הפשטה לחישובים - פונקציות שלוקחות קבוצה של פונקציות כארגומנטים ומחזירות עוד אחת. את תפקיד המשתנים ממלאות אותן פונקציות (משתנים המוכרים לנו הם פשוט ביטויים קבועים, בדומה לסופי לפני הצהרת סוג בג'אווה). הפונקציה עצמה סגורה בהיקף שלה, התוצאה של פעולתה תלויה רק ​​בארגומנטים שעברו. שני מאפיינים מדהימים נובעים מכך:
  • לצורך בדיקה אנחנו צריכים רק ארגומנטים של פונקציה (תוצאת העבודה אינה תלויה במשתנים חיצוניים וכו').
  • תוכנית בסגנון פונקציונלי מוכנה באורח פלא במקביל: קריאות פונקציות עוקבות יכולות להתבצע בשרשורים שכנים (מכיוון שהן אינן מושפעות מגורמים חיצוניים) ואינן דורשות נעילה (כלומר, אין בעיות סנכרון). תמריץ טוב להקדיש זמן לנושא זה, לאור האימוץ הנרחב של מעבדים מרובי ליבות.
עם זאת, סף הכניסה גבוה יותר מאשר עבור OOP: עבור קוד יעיל יש צורך לבנות תוכנית, המתארת ​​את אלגוריתם הביצוע בצורה של פונקציות. אבל גם עבור סגנון פונקציונלי טהור זה יהיה נחמד לדעת את היסודות של לוגיקה ותורת הקטגוריות. הפופולריים ביותר הם Haskell, Scala, F#. אבל אל תפחד, אלמנטים של תכנות פונקציונלי הופיעו ב-Java (כמו גם בשפות מודרניות אחרות של הדור השלישי) וניתן לשלב אותם עם OOP. את כל הפרטים הללו תוכלו להכיר ביתר פירוט בהתמחות מקוונת JavaRush. תחום התכנות הלוגי (הרמה הבאה של שפות) עדיין לא מצא יישום מעשי רחב בשל הביקוש הנמוך שלו. בניית תוכניות דורשת ידע ביסודות של מתמטיקה בדידה, לוגיקה פרדיקטים, כלי אילוצים וענפים אחרים של לוגיקה מתמטית. השפה הפעילה הפופולרית ביותר היא פרולוג.

סיכום

נכון לעכשיו, השפות הנפוצות ביותר הן OOP. Java, מאז הקמתה, תמיד הייתה בטופ, בדרך כלל בשלוש השפות הפופולריות. בנוסף ל-OOP, הוא מכיל אלמנטים של תכנות פונקציונלי, ואתה יכול לשלב סגנונות שונים של כתיבת התוכנות שלך. מגוון היישומים של Java הוא רחב מאוד - אלו משימות עסקיות, הטמעת שרתי אינטרנט (בגב), השפה העיקרית ליצירת אפליקציות אנדרואיד, סביבות תכנות ומקומות עבודה חוצי פלטפורמות (IDE/AWM) ומודלים ועוד ועוד. . מעמדה של Java חזק במיוחד במגזר ה-Enterprise - תחום של תוכנות ארגוניות הדורשות קוד איכותי ואורך חיים ויישום ההיגיון העסקי המורכב ביותר.
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION