<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های AliReza Beigy</title>
        <link>https://virgool.io/feed/@alirezabeigy</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-06-16 11:04:38</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/41214/avatar/Uzlp3K.png?height=120&amp;width=120</url>
            <title>AliReza Beigy</title>
            <link>https://virgool.io/@alirezabeigy</link>
        </image>

                    <item>
                <title>ارائه TA برنامه نویسی پیشرفته - Qt - جلسه 2</title>
                <link>https://virgool.io/@alirezabeigy/%D8%A7%D8%B1%D8%A7%D8%A6%D9%87-ta-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D9%BE%DB%8C%D8%B4%D8%B1%D9%81%D8%AA%D9%87-qt-%D8%AC%D9%84%D8%B3%D9%87-2-p7dqgbvtnoks</link>
                <description>دروداین جلسه میخوایم درباره فریم ورک Qt صحبت کنیم و چندتا از کامپوننت های Qt رو استفاده کنیم.این ترم شما با برنامه نویسی cpp و سینتکس اون آشنا شدین و میتونید ازش استفاده کنید تا برنامه هایی رو پیاده سازی کنید، ولی آیا الان میتونید از صفر یه بازی گرافیکی بنویسید؟برای همچین کاری نیاز به دانشی بیشتر از دانش برنامه نویسی یک زبان دارید، باید با سیستم عامل و امکانات و طرز کارش آشنا باشید.برای خیلی از کارها نیاز هست تا کد هایی بر اساس سیستم عامل پیاده سازی بشه و خب ما این ترم نمیخوایم زیاد وارد این موارد بشیم و میخوایم از یک مجموعه ابزار که بهمون قابلیت هایی رو میدن که میتونیم محیط گرافیکی ایجاد کنیم، از طریق اینترنت به جایی درخواست بفرستیم و جواب بگیریم و یا کیبورد و موس رو کنترل بکنیم.اسم این ابزار Qt (کیوت یا کیوتی) هست، برای نصب این ابزار میتونید به آدرس زیر مراجعه کنید و نسخه Open Source یا همون Community اون رو دانلود و نصب کنید (لازم نیست نسخه پولی اون رو دانلود کنید یا فرم تریال پر کنید، شما نسخه کاربران متن‌باز(for open source users) رو باید دانلود کنید)qt.io/downloadزمان نصب گزینه custom installation رو بزنید و مورد Qt 6.4.2 رو گزینه های داخل عکس رو انتخاب کنید، این موارد برای کارهایی که میخوایم انجام بدیم کفایت میکنه.نسخه 6.4.2 نسخه LTS(long term support) یا پایدار Qt میباشد و اینکه ما از کتابخونه QtMultimedia برای کار با فایل های صوتی استفاده میکنیم.وقتی Qt رو نصب میکنید ابزاری به اسم Qt Creator روی سیستمتون نصب میشه که عملا IDEه Qt هست، ما یه کم روی IDE کار میکنیم و بعد میریم روی CLion (علتش هم اینه که توسعه راحت تر هست و هوشمندی CLion بیشتر از Qt Creator هست).بریم یک پروژه روی Qt Creator ایجاد کنیم، برای اینکار روی Create Project در صفحه Welcome کلیک میکنیم یا از طریق منوی File اقدام میکنیم که با پنجره زیر رو به رو میشیمبرای شروع ما میخوایم یک برنامه تحت کامند لاین توسط Qt توسعه بدیم، بعد از این مرحله نام پروژه رو باید انتخاب کنیم و در مرحله بعد باید Build System رو انتخاب کنیمما میتونیم از سه نوع Build System استفاده کنیم1. qmake که دیگه توسعه داده نمیشه2. cmake که گزینه پیشنهادی برای Build System هست3. qbs که عملا نسخه جدید qmake هست که در حال توسعه هست ابزار های دیگه ای هم برای اینکار موجود هست، در واقع Build System ابزاری هست که ما از اون برای مدیریت پروژه و بیلد کردن اون پروژه ازش استفاده میکنیم.مرحله بعد برامون سیستمی رو محیا میکنه تا بتونیم جملات و کلماتی که در برنامه قراره به کاربر نشون بدیم رو در فایلی ذخیره کنیم، این ویژگی در زمان چند زبانه بودن برنامه بسیار کاربردی هست،  توجه داشته باشید که استفاده از این قابلیت میتونه به خوانا تر شدن و مرتب تر بودن کدتون نیز کمک کنه.مرحله بعد Development Kit یا همون نسخه Qt ای که میخواید باهاش پروژه رو بیلد بگیرید انتخاب میکنیددر نهایت هم ورژن کنترل یا همون Git رو انتخاب میکنید تا بتونید بهتر مدیریت روی تغییراتتون داشته باشید.توجه داشته باشید که میتونید برای ایجاد پروژه از همون IDEه CLion نیز استفاده کنید.برای شروع میریم سراغ یکی از پر کاربردترین کلاس ها در Qt به اسم QObject، این کلاس تقریبا در خیلی از کلاس های Qt استفاده میشه و ویژگی هایی رو برای یک کلاس محیا میکنه، حالا بریم یک مثال بزنیم، یک کلاس که از QObject ارث‌بری کنه میسازیم، برای اینکار فعلا بهتره از طریق Qt Creator اقدام کنیم و روی پروژه راست کلیک کنیم و گزینه Add New... رو انتخاب کنیم و در پنجره باز شده C++ class و انتخاب کنیم و از قسمت Base Class کلاس QObject رو انتخاب کنیمهمونطور که در تصویر میبینید گزینه هایی مثل Include کردن و اضافه کردن Q_OBJECT میبینید، مورد اول که واضع هست، کلاس QObject رو Include میکنه تا بتونیم ارث‌بری کنیم، مورد دوم یک Macro هست که قابلیت meta-object رو برای کلاس مورد نظر فعال میکنه (در مورد meta-object در اینجا میتونید مطالعه کنید)بعد از زدن روی Finish دیالوگی نمایش داده میشه که میگه Qt توانایی اضافه کردن کلاس ها به CMake رو نداره و اطلاعات داخل clipboard شما ذخیره شده فقط کافیه در قسمت add_executable در فایل CMake که باز میشه Paste (Ctrl + V) کنید. (این عملیات در IDEه CLion بهتر عمل میکنه)character.h#ifndef CHARACTER_H
#define CHARACTER_H

#include &lt;QObject&gt;

class Character : public QObject {
    Q_OBJECT
public:
    explicit Character(QObject *parent = nullptr);
signals:
};

#endif // CHARACTER_Hدر کد رو به رو میبینیم که ماکرو Q_OBJECT اضافه شده و از QObject ارث‌بری شدهحالا میخوایم به دوتا از قابلیت هایی که QObject در اختیارمون میاره بپردازیم:1. destructor of a parent object destroys all child objects2. signal &amp; slot3. غیر قابل کپی بودنقبل از اینکه بخوام درباره قابلیت های QObject صحبت کنیم، بهتره بدونیم که Qt خیلی از کلاس های استاندارد cpp رو بازنویسی کرده و متد های کاربردی ای رو برامون محیا کرده، برای مثال برای اینکه خروجی کارمون رو تحت Console ببینیم عموما از cout داخل namespaceعه std استفاده میکنیم و برای هر خط endl میزاریم، در حالی که Qt متد هایی رو برای دیباگ و نمایش در کنسول برامون مهیا کرده که میتونه خروجی های بهتری رو برامون داشته باشه.برای مثال به نمونه کد زیر توجه کنید#include &lt;QDebug&gt;
#include &amp;quotcharacter.h&amp;quot

int main(int argc, char *argv[])
{
    Character characterObj;
    characterObj.setObjectName(&amp;quotTheObjectName&amp;quot);
    qInfo() &lt;&lt; &amp;quotThis is a QObject class -&gt;&amp;quot &lt;&lt; &amp;characterObj;
}در این کد ما یک شی از کلاس Character ساختیم و یک نام برای این شی قرار دادیم توسط تابع setObjectName و توسط qInfo از QDebug خروجی رو به نمایش در آوردیم.خروجی کد بالا به صورت زیر میشهThis is a QObject class -&gt; Character(0x250f1ff6a0, name = &amp;quotTheObjectName&amp;quot)اگر از cout به جای qInfo استفاده میکردیم خروجی به صورت زیر میشدThis is a QObject class -&gt;0x6d16fff790برای شروع بهتره با یکی از کلاس های اصلی Qt آشنا بشیم، در Qt کلاسی وجود داره به اسم QObject که بسیاری از کلاس های Qt از این کلاس ارث‌بری کردند و قابلیت هایی رو برای ما محیا میکنه.حالا برگردیم سراغ قابلیت های QObjectDestructor of a parent object destroys all child objectsبه constructor کلاسی که ساختیم دقت کنید، میبینید که به عنوان ورودی میتونید یک QObject پدر پاس بدید، ساختار QObject ها میتونه به صورت یک درخت باشه که بعد از از بین رفتن QObject پدر تمام QObject های فرزند نیز از بین میروند.بیاید برای کلاس بالا یک destructor بنویسیم و کنترل کنیم که کی شی ساخته میشه و کی از بین میرهپس بالا رو به صورت زیر تغییر میدیمcharacter.h#ifndef CHARACTER_H
#define CHARACTER_H

#include &lt;QObject&gt;

class Character : public QObject
{
    Q_OBJECT
public:
    explicit Character(QObject *parent = nullptr);
    ~Character();
};

#endif // CHARACTER_Hcharacter.cpp#include &lt;QDebug&gt;
#include &amp;quotcharacter.h&amp;quot

Character::Character(QObject *parent)
    : QObject{parent}
{
    qInfo() &lt;&lt; this &lt;&lt; &amp;quot Created&amp;quot
}

Character::~Character()
{
    qInfo() &lt;&lt; this &lt;&lt; &amp;quot Destroyed&amp;quot
}main.cpp#include &lt;QDebug&gt;
#include &amp;quotcharacter.h&amp;quot
#include &lt;QCoreApplication&gt;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    auto parent = new Character();
    auto child1 = new Character(parent);
    auto child2 = new Character(parent);
    auto child1Child1 = new Character(child1);
    auto child1Child2 = new Character(child1);

    parent-&gt;setObjectName(&amp;quotparent&amp;quot);
    child1-&gt;setObjectName(&amp;quotchild1&amp;quot);
    child2-&gt;setObjectName(&amp;quotchild2&amp;quot);
    child1Child1-&gt;setObjectName(&amp;quotchild1Child1&amp;quot);
    child1Child2-&gt;setObjectName(&amp;quotchild1Child2&amp;quot);

    delete parent;

    qInfo() &lt;&lt; &amp;quotObject deleted!&amp;quot

    return a.exec&#40;&#41;;
}کاری که کردیم این بود که یک destructor برای کلاس درست کردیم و ساخت و از بین رفتن شی رو در کنسول نمایش دادیم.خروجی کد بالا به صورت زیر هستCharacter(0x1ed03bf3ec0)  Created
Character(0x1ed03bfd9a0)  Created
Character(0x1ed03bffc40)  Created
Character(0x1ed03bffed0)  Created
Character(0x1ed03c00430)  Created
Character(0x1ed03bf3ec0, name = &amp;quotparent&amp;quot)  Destroyed
Character(0x1ed03bfd9a0, name = &amp;quotchild1&amp;quot)  Destroyed
Character(0x1ed03bffed0, name = &amp;quotchild1Child1&amp;quot)  Destroyed
Character(0x1ed03c00430, name = &amp;quotchild1Child2&amp;quot)  Destroyed
Character(0x1ed03bffc40, name = &amp;quotchild2&amp;quot)  Destroyed
Object deleted!اگر به جای delete parent بیایم و child1 رو delete کنیم خروجی به صورت زیر میشهCharacter(0x1ed03bf3ec0)  Created
Character(0x1ed03bfd9a0)  Created
Character(0x1ed03bffc40)  Created
Character(0x1ed03bffed0)  Created
Character(0x1ed03c00430)  Created
Character(0x1ed03bfd9a0, name = &amp;quotchild1&amp;quot)  Destroyed
Character(0x1ed03bffed0, name = &amp;quotchild1Child1&amp;quot)  Destroyed
Character(0x1ed03c00430, name = &amp;quotchild1Child2&amp;quot)  Destroyed
Object deleted!بریم سراغ قابلیت دوم QObjectSignals &amp; Slotsفرض کنید قرار هست بازی ای بنویسید که وقتی روی شخصیت های اون کلید میکنیم توابعی صدا زده بشه تا عملیاتی صورت بگیره، به شکل زیر توجه کنیدرخداد کلیک کردن از سیستم عامل به بازی شما میرسه و پس از اون اگر در اون موقعیت شخصیتی وجود داشته باشه به شخصیت میرسه، حال ما میخواهیم اگر این اتفاق افتاد توابعی که در Game پیاده کرده ایم مثل Start Game یا Remove Character صدا زده شود.در این سناریو ما باید یک تابع Signal (مستطیل قرمز) و چندین تابع Slot(مستطیل سبز) تعریف کنیم و Signal و Slot ها رو به هم connect کنیم. برای شروع یک تابع signal داخل کلاس Character که بالا ایجاد کردیم درست میکنیم به صورت زیرcharacter.h#ifndef CHARACTER_H
#define CHARACTER_H

#include &lt;QObject&gt;

class Character : public QObject
{
    Q_OBJECT
public:
    explicit Character(QObject *parent = nullptr);
    ~Character();
    void click();

signals:
    void onCharacterClicked(int characterId);
};

#endif // CHARACTER_Hcharacter.cpp#include &lt;QDebug&gt;
#include &amp;quotcharacter.h&amp;quot

Character::Character(QObject *parent)
        : QObject{parent}
{
    qInfo() &lt;&lt; this &lt;&lt; &amp;quot Created&amp;quot
}

Character::~Character()
{
    qInfo() &lt;&lt; this &lt;&lt; &amp;quot Destroyed&amp;quot
}

void Character::click() {
    emit this-&gt;onCharacterClicked(50);
}در کلاس بالا اومدیم یک signal رو define کردیم و یک تابع click هم تعریف کردیم که داخلش میگیم اگر صدا زده شد signalه  رو emit کن(یعنی منتشر کن این signal رو).بریم سراغ کلاس Gamegame.h#ifndef GAME_H
#define GAME_H

#include &lt;QObject&gt;

class Game : public QObject {

    Q_OBJECT
public:
    Game();

public slots:
    void EndGame();
    void StartGame();
    void RestartGame();
    void RemoveCharacter(int characterId);
};

#endif //GAME_Hgame.cpp#include &amp;quotgame.h&amp;quot
#include &lt;QDebug&gt;

Game::Game() : QObject{}
{
    qInfo() &lt;&lt; this &lt;&lt; &amp;quot Created&amp;quot
}

void Game::EndGame() {
    qInfo() &lt;&lt; &amp;quotgame end!&amp;quot
}

void Game::StartGame() {
    qInfo() &lt;&lt; &amp;quotgame start!&amp;quot
}

void Game::RestartGame() {
    qInfo() &lt;&lt; &amp;quotgame restart!&amp;quot
}

void Game::RemoveCharacter(int characterId) {
    qInfo() &lt;&lt; &amp;quotCharacter &amp;quot &lt;&lt; characterId &lt;&lt; &amp;quot removed from game!&amp;quot
}در این کلاس هم یک سری تابع slot تعریف میکنیم.در این کلاس از QObject دقت کرده باشید دیگه در constructor ورودی parent رو ندادم.بریم کدی برای ارتباط این دو بنویسیمmain.cpp#include &amp;quotgame.h&amp;quot
#include &amp;quotcharacter.h&amp;quot
#include &lt;QCoreApplication&gt;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    auto game = new Game();
    auto character = new Character();

    QObject::connect(character, &amp;Character::onCharacterClicked, game, &amp;Game::RemoveCharacter);

    character-&gt;click();

    return a.exec&#40;&#41;;
}در این کد قصد داریم تا صدا زدن تابع click در character تابع RemoveCharacter در game صدا زده بشه که برای اینکار از تابع connect استفاده کردیم و signal داخل character را به slot داخل game متصل کردیم.خروجی کد بالا به صورت زیر استGame(0x295d7c83f00)  Created
Character(0x295d7c8da50)  Created
Character  50  removed from game!برای درک بهتر شاید تصویر زیر نیز بهتون کمک کنهغیر قابل کپی بودن QObjectنکته نهایی در مورد QObject ها اینکه ما نمیتونیم از QObject ها کپی تهیه کنیم علتش هم به خاطر ساختار پیچیده ای هست که این نوع کلاس داره و همچنین ممکنه Signal و Slot ها بعد از کپی درد سر ایجاد کنند برای همین در جا هایی مثل کد زیر به خطا میخورد که اعلام میکنه constructor کپی از delete شده#include &amp;quotcharacter.h&amp;quot
#include &lt;QCoreApplication&gt;

void test(Character character){
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    auto character = new Character();
    test(*character); // &lt;---------  &#039;QObject&#039; copy constructor has been explicitly marked deleted

    return a.exec&#40;&#41;;
}برای حل مشکل بالا میتونید آدرس Character رو پاس بدید به صورت زیر#include &amp;quotcharacter.h&amp;quot
#include &lt;QCoreApplication&gt;

void test(Character *character){
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    auto character = new Character();
    test(character);

    return a.exec&#40;&#41;;
}شاید یکی از مسائلی که توی زبان های دیگه دیده باشید و داخل cpp یه کم براتون اذیت کننده باشه وجود کلاس List هست، موجودیتی که بتونید بدون مشخص بودن سایز از پیش تعیین شده داده هاتون رو در لیستی ذخیره کنید و یا بتونید یک ایتم از لیست رو به راحتی پیدا کنید.اینجا ما میتونیم از کلاس QList استفاده کنیم که بهمون این امکان رو میده. فرض کنید در مثال قبل قصد داریم در کلاس Game لیستی از Character ها داشته باشیم و متدی برای اضافه و کم کردن و پیدا کردن Character ها داشته باشیمبه نمونه کد زیر توجه کنیدgame.h#ifndef GAME_H
#define GAME_H

#include &lt;QObject&gt;
#include &amp;quotcharacter.h&amp;quot

class Game : public QObject {

Q_OBJECT
private:
    QList&lt;Character*&gt; characters{};

public:
    Game();
    void RemoveCharacterAt(int position);
    void AddCharacter(Character *character);
    Character *FindCharacter(Character *character);

public slots:
    void EndGame();
    void StartGame();
    void RestartGame();
    void RemoveCharacterGame(int characterId);
};

#endif //GAME_Hسه تابع به کلاس اضافه کردیم و یک فیلد که لیستی از character ها رو شامل میشه اضافه کردیمgame.cpp#include &amp;quotgame.h&amp;quot
#include &lt;QDebug&gt;

Game::Game() : QObject{}
{
    qInfo() &lt;&lt; this &lt;&lt; &amp;quot Created&amp;quot
}

void Game::EndGame() {
    qInfo() &lt;&lt; &amp;quotgame end!&amp;quot
}

void Game::StartGame() {
    qInfo() &lt;&lt; &amp;quotgame start!&amp;quot
}

void Game::RestartGame() {
    qInfo() &lt;&lt; &amp;quotgame restart!&amp;quot
}

void Game::RemoveCharacterGame(int characterId) {
    qInfo() &lt;&lt; &amp;quotCharacter &amp;quot &lt;&lt; characterId &lt;&lt; &amp;quot removed from game!&amp;quot
}

void Game::AddCharacter(Character* character) {
    this-&gt;characters.append(character);
}

void Game::RemoveCharacterAt(int position){
    this-&gt;characters.removeAt(position);
}

Character* Game::FindCharacter(Character* character) {
    return this-&gt;characters.at(this-&gt;characters.indexOf(character));
}همون طور که مشاهده میکنید اینجا میتونیم از متد هایی مثل append و remoteAt و at و بسیاری متد دیگه استفاده کنیمهمونطور که اول جلسه اشاره کردم Qt سعی کرده در هر زمینه ای کلاس و متد هایی رو برای راحتی در cpp برای برنامه نویس ها محیا کنه، برای مثال میتونیم از کلاس هایی که برای کار با فایل پیاده شده استفاده کنیمبه کد زیر توجه کنید#include &lt;QFile&gt;
#include &lt;QDir&gt;

int main(int argc, char *argv[])
{
    QFile file{&amp;quottest.txt&amp;quot};

    if(file.open(QIODevice::ReadWrite)) {
        file.write(&amp;quotHello World!&amp;quot);
        file.flush();
        file.write(&amp;quot\r\nAdd Some Text...&amp;quot);
        file.flush();
        file.seek(6);
        file.write(&amp;quot Reza&amp;quot);
        file.copy(&amp;quottest_copy.txt&amp;quot);
        file.remove();
    }

    QDir dir{&amp;quot.&amp;quot};

    for (const auto &amp;item: dir.entryList(QDir::Filter::Files))
        qInfo() &lt;&lt; item;

    return 0;
}در کد بالا یک شی از کلاس QFile درست کردیم و برای خواندن و نوشتن فایل رو باز کردیم، داخل فایل عبارت Hello World! رو نوشتیم و flush کردیم تا اطلاعات بر روی دیسک ذخیره شود(تا زمانی که فایل flush یا close نشه اطلاعات بر روی هارد نوشته نمیشه) بعد از اون یک عبارت دیگه داخل فایل مینویسیم و به موقعیت کاراکتر 6 ام میرویم و کلمه Reza رو مینویسیم و یک کپی از فایل درست میکنیم به اسم test_copy.txt و فایل قبلی رو حذف میکنیم.بعد از اون میخوایم لیست فایل های درون دایرکتوری کنونی رو بدست بیاریم و در کنسول نمایش بدهیم که از تابع entryList استفاده میکنیم و فیلتر روی Files میزاریم.</description>
                <category>AliReza Beigy</category>
                <author>AliReza Beigy</author>
                <pubDate>Mon, 06 Jun 2022 22:22:12 +0430</pubDate>
            </item>
                    <item>
                <title>ارائه TA برنامه نویسی پیشرفته - Git و Regex - جلسه 1</title>
                <link>https://virgool.io/@alirezabeigy/%D8%A7%D8%B1%D8%A7%D8%A6%D9%87-ta-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D9%BE%DB%8C%D8%B4%D8%B1%D9%81%D8%AA%D9%87-git-%D9%88-regex-%D8%AC%D9%84%D8%B3%D9%87-1-pdd2flwqo4rn</link>
                <description>دروداین جلسه میخوایم مطالبی که سر کلاس حضوری صحبت کردیم رو دوباره بهشون اشاره کنیم که بتونید با تامل مطالب رو دنبال کنید.گیت - Gitچرا از گیت استفاده میکنیم؟1. انجام کار تیمی رو راحت تر میکنه و مدیریت پروژه بهتر انجام میشه2. مدیریت نسخه های برنامه برای برنامه نویس محیا میکنه (برای میتونید ببینید برای پیاده سازی ویژگی X چه تغییراتی اعمال شده)برای استفاده از Git باید این برنامه رو از سایت زیر دریافت کنید و نصب کنیدhttps://git-scm.com/downloadsگیت یک ابزار تحت کامند لاین هست که میتونید با اجرای دستوراتی از امکانات اون استفاده کنید.مهمقبل از اینکه وارد توضیحات گیت بشیم بگم که توی این جلسه صرفا سعی میکنیم با دستورات گیت و مفاهیم اون آشنا بشیم و در نهایت خیلی از این دستوراتی که استفاده میکنیم توسط IDE ها به صورت خودکار و به صورت گرافیکی انجام میشه، پس هدف ما یادگیری مفاهیم گیت هست که بدونیم چطور ازش باید استفاده کنیم.فرض کنید ما یک پروژه داریم که صرفا یک فایل main.cpp داخلش قرار دادیم و یک فانکشن ساده رو پیاده سازی کردیم به شکل زیر:main.cppint main() {
    return 0;
}پس پوشه پروژه ما به صورت زیر میشه - MyProject
     - main.cppحالا میخوایم از امکانات گیت توی این پروژه استفاده کنیم، اولین کاری که باید انجام بدیم initialize کردن گیت در پوشه پروژه هست که دستور زیر رو در command prompt در پوشه مربوطه اجرا میکنیم.&gt; git initبا اجرای این دستور فولدری در پوشه پروژتون درست میشه به نام .git که تنظیمات و اطلاعات تاریخچه پروژه شما داخلش با ساختار خاصی ذخیره میشه، به صورت زیرحالا باید با مفهومی آشنا بشیم به نام کامیت (Commit)، زمانی که ما تغییری را در پروژه ایجاد میکنیم باید این تغییرات رو ثبت کنیم و این ثبت تغییرات رو به صورت کامیت در گیت داریم.الان که گیت رو در پوشه پروژه تنظیم کردیم نوبت این هست که تغییرات رو ثبت کنیم، برای ثبت تغییرات از دستور زیر استفاده میکنیم&gt; git commit -m &amp;quotcommit message&amp;quotدستور بالا تغییرات رو با نام خاصی که به هر مجموعه تغییرات میدیم ثبت میکنهفقط یه نکته ای، الان گیت از کجا میدونه من میخوام کدوم تغییرات رو ثبت کنم؟ شاید چندین فایل داشته باشیم و فقط بخوایم یکی از فایل ها تغییراتش ثبت بشه، اینجا مفهومی مطرح میشه به اسم Stage به این شکل که ما فایل هایی که میخوایم تغییراتش رو ثبت کنیم در Stage اضافه میکنیم و دستور commit به stage نگاه میکنه و فایل هایی که داخل Stage هستند رو ثبت میکنه، برای اضافه کردن فایل به stage از دستور زیر استفاده میکنیم&gt; git add main.cppکه میتونی با دستور زیر هر فایل که در پوشه کنونی وجود داره رو به stage اضافه کنیم&gt; git add .حالا میتونیم از طریق دستور زیر تغییراتمون رو ثبت کنیم&gt; git commit -m &amp;quotfirst commit&amp;quotحالا بریم سراغ یه سری امکاناتی که در کنار هم دیگه به ما کمک میکنن تا با گیت بهتر کار کنیمدر گیت مفهومی وجود داره به نام برنچ (Branch) که یک لینک لیست از کامیت ها هست. یعنی شما میتونید یک مجموعه کامیت رو در کنار هم داشته باشید که به اون لیست نامی رو اختصاص بدید.به صورت پیش‌فرض شما در برنچ master قرار دارید و کامیت هایی که میزنید به این لیست اضافه میشه، حالا ممکنه شما نیاز داشتید باشید بعد از یک مدت یک برنچ A از برنچ master ایجاد کنید و از این به بعد تغییراتتون رو داخل برنچ A ثبت کنید.برای شروع بیاید یک برنچ به اسم test ایجاد کنیم و یک تغییر داخل فایل main.cpp بدیم و این تغییر رو ذخیره کنیم، برای ایجاد برنچ جدید باید از دستور زیر استفاده کنیم&gt; git branch testحالا برای اینکه از این به بعد کامیت ها داخل این برنچ ثبت بشه باید داخلش checkout کنید که با دستور زیر میتونیم اینکارو انجام بدیم&gt; git checkout testیه تغییر تو فایل main.cpp بدیم و بریم یه کامیت هم با دستور زیر ثبت کنیم&gt; git add main.cpp
&gt; git commit -m &amp;quotmake a change in test branch&amp;quotحالا میتونید تاریخچه کامیتی که زدیم رو با دستور زیر ببینیم (آپشن های all و graph صرفا برای نمایش بهتر گراف هست)&gt; git log --graph --allتوی این تصویر دوتا مورد هست که بهش اشاره میکنم1f8a715dfaab25b5061f8726ed699c4a534c9d79
1c01aa3da3bde22469dbcadee8aa480b84f5d589عبارت های بالا هش اطلاعات کامیتی هست که ثبت کردیم، در واقع اطلاعاتی شامل مسیج کامیت و تغییراتی که اون کامیت شامل بوده هست.عبارت HEAD نشان دهنده آخرین کامیت برنچ کنونی هست.سوالی که الان پیش میاد اینه که این تغییرات رو چطور با هم تیمی ها به اشتراک بزاریم؟ اینجا مفهومی به نام remote مطرح میشه که ما اعلام میکنیم در کجا ها میخوایم این تغییرات رو آپلود بکنیم.تو گام اول اینکه کجا میتونیم پروژه های گیت رو قرار بدیم باید بگم که برای قرار دادن پروژه میتونیم به پلتفرم هایی مثل github.com و یا gitlab.com مراجعه کنیم، اینها تعدادی از پلتفرم ها هستن، شما میتونید خودتون هم برای خودتون همچین git server هایی بالا بیارید. برای ایجاد remote از دستور زیر استفاده میکنیم، توجه داشته باشید که هر پروژه میتونه چندین remote داشته باشه و توی چندین remote مختلف آپلود بشه&gt; git remote add origin https://github.com/AliRezaBeigy/Testعبارت origin صرفا یه اسم هست برای remote که میتونه هر چیزی باشهبرای شروع آپلود هم از دستور زیر استفاده میکنیم که کامیت ها ما رو اپلود کنه&gt; git pushاگر بار اولی باشه که میخواید push کنید احتمالا باید یک برنج رو به عنوان برنچ پیش‌فرض معرفی کنید&gt; git push --set-upstream origin masterاز اونجایی که ما دوتا برنچ داریم و میخوایم دوتاش رو push کنیم با دستور زیر برنچ test هم push میکنیم&gt; git push origin testحالا پروژه ما داخل Repository ما آپلود شده.برای استفاده حرفه ای تر از گیت بهتره با ویژگی هایی هم آشنا بشیمفرض کنید در حال پیاده سازی تابع جستجو در لیست هستید و تصمیم میگیرید پیاده سازی این تابع رو به زمان دیگه ای موکول کنید، اینجا نیاز دارید تا تغییرات رو داخل فضایی ذخیره کنید، برای این کار میتونید از دستور زیر استفاده کنید&gt; git stash push -m &amp;quotsearch function&amp;quotدستور بالا تغییرات کنونی رو داخل یک پشته ذخیره میکنه و با عملیات های push و pop میتونید تغییرات رو کنترل کنید، برای نمایش لیست stash ها میتونید از دستور زیر استفاده کنید&gt; git stash listبرای برگدوندن تغییرات از stash میتونید از دستور زیر استفاده کنید&gt; git stash pop 0همون طور که اشاره کردیم ما میتونیم تغییرات رو توی برنچ های مختلف ثبت کنیم، این به معنی این هست که فرض کنید شما و دوستتون رضا دارید روی پروژه کار میکنید و شما قراره صفحه A رو پیاده کنید و رضا قراره صفحه B رو پیاده سازی کنه، برای اینکه کار گروهی بهتری داشته باشید بهتره هر کدوم روی برنچ مخصوص اون ویژگی یعنی پیاده سازی صفحه A و صفحه B کار کنیدشما یک برنچ با دستور زیر درست میکنید&gt; git branch page-Aروی اون برنچ checkout میکنید&gt; git checkout page-Aحالا پیاده سازی خودتون رو انجام میدید و تغییراتون رو commit میکنید(بهتره تغییرات خودتون رو در چندین کامیت ثبت کنید)به این مرحله رسیدیم که شما و رضا هر دو تغییرات خودتون رو پیاده کردید و دو برنچ با مجموعه ای از تغییرات دارید، به شکل زیر توجه کنیداینجا ما یک برنچ master داریم که بعد از کامیت دوم دو برنچ page-A و page-B ساخته شده و ابتدا یک کامیت در page-A ثبت شده و بعد از آن یک کامیت در page-B ثبت شده و در نهایت یک کامیت در page-A ثبت شده.نمایی از log هم ببینیمحالا بعد از اینکه کار دو برنچ به پایان برسه باید برنچ ها رو با هم یکسان کنیم و تغییرات رو به برنچ master بیاریم، به همچین عملی مرج(merge) میگیم که میتونیم با دستور زیر اینکار رو انجام بدیم (توجه داشته باشید که باید ابتدا در برنچ master قرار بگیرید و بعد دستور زیر را بزنید تا برنچ مربوطه را با آن مرج کند)&gt; git merge page-Aیه نگاهی دوباره به log بندازیمهمونطور که میبینید الان دو برنچ master و page-A به یک کامیت اشاره میکنندبرای برنچ page-B هم همین دستور رو ثبت میکنیم ولی به یک مشکل میخوریم، برای درک علت مشکل یک نگاهی به تغییرات مثال که مطرح کردم بکنیدpage-Apage-Bبنظرتون گیت توانایی تشخیص و مرج کردن این دو برنچ رو داره؟ چطور میتونه تشخیص بده که باید این دو فانکشن رو در کنار هم قرار بده؟ جواب این هست که نمیتونه و به اصطلاح به conflict میخوره و از شما میخواد که این conflict رو رفع کنید، یه نگاه به اتفاقی که بعد از اجرای دستور زیر میوفته بندازیم&gt; git merge page-Bهمونطور که میبینید گیت یک سری علامت به کد ما اضافه کرده و اعلام کرده در این بخش مشکل در تشخیص داره، حالا نوبت ماست تا این مشکل رو حل کنیموقتی کانفلیکتی رخ میده گیت به فرمت زیر مشکل رو نمایش میده&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD
تغییرات در برنچ کنونی
=======
تغییرات در برنچ موردنظر
&gt;&gt;&gt;&gt;&gt;&gt;&gt; اسم برنچ موردنظرحالا خودمون مشکل رو حل میکنیم و این فرمت هم پاک میکنیم و در نهایت تغییرات رو commit میکنیم.توی مثال قبل شما و رضا روی پروژه کار میکردید اگر رضا تغییراتش رو push کنه شما برای اینکه به تغییرات اون دسترسی داشته باشید میتونید از دستور زیر استفاده کنید تا تغییرات و تاریخچه گیت بروز بشه&gt; git pullعبارات با قاعده - Regexفرض کنید یک متن بزرگ بهتون دادند و گفتن از داخلش IP ها رو استخراج کنید به طور مثال به متن زیر توجه کنیدHello
ALiReza
LMS: address (https://lms.khu.ac.ir)
IP: 127.0.0.1
IP: 127.0.0.2
IP: 192.5.0.3
IP: 127.0.0.4قاعدتا با سرچ کردن . توی یک متن بزرگ نمیشه به IP ها رسید، از اونجایی که از اینکه IP ها شامل چه اعدادی میشن هم اطلاعی نداریم نمیتونیم به راحتی IP ها رو بدست بیاریمراه حل استفاده از عبارات با قاعده یا Regex هست، به این معنی که یک عبارتی بنویسیم که برای کامپیوتر قابل درک باشهبرای شروع من یک عبارت با قاعده خیلی مبتدی مینویسم که IP های داخل متن بالا رو پیدا کنه\d\d\d\.\d\.\d\.\dعبارت بالا از \d استفاده شده که به معنی عدد یا digit هست \. به معنی کاراکتر . هست، عبارت بالا گفتید مواردی رو پیدا کن که سه عدد کنار هم و بعد از آن یک نقطه و یک عدد و یک نقطه و یک عدد و یک نقطه و یک عدد دیده بشهحالا اگه متن رو به صورت زیر تغییر بدیمHello
ALiReza
LMS: address (https://lms.khu.ac.ir)
IP: 127.0.0.1
IP: 127.0.0.2
IP: 192.55.0.3 &lt;- this line changed
IP: 127.0.0.4توی متن بالا Regex قبل نمیتونه 192.55.0.3 رو پیدا کنه چون قسمت دوم از دو عدد تشکیل شده، پس بهتره Regex نوشته شده رو بهبود بدیم تا این دسته از IP ها رو هم پیدا کنه\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}در Regex بالا با استفاده از {1,3} اعلام میکنیم که کاراکتر میتونه 1 تا 3 بار تکرار بشهحالا بیاید استفاده از Regex در کد cpp هم ببینیمبرای استفاده از Regex باید regex را include کنید، بیاید یک نمونه کد ببینیم#include &lt;regex&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;
int main() {
    using namespace std;
    string input = &amp;quotHello\n&amp;quot
                   &amp;quotALiReza\n&amp;quot
                   &amp;quotLMS: address (https://lms.khu.ac.ir)\n&amp;quot
                   &amp;quotIP: 127.0.0.1\n&amp;quot
                   &amp;quotIP: 127.0.0.2\n&amp;quot
                   &amp;quotIP: 192.55.0.3\n&amp;quot
                   &amp;quotIP: 127.0.0.4&amp;quot
    cout &lt;&lt; &amp;quotList Of IP:&amp;quot &lt;&lt; endl;
    regex reg(R&amp;quot(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})&amp;quot);
    smatch matches;
    regex_search(input, matches, reg);
    cout &lt;&lt; &amp;quotMatched Position: &amp;quot &lt;&lt; matches.position() &lt;&lt; endl;
    cout &lt;&lt; &amp;quotMatched: &amp;quot &lt;&lt; matches.str() &lt;&lt; endl;
    return 0;
}در اینجا ما یک شی از کلاس regex ساختیم و از cpp 11 به بعد میتونید آپشن R قبل از string استفاده کنید و راحت تر بدون دوبار \ گذاشتن عبارت با قاعده خودتون رو بنویسید.برای اینکه عبارتی رو از طریق regex پیدا کنید میتونید از متد regex_search استفاده کنید و خروجی آن یک bool برای اینکه متوجه بشید آیا این عبارت در متن پیدا شده یا خیراطلاعات مورد پیدا شده را در smatch ثبت میشه و میتونید از متد هایی مثل position یا str برای دسترسی به اطلاعات مورد پیدا شده استفاده کنیدخروجی کد بالا به صورت زیر میشود:List Of IP:
Matched Position: 55
Matched: 127.0.0.1یک مثال دیگه بزنیم، میخوایم همه IP هایی که قبل اون ها IP: داره رو پیدا کنیمبرای اینکار کافیه Regex رو به صورت زیر تغییر بدیمIP: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}حالا خروجی کد بالا با Regex جدید به صورت زیر میشهList Of IP:
Matched Position: 51
Matched: IP: 127.0.0.1همونطور که میبینید قسمت IP: هم به خروجی اضافه شد، اگر بخوایم فقط قسمت خاصی رو استفاده کنیم از مفهومی به اسم group استفاده میکنیم، به این صورت که قسمتی از عبارت رو که میخوایم داخل پرانتز قرار میدیم و از طریق تابع str و ورودی index میتونیم به group مورد نظر دسترسی داشته باشیم، به کد زیر توجه کنید#include &lt;regex&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;
int main() {
    using namespace std;
    string input = &amp;quotHello\n&amp;quot
                   &amp;quotALiReza\n&amp;quot
                   &amp;quotLMS: address (https://lms.khu.ac.ir)\n&amp;quot
                   &amp;quotIP: 127.0.0.1\n&amp;quot
                   &amp;quotIP: 127.0.0.2\n&amp;quot
                   &amp;quotIP: 192.55.0.3\n&amp;quot
                   &amp;quotIP: 127.0.0.4&amp;quot
    cout &lt;&lt; &amp;quotList Of IP:&amp;quot &lt;&lt; endl;
    regex reg(R&amp;quot(IP: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))&amp;quot);
    smatch matches;
    regex_search(input, matches, reg);
    cout &lt;&lt; &amp;quotMatched Position: &amp;quot &lt;&lt; matches.position() &lt;&lt; endl;
    cout &lt;&lt; &amp;quotWhole Matched: &amp;quot &lt;&lt; matches.str(0) &lt;&lt; endl;
    cout &lt;&lt; &amp;quotIP Matched: &amp;quot &lt;&lt; matches.str(1) &lt;&lt; endl;
    return 0;
}در دستور بالا قسمت IP عبارت رو داخل پرانتز گذاشتیم و با استفاده از ورودی str تونستید group مورد نظر رو انتخاب کنیم(توجه داشته باشید که index صفر به معنی کل عبارت و 1 به معنی گروه اول میباشد)خروجی کد بالا به صورت زیر میشودList Of IP:
Matched Position: 51
Whole Matched: IP: 127.0.0.1
IP Matched: 127.0.0.1حالا اگر متن رو به صورت زیر تغییر دهیمHello
ALiReza
LMSIP: 45.56.53.56 &lt;- this line changed
LMS: address (https://lms.khu.ac.ir)
IP: 127.0.0.1
IP: 127.0.0.2
IP: 192.55.0.3 &lt;- this line changed
IP: 127.0.0.4میخواهیم IP هایی رو پیدا کنیم که قبل از IP: کاراکتر S وجود نداشته باشد، Regex رو به صورت زیر تغییر میدیم[^S]IP: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))در اینجا از [^] استفاده شد که اعلام کردیم قبل از IP: کاراکتر S نباید دیده شود میتوانید عبارتی به صورت زیر بنویسید[^12345678]TESTبه معنی اینکه قبل از TEST هیچ کدام از کاراکتر های 1 تا 8 نباید دیده شود(حواستون باشه به معنی دیده نشدن 12345678 نیست)اگر بخواهیم همه موارد که پیدا میشود در متن پیدا کنیم بهتر از کلاس sregex_iterator استفاده کنیم، به کد زیر توجه کنید#include &lt;regex&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;
int main() {
    using namespace std;
    string input = &amp;quotHello\n&amp;quot
                   &amp;quotALiReza\n&amp;quot
                   &amp;quotLMS: address (https://lms.khu.ac.ir)\n&amp;quot
                   &amp;quotIP: 127.0.0.1\n&amp;quot
                   &amp;quotIP: 127.0.0.2\n&amp;quot
                   &amp;quotIP: 192.55.0.3\n&amp;quot
                   &amp;quotIP: 127.0.0.4&amp;quot
    cout &lt;&lt; &amp;quotList Of IP:&amp;quot &lt;&lt; endl;
    regex reg(R&amp;quot(IP: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))&amp;quot);
    for(sregex_iterator i = sregex_iterator(input.cbegin(), input.cend(), reg);
        i != sregex_iterator();
        i++) {
        const smatch&amp; match = *i;
        cout &lt;&lt; match.str(1) &lt;&lt; endl;
    }
    return 0;
}خروجی کد بالا به صورت زیر هستList Of IP:
127.0.0.1
127.0.0.2
192.55.0.3
127.0.0.4حالا بریم یه Regex بنویسیم که اسم ALiReza رو پیدا کنه، برای اینکار اگر من از عبارت زیر استفاده کنم هیچ موردی پیدا نمیشهalirezaعلتش هم این هست که به صورت پیش‌فرض Regex به بزرگ و کوچیکی حساسه ولی ما میتونیم با فلگ ها(flag) به Regex بگیم که این عبارت به بزرگی و کوچیکی حساس نیست، به کد زیر توجه کنید#include &lt;regex&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;
int main() {
    using namespace std;
    string input = &amp;quotHello\n&amp;quot
                   &amp;quotALiReza\n&amp;quot
                   &amp;quotLMS: address (https://lms.khu.ac.ir)\n&amp;quot
                   &amp;quotIP: 127.0.0.1\n&amp;quot
                   &amp;quotIP: 127.0.0.2\n&amp;quot
                   &amp;quotIP: 192.55.0.3\n&amp;quot
                   &amp;quotIP: 127.0.0.4&amp;quot
    regex reg(R&amp;quot(alireza)&amp;quot, regex::icase);
    smatch matches;
    regex_search(input, matches, reg);
    cout &lt;&lt; &amp;quotMatched Position: &amp;quot &lt;&lt; matches.position() &lt;&lt; endl;
    cout &lt;&lt; &amp;quotMatched: &amp;quot &lt;&lt; matches.str() &lt;&lt; endl;
    return 0;
}خروجی کد بالا به صورت زیر استMatched Position: 6
Matched: ALiReza</description>
                <category>AliReza Beigy</category>
                <author>AliReza Beigy</author>
                <pubDate>Thu, 02 Jun 2022 00:44:02 +0430</pubDate>
            </item>
                    <item>
                <title>راه اندازی محیط برنامه نویسی AVR در محیط ویندوز</title>
                <link>https://virgool.io/@alirezabeigy/%D8%B1%D8%A7%D9%87-%D8%A7%D9%86%D8%AF%D8%A7%D8%B2%DB%8C-%D9%85%D8%AD%DB%8C%D8%B7-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-avr-%D8%AF%D8%B1-%D9%85%D8%AD%DB%8C%D8%B7-%D9%88%DB%8C%D9%86%D8%AF%D9%88%D8%B2-bnaxeusxjsb4</link>
                <description>نیازمندی ها:AVR8 GNU ToolchainGnuWin32.MakeVS Codeنصب و کانفیگ AVR8 GNU Toolchainابتدا Toolchain را از رفرنس اصلی یا مدیافایر دانلود کنیدفایل zip را در مسیری extract کنید، مثلا C:\Program Files\AVRمسیر پوشه bin را در Environment Variable به Path اضافه کنیدنصب GnuWin32.Makeمیتونید مستقیم از SourceForge دانلود و نصب کنید یا از از WinGet استفاده کنید$ winget install GnuWin32.Make مسیر برنامه را در Environment Variable به Path اضافه کنیدC:\Program Files (x86)\GnuWin32\binنصب VS CodeDownload Visual Studio Code - Mac, Linux, Windowsافرونه C/C++ رو نصب کنیدپوشه ای با محتویات مشابه عکس زیر درست کنیدمحتوای فایل c_cpp_properties.json (توجه داشته باشید که اگر Toolchain رو در جایی غیر از مثال ریختید اینجا درستش کنید)محتوای فایل Makefileنمونه کد C++#include &lt;avr/io.h&gt;

int main() {
    while (1) {
        PORTA = 0;
    }
    return 0;
}کامپایل کدبا ورود به terminal (Ctrl + Shift + &#x60;) میتونید با اجرای دستور make خروجی hex و elf و obj برنامتون رو تحویل بگیریددر صورت بروز مشکل توصیه میکنم vs code رو ببندید و باز کنید و دوباره تست کنید</description>
                <category>AliReza Beigy</category>
                <author>AliReza Beigy</author>
                <pubDate>Fri, 01 Oct 2021 00:22:17 +0330</pubDate>
            </item>
                    <item>
                <title>زباله جمع کن (GC) در جاوا</title>
                <link>https://virgool.io/@alirezabeigy/garbage-collector-in-java-n01levqqxgwc</link>
                <description>چند هفته ی پیش استاد برنامه نویسی پیشرفته کلمه ی GC از دهنش در رفت و باعث شد اولین مطلبم در ویرگول رو به این مورد اختصاص بدممقدمه:تا حالا شده فکر کنید ما توی برنامه هایی که می نویسیم خیلی شی هایی که می سازیم رو به حال خودش ول می کنیم و دیگه ازشون استفاده نمی کنیم چی میشن؟؟ آخه حجمی رو از رم رو اشغال کرده ،پس بهتره یه سیستمی وجود داشته باشه که بتونه این اشیای بی استفاده رو شناسایی کنه و جمع شون کنهGC چیست؟در ماشین مجازی جاوا(JVM) یه زباله جمع کن(Garbage Collector) هست که وظیفه ی مدیریت آبجکت های توی حافظه رو داره و آبجکت های بلااستفاده رو پیدا میکنه و اون فضای اشغال شده رو آزاد می کنه، شایان ذکر این فرایند به صورت خودکار در یه ترد کنار برنامه انجام میشه و زمانی که فضای آزاد اختصاص داده شده به برنامه(Heap) به یه حدی برسه این فرایند به صورت خودکار انجام میشهحافظه Heap چیست؟  به قسمتی از حافظه هست که به صورت مجازی برای ذخیره ی داده های برنامه اختصاص داده میشهعکس 1GC چطور کار می کنه؟زباله جمع کن میاد توی حافظه ی Heap میگرده و آبجکت هایی که کسی باهاشون کاری نداره رو حذف می کنهعکس 2توی عکس 2 یه GC Roots هست که در واقع همون طور که می دونید وقتی یه آبجکت جایی استفاده نشده باشه بلااستفاده تشخیص داده میشه پس لازمه که یه سری GC Root هایی وجود داشته باشن تا به این آبجکت ها هویت بدندر اینجا می تونید انواع GC Root های جاوا رو ببینیدالبته به همین سادگی ها هم نیست، در واقع GC میاد یه اسکن می کنه و آبجکت های بلا استفاده رو قبل از حذف به قسمتی مجازی انتقال میده که به اصطلاح بهش میگن Old Generations عکس 3توی زبان های سطح پایین این عملیات رو به صورت دستی باید انجام بدن در حالی که شما دیگه نیاز به همچین کاری نداریدتوی جاوا هم اگه بخواید دستی اینکارو بکنید کافیه اون متغییری که با اون آبجکت در ارتباط هست رو مساوی null قرار بدید و GC رو به صورت دستی با فرا خوانی تابع gc در کلاس System صدا بزنید که البته خود GC به صورت خودکار هم این کارو انجام میدهتابع finalize در جاوا چیست؟همون طور که گفتم GC همون اول دخل آبجکت رو نمیاره و هر موقع بخواد اون از حافظه پاک کنه تابع finalize رو صدا میزنه و شما می تونی این متد رو توی یه کلاس override کنید و بفهمید کی از بین رفته. اینم بگم این متد باعث از بین رفتن آبجکت در مموری نمیشه و فقط مثل یه event عمل میکنه پس فکر اینکه با reflection این متدو صدا بزنید و اون شی رو حذف کنید از ذهنتون بیرون کنیدبا وجود GC در جاوا دیگه نباید نگران مموری باشیم؟سخت در اشتباهید، فرض کنید شما برنامه ی توییتر رو نوشتید توی این برنامه داخل پروفایل افراد باید عکس  ارسال کننده هر پست در حافظه لود بشه و در Image View مورد نظر نمایش داده بشه. نکته ای که اینجا هست اینه که ما توی پروفایل افراد عموما ارسال کننده خود شخصه و یک عکس باید در چند Image View به نمایش در بیاد. نکاتی که در اینجا باید رعایت بشه عبارت است از:عکسی که لود میشه داخل حافظه به اندازه ی View تارگت باید کوچیک شه تا کمترین حجم ممکن در حافظه رو داشته باشهیک عکس رو نباید دو بار در حافظه لود کردبرای مورد دوم باید یه سیستم مدیریت لود عکس بنویسید که اگر عکس قبلی خواست دوباره لود بشه و به جایی رفرس داده بشه باید رفرس آبجکت عکس قبلی رو بهش بدیم و یه آبجکت دیگه توی مموری لود نکنیممورد دیگه ای که باید بهش اشاره کنم فیلد های static هست که مستقیم به یه GC Root مرتبط میشن پس سعی کنید هر شی ای رو static نکنید و اگر می کنید بعد اینکه کارتون باهاش تموم شد null کنیدشرفرنس ها:GC RootsUnderstanding Java Garbage Collection When does Java calls Garbage Collector</description>
                <category>AliReza Beigy</category>
                <author>AliReza Beigy</author>
                <pubDate>Fri, 19 Apr 2019 00:06:26 +0430</pubDate>
            </item>
            </channel>
</rss>