תכנות מונחה התנהגות – רובי און ריילס (סקרינקאסט)

בסקרינקאסט הקצר הבא אני עובר על מספר עקרונות מנחים ומציג דוגמא זריזה של איך לעבוד ברובי און ריילס באמצעות תכנות מונחה התנהגות או BDD.

הסקרינקאסט קצר ונועד להסביר בקצרה את העקרונות ולהציג את שיטת העבודה המיוחדת ברובי און ריילס ובBDD.

הערה: לחוויית צפיה מיטבית, מומלץ לבחור HD ולהגדיל את הוידאו למסך מלא.

זיהוי גרסת SQL Server בחיבור מרוחק

לעיתים קרובות מאוד (אולי מדי) אני מתחבר לבסיסי נתונים מרוחקים של לקוחות או על מכונות אחרות באותה רשת שעליה אני עובד כרגע.

אני באופן אישי מבצע את החיבור דרך Sql Server Management Studio 2008 אבל כמובן שאני יכול להתחבר לכול גרסה של בסיס נתונים קודמת מה שיכול להיות מאוד מבלבל.

כמו כן, על מכונת הפיתוח שלי אני מריץ שתי גרסאות של core, גם 2005 וגם 2008, כדי שאוכל לייצא את הנתונים בצורה תקינה לשרתי הproduction או הtest.

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

9-12-2010 12-06-29 PM

המספרים שאפשר לראות בצד ימין לא ממש אומרים לנו משהו, האמת היא שאם אתם לא בSql Server team במיקרוסופט זה גם לא ממש צריך לומר לכם משהו.

לכן, יש סקריפט t-Sql מאוד נחמד שנותן פרטים רבים (את כול מה שצריך בעצם) על בסיס הנתונים שאליו אתם מחוברים כעת דרך הAPI של Sql server לנושא ולא דרך מעקפים שונים ומשונים ובטח לא על ידי טלפונים ומיילים לחברת ההוסטינג לשאול אותם :-)

הנה הסקריפט

CREATE TABLE #SqlServerInformation(
editionText char(30),
versionText char(250),
productVersionText char(20),
levelText char(20))

INSERT INTO #SqlServerInformation (editionText, versionText, productVersionText, levelText)
VALUES (
CONVERT(char(30), SERVERPROPERTY('Edition')),
CONVERT(char(250), @@version),
CONVERT(char(20), SERVERPROPERTY('ProductVersion')),
CONVERT(char(20),SERVERPROPERTY('ProductLevel'))
)

SELECT * FROM #SqlServerInformation

drop table #SqlServerInformation

כמו שאפשר לשים לב, אני בעצם יוצר טבלה זמנית ואליה מכניס את כול הנתונים, אפשר כמובן סתם להדפיס אותם על המסך אבל לדעתי הפתרון הזה יותר גמיש כי אפשר לעשות אותו גם דרך קוד c# למשל.

אשמח לתגובות

ניהול זכרון באפליקציות פלקס או איך לשמור על שפיות

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

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

ראשית, הדבר שחשוב להבין הוא שהזכרון שלנו נמצא בתוך סביבה מנוהלת, אנחנו לא כותבים קוד מכונה ולכן לא יכולים לעשות כול העולה על רוחנו או שמישהו מעלינו, בין אם זה מק או windows או כול אחד אחר, יחליט בשבילנו שנגמר הזכרון ואנחנו יכולים לכבות את האפליקציה.

הדבר שתיארתי למעלה מתואר בהמון פוסטים שהכותרת שלהם היא "flex sucks" וכן הלאה, נחסוך תיאורים אחרים.

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

מה גם, שבעולם של היום שהוא עולם של mobile devices, חשוב לנו להבין שהזכרון הוא משאב עוד יותר מוגבל.

בכול הזדמנות שיש לי אני מתאר תהליך של ניהול זכרון כ"היה חכם" ולא כ"היה צודק" או כול מושג אחר, תמיד תדאג שהזכרון יהיה נמוך ביותר שניתן להעלות על הדעת, יבואו כול המתכנתים ויגידו שיש לולאות, פונקציות, וכדומה… איך אנחנו יכולים לדאוג שיהיה נמוך?

אני אומר, ונוהג כך באפליקציות שלי, הדרך לזיכרון נמוך עוברת דרך כול שורת קוד, אם שורה יכולה לקחת .3k במקום 5k זה מעולה, בחישוב של אפליקציה גדולה, הדבר יתורגם למגות על גבי מגות של זכרון יקר ושלא יסולא בפז.

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

דליפות זכרון

דליפות זכרון זה עניין גדול ומשמעותי באפליקציות פלקס, בדרך כלל ניתן לקטלג אותן בשתי קטגוריות, הקטגוריה הראשונה היא שהאפליקציה צורכת זכרון שלא כתוצאה מפעולה שלנו, הקטגוריה השנייה היא שהאפליקציה לא משחררת זכרון היות ולא טיפלנו בנקיון שלו כמו שצריך.

אפליקציות פלקס מנהלות זכרון על ידי referances. כלומר, אם יש לי instanceA שיש לו referance דרך instanceB הוא לא ישוחרר מהזכרון עד שלא נשחרר את ההפניה.

Event Listeners

הבעיה הגדולה ביותר שלנו היא עם אירועים Event Listeners שהם ללא ספק המקור מספר אחת לבעיות ולדליפות זכרון באפליקציות שלנו.

ניקח את פיסת הקוד הזו למשל

//objectX
objectY.addEventListener(some_event, some_function)

יש לנו כאן בעצם שני אובייקטים, יש לנו את אובייקט Y ויש את אובייקט X.

אובייקט Y מחזיק referance לאוביקט X על ידי זה שהעברתי פונקציה שאמורה להאזין לפעולה בתוך האוביקט, כלומר, עד שלא נסיר את ה"האזנה" שני האובייקטים האלה לא יוכלו להיות משוחררים מהזכרון או יותר נכון לומר שכול עוד אוביקט Y קיים, אובייקט X יהיה קיים בזכרון גם הוא.

כן כן, תנו לזה לשקוע :-)

ניתן בevent Listeners לומר שהlistener  הוא weak, כלומר הוא לא נחשב כreference מאחורי הקלעים, יש ויכוח מאוד גדול כול פעם שהנושא הזה עולה ב StackOverflow או כול פורום אחר, הרבה אומרים שאדובי היו צריכים לעשות שevent listeners יהיו weak כברירת מחדל, אני חייב לומר שאני לא מסכים עם הקביעה הזו, אני חושב שאנחנו כמתכנתים צריכים לדעת לזרוק את ה listeners לפח בסיום השימוש

משתנים סטטיים

משתנים סטטיים לעולם לא מתאפסים, לאורך כול חיי האפליקציה ערך שהצבתם בהם צורך זכרון, דמיינו עכשיו שנתתם למשתנה static ערך מסוג class שמחזיק event listener והנה יש לכם כאן מסננת של זיכרון שתדלוף ותדלוף.

מה שאנחנו צריכים לעשות בעצם כדי לדאוג לשחרור הזכרון הוא לבצע null out לאובייקט בסיום השימוש, כמו שפיסת הקוד הבאה

// static variable
public static var _foo:Foo;
//setting the value
_foo = new Foo();
//clean
_foo = null;

Dictionaries

Dictionaries זה בעצם אוסף של אובייקטים בצורה של מפתח-ערך, על כול שורה יש מפתח ולכות מפתח יש ערך.

אני אנסה להסביר את זה בצורה הטובה ביותר שניתן אבל אנא אמצו את עינכם, זה ממש קסמי Adobe ניהול הזכרון באובייקטים האלה :-)

אפשר (ורצוי) לקבוע שאובייקט X הוא מפתח ואובייקט Y הוא ערך, כלומר מה שיש לנו עכשיו זה מילון של אובייקטים שאחד הוא המפתח והשני הוא הערך של המפתח.

אפשר לקבוע weak key כלומר במידה ואין הפניות (references) לאובייקט X, הוא יאסף על ידי הCollector אבל עכשיו יש לנו מצב מוזר, אפילו שיש לנו ערך בלי מפתח, הערך עדיין שם.

כן כן, אני יודע זה מוזר, אני גם לא האמנתי לזה כשנכנסתי לפרופיילר אבל זה המצב.

אשמח עם מישהו מצוות פיתוח פלקס יבהיר את המצב הזה…

נמשיך.

איך מנקים את המצב הזה?
יש האק, אם עושים לולאת For על הDictionary, כול הערכים שאין להם מפתחות ינוקו גם הם, כמובן בכול מגבלות הreferance הקיימות.

סיכום

יש כמובן עוד טיפים, טריקים ושיטות לניהול צריכת הזכרון באפליקציות פלקס, אני חושב שאם מקפידים על שלושת אלה, שהם המרכזיים בעיני האפליקציות שלכם יהיו טובות ורזות.

כול ה"טיפים" האלה אולי יכולים להראות קטנוניים אבל כשמבינים מה קורה מאחורי הקלעים כשיש לנו למשל DataGrid שיש לו ItemRenderes שלכול אחד יש reference אחד שלא מנוקה יכול להבין שבסופו של יום מדובר בכמויות היסטריות לחלוטין של זיכרון.

לפני כחודש היה לי לקוח שטיפלתי לו בדליפת זכרון של 1G מתוך פלייר וידאו, כול מה שעשיתי היה לדאוג לניקוי של Event Listeners והאפליקציה היום צורך 23מגה בשיא העבודה והעומס שלה.