<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>پست‌های انتشارات انتشارات جاواکاپ</title>
        <link>https://virgool.io/javacup/feed</link>
        <description>انجمن جاواکاپ مطالب برنامه‌نویسی مرتبط به آموزش جاوا، نکات جذاب برای برنامه‌نویسان، آموزش بهتر کد زدن و .. را از طریق انتشارات بازنشر می‌کند. آدرس وب‌سایت: www.javacup.ir</description>
        <language>fa</language>
        <pubDate>2026-06-21 02:58:07</pubDate>
        <image>
            <url>https://files.virgool.io/upload/publication/ywpny2g4axq3/ylft5h.png</url>
            <title>انتشارات جاواکاپ</title>
            <link>https://virgool.io/javacup</link>
        </image>

                    <item>
                <title>مقدمه ای بر کَمِل</title>
                <link>https://virgool.io/javacup/%D9%85%D9%82%D8%AF%D9%85%D9%87-%D8%A7%DB%8C-%D8%A8%D8%B1-%DA%A9%D9%8E%D9%85%D9%90%D9%84-baextthcahsp</link>
                <description>در قسمت قبل الگوهای ادغام سازمانی (Enterprise Integration Patterns) را به صورت مختصر معرفی کردیم. در ادامه با یکی از ابزارهایی که برای پیاده سازی این الگوها استفاده می شود، آشنا می شویم.کمل (Apache Camel)، یکی از چهارچوب هایی است که امکان ادغام سرویس های تولید کننده و مصرف کننده را فراهم می کند. این پروژه در اوایل سال 2007 آغاز شده و در حال حاضر به صورت منبع باز و تحت مجوز Apache 2.0 در دسترس قرار گرفته است. جهت بررسی بیشتر، پیشنهاد می کنیم به Camel in Action, Second Edition مراجعه کنید.مقدمهبه صورت کلی کمل این امکان را برای شما فراهم می کند که برای سیستم پیامگرای خود، قواعد مسیریابی تعریف کنید. این قواعد را می توان به صورت زیر بیان کرد اینکه پیام ها:از کدام منبع دریافت شوندبه چه صورت پردازش شوندبه کدام مقصد هدایت شوند همانطور که قبلا هم اشاره کردیم، از چالش های مهم ادغام سرویس ها، پیاده سازی مختلف آن ها است. هر سرویس انتظار دارد که نوع داده خاصی را در پیام ها استخراج کند. همچنین ممکن است از پروتکل های مختلفی پیشتیبانی بکند. کمل با ارائه واسط های مختلف و پیاده سازی حالت های بسیار از آن ها، تا حد ممکن این مشکلات را از توسعه دهنده پنهان می کند. برخی از مهمترین امکاناتی که کمل در اختیار ما قرار می دهد عبارتند از:1. واسط مسیریابیهسته اصلی کمل که امکان انتقال پیام ها را میان اجزاء مختلف با توجه به مسیر های ایجاد شده به وسیله توسعه دهنده فراهم می کند. این مسیرها به وسیله الگوهای ادغام سازمانی (EIP) و زبان واسط (DSL) تنظیم می شوند که در ادامه شرح خواهیم داد.2. کامپوننت های گستردهدر کمل، کتاب خانه گسترده ای از کامپوننت های مختلف ارائه شده که هر کدام برای بهره وری از واسط ها و تبدیل داده استفاده می شوند. کامپوننت ها امکان تعامل با سایر نرم افزار ها را فراهم می کنند.3. مطابق با الگوهای ادغام سازمانیبا وجود اینکه الگوهای ادغام سازمانی EIP مشکلات ادغام و راه حل آنها را توصیف می کند؛ اما آن ها را به صورت رسمی پیاده سازی نمی کند. کمل با ارائه زبانی خاص و مشترک میان همه توسعه دهندگان تلاش کرده تا حد ممکن این شکاف را برطرف کند.4. زبان واسط domain-specific language (DSL)کمل با ارائه زبان واسط تلاش می کند یکپارچگی خاصی در زمینه پیاده سازی الگوهای ادغام سازمانی ارائه بدهد و توسعه دهنده به جای تمرکز بر پیاده سازی این الگوها، بر ارائه راه حل تمرکز کند. این زبان واسط به شکل کد جاوا یا فرمت XML قابل استفاده است:Java DSLXML DSL به منظور سادگی در ادامه از Java DSL استفاده خواهیم کرد. برای شروع پیشنهاد می کنیم مثال کپی کردن فایل از مبدا به مقصدی خاص را از گیتهاب بررسی کنید. معماری کملدر ادامه هر یک از اجزاء معماری کمل را به صورت مختصر بررسی می کنیمCamel ArchitectureCamel contextهمه اجزا را کنار هم قرار داده و امکان اجرای کمل را فراهم می کند. هر مسیر(Route)ی که به وسیله توسعه دهنده تنظیم می شود، به وسیله Camel context نگهداری شده و به بهره برداری می رسد.Routing engineهمان چیزی که پیام ها را میان اجزاء تولید کننده و مصرف کننده انتقال می دهد. Routing engine استفاده ای برای توسعه دهنده ندارد؛ اما خوب است بدانیم که انتقال پیام ها به وسیله آن انجام می شود.Routesمسیرها به وسیله توسعه دهنده تعریف می شوند. یک مسیر ساده می تواند زنجیره ای از پردازش ها را میان مبدا و مقصد داشته باشد که به وسیله Processor ها انجام می شود. در کمل هر مسیر فقط یک مبدا خواهد داشت که تولید کننده و مصرف کنندگان را از یکدیگر مستقل می کند؛ بنابراین حتی اگر به شکل زیر چندین مبدا برای یک مسیر در نظر بگیریم: from(&#039;jms:queue:A&#039;, &#039;jms:queue:B&#039;, &#039;jms:queue:C&#039;).to(&#039;jms:queue:D&#039;);در نهایت کمل آن را به شکل زیر برداشت خواهد کرد:from(&#039;jms:queue:A&#039;).to(&#039;jms:queue:D&#039;); 
from(&#039;jms:queue:B&#039;).to(&#039;jms:queue:D&#039;); 
from(&#039;jms:queue:C&#039;).to(&#039;jms:queue:D&#039;);Processorsاز مهمترین اجزاء کمل که امکان دسترسی به پیام ها و مدیریت آن ها را فراهم می کند. Processor ها می توانند همزمان به صورت تولید کننده و مصرف کننده عمل کنند؛ به گونه ای که هر Processor پیام های پردازش شده به وسیله Processor قبلی خودش را دریافت کند. مثال قسمت قبل را در نظر بگیرید که بخواهیم پیام های دریافت شده از طرف کاربر را ابتدا رمزگشایی کرده و پس از انجام عملیات احراز هویت پیام های اسپم را نادیده بگیریم. این ویژگی به شکل زیر به وسیله Java DSL قابل پیاده سازی می باشد: from(&#039;direct:start&#039;)
.process(decryptionProcessor)
.process(authenticationProcessor)
.process(spamTrashProcessor)
.to(&#039;direct:end&#039;);نحوه پیاده سازی Processor ها در ادامه بررسی خواهیم کرد.Componentsکامپوننت ها امکان تعامل با سایر واسط ها را با وجود پروتکل های گوناگون و فرمت داده متفاوت فراهم می کنند. با استفاده از آن ها می توانید پیام های موجود در یک کارگزار پیام (Message broker) را استخراج کنید یا به یک دیتابیس خاص کوئری بزنید یا حتی رویداد های یک ربات تلگرام را پردازش کرده و نتیجه را برگردانید. به طور خاص کامپوننت ها به وسیله نام خود در URI مورد استفاده قرار می گیرند. به عنوان مثال فرض کنید می خواهیم به فایلی در مسیر خاص دسترسی پیدا کنیم:from(&#039;file:data/inbox&#039;)در این حالت اسم file، در حقیقت FileComponent را مشخص می کند که امکان دسترسی به مسیر data/inbox را فراهم می کند. در کمل کامپوننت های متنوعی تعریف شده اما امکان توسعه کامپوننت جدید هم وجود دارد. کامپوننت ها به عنوان کارخانه ای از Endpoint ها عمل می کنند.Endpointsبه عنوان واسطی میان اجزا و سیستم پیامگرا مورد استفاده قرار می گیرند. تولید کننده و مصرف کننده به وسیله Endpoint، پیام ها را دریافت کرده یا ارسال می کنند. در کمل، پیام ها در حقیقت به صورت یک Exchange میان اجزاء رد و بدل می شوند که به وسیله Endpoint ها مدیریت می شوند. در تصویر فوق فیلد های یک Exchange را مشاهده می کنید. یکی از مهمترین آنها MEP است. یک الگوی تبادل پیام (Message Exchange Pattern) یا به اختصار MEP، نوع پیامگرایی را به صورت یک طرفه یا درخواست پاسخ مشخص می کند. MEP موجود در یک Exchange، مقادیر زیر را میتواند داشته باشد:1. InOnly پیام گرایی یک طرفه. ساده ترین مثال آن می تواند استفاده از یک کارگزار پیام باشد.2. InOutمدل درخواست پاسخ که به عنوان مثال می تواند در HTTP مورد استفاده قرار بگیرد.در مثال فوق می بینید که Exchange هایی که فیلد MEP برابر با InOut دارند، به مصرف کننده بازگردانده می شوند.Routingدر این قسمت نوشتن مسیر در کمل را بررسی خواهیم کرد و بخشی از الگوهای EIP را به وسیله آن پیاده سازی می کنیم.امروزه مسیریابی را می توان در بسیاری از روزمرگی های خودمان مشاهده کنیم. به عنوان مثال، وقتی نامه ای را پست می کنید؛ ممکن است قبل از رسیدن به آدرس نهایی، از چندین شهر عبور کند. ایمیلی که ارسال می کنید؛ قبل از رسیدن به مقصد نهایی از طریق بسیاری از سیستم های شبکه کامپیوتری هدایت می شود. در همه موارد، مسیریاب انتخاب می کند که بسته دریافتی را از چه راهی به مقصد بفرستد.در سیستم های نرم افزاری پیامگرا، مسیریابی فرایندی است که طی آن پیام از یک مبدا دریافت شده و پس از پردازش، با توجه به مجموعه ای از شروط، به مقصد مناسب هدایت می شود. کمل با بهره گیری از الگوهای تعریف شده معماری پیامگرا، امکان توسعه سیستم های مبتنی بر این رویکرد را فراهم می کند. در ادامه مثال هایی از پیاده سازی موارد ساده به وسیله Java DSL را بررسی خواهیم کرد.استفاده از تایمربه عنوان اولین مثال، نشان می دهیم که چگونه پیام خاصی را طی یک بازه زمانی مشخص در خروجی چاپ کنیم.برای تعریف مسیر به وسیله Java DSL لازم است که از کلاس RouteBuilder ارث بری کنیم. این کلاس متد configure را در اختیار ما قرار می دهد که در آن پیاده سازی خودمان را انجام می دهیم:public class MyRouteBuilder extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        from(&#039;timer:foo?period=5000&#039;)
            .transform(simple(&amp;quotHello&amp;quot))
            .log(&#039;${body}&#039;);
    }
}کامپوننت Timer برای ایجاد پیام در یک بازه زمانی مشخص استفاده می شود. این پیام ها به صورت یک رویداد (event) تولید می شوند. در این مثال اسم کامپوننت را foo در نظر گرفته ایم و مقدار بازه زمانی دلخواه را برابر 5 ثانیه قرار داده ایم. در ادامه به وسیله متد transform، پیام Hello را در بدنه ورودی (Body) قرار داده و سپس آن را چاپ می کنیم.همانطور که قبلا هم گفتیم، در کمل تمام مسیرهای تعریف شده به وسیله CamelContext نگهداری می شوند و به بهره برداری می رسند. لذا در متد Main:public final class MyCamelApplication {
    public static void main(String[] args) throws Exception {
        CamelContext context = new DefaultCamelContext();
        context.addRoutes(new MyRouteBuilder());
        context.start();
    }
}توجه داشته باشید که در مثال فوق کمل فرصتی برای چاپ پیام Hello نخواهد داشت زیرا ترد اصلی که به وسیله main ایجاد شده به انتها می رسد. برای حل این مشکل متد main دیگری ایجاد می کنیم:import org.apache.camel.main.Main;

public class MyApplication {
    public static void main(String[] args) throws Exception {
        Main main = new Main(MyCamelApplication.class);
        main.run();
    }
}که به خروجی زیر منجر می شود:استفاده از Processor هاکامپوننت Timer برای هر پیامی که ارسال می کند یک هدر HEADER_FIRED_TIME تنظیم می کند که زمان تولید آن پیام را به شکل روز هفته، ماه، ساعت و سال میلادی نشان می دهد. در این قسمت قصد داریم هدری به هر پیام اضافه کنیم؛ به طوری که روز هفته شمسی (شنبه، یکشنبه و ...) را بیان کند. این کار را به کمک یک پردازه (Processor) انجام می دهیم.ابتدا یک Enum برای مدل کردن روزهای هفته در نظر میگیریم:public enum WeekDays {
    
    Sat(&#039;شنبه&#039;),
    Sun(&#039;یکشنبه&#039;),
    Mon(&#039;دوشنبه&#039;),
    Tue(&#039;سه شنبه&#039;),
    Wed(&#039;چهارشنبه&#039;),
    Thu(&#039;پنجشنبه&#039;),
    Fri(&#039;جمعه&#039;);

    private final String name;

    WeekDays(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}برای پیاده سازی یک پردازه، لازم است که از واسط org.apache.camel.Processor استفاده کنیم. این واسط متدی به نام process فراهم می کند که امکان دسترسی به Exchange دریافتی را می دهد:public class TimerProcessor implements Processor {
    @Override
    public void process(Exchange exchange) throws Exception {
        final Message message = exchange.getMessage();
        final String firedTime = message.getHeader(
                TimerConstants.HEADER_FIRED_TIME, String.class
        );

        WeekDays weekDay = Arrays.stream(WeekDays.values())
                        .filter(weekDays -&gt; firedTime.contains(weekDays.toString()))
                        .findFirst().get();

        exchange.getMessage().setHeader(&#039;dayOfWeek&#039;, weekDay.getName());
    }
}در مثال فوق ابتدا پیام را از Exchange دریافتی استخراج کرده سپس با توجه به محتوای هدر پیام، مشخص می کنیم که کدام یک از روزهای هفته را باید در نظر بگیریم. در پایان نتیجه را به عنوان هدر جدیدی به نام dayOfWeek در پیام قرار می دهیم.برای استفاده از TimerProcessor لازم است که آن را به Java DSL قبلی اضافه کنیم:public class MyRouteBuilder extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        from(&#039;timer:foo?period=5000&#039;)
            .transform(simple(&#039;Hello&#039;))
            .process(new TimerProcessor())
            .log(&#039;${body} on ${header.dayOfWeek}&#039;);
    }
}مشاهده می کنید که کمل امکان دسترسی به هدر و بدنه را در متد log فراهم می کند که منجر به خروجی زیر خواهد شد:استفاده از Message Routerدر قسمت الگوهای پیامگرایی دیدیم که مسیریاب پیام، فیلتری است که می تواند با استفاده از هدر های یک پیام، آن را به خروجی مناسب هدایت کند. در این بخش مثال قبل را توسعه می دهیم به گونه ای که پیام هایی که در روز زوج ساخته شده باشند به یک صف خاص، و روزهای فرد برای صف دیگر هدایت شود.public class MyRouteBuilder extends RouteBuilder {

    private static final String DAY_OF_WEEK = &#039;dayOfWeek&#039;
    private static final String EVEN_QUEUE = &#039;direct:even&#039;
    private static final String ODD_QUEUE = &#039;direct:odd&#039;
    private static final String ANOTHER_QUEUE = &#039;direct:another&#039;


    @Override
    public void configure() throws Exception {
        from(&#039;timer:foo?period=5000&#039;)
            .transform(simple(&#039;Hello&#039;))
            .process(new TimerProcessor())
            .choice()
                .when(exchange -&gt; {
                    final String day = exchange.getMessage().getHeader(DAY_OF_WEEK, String.class);
                    return day.contains(WeekDays.Sat.getName()) ||
                           day.contains(WeekDays.Mon.getName()) ||
                           day.contains(WeekDays.Wed.getName());
                }).to(EVEN_QUEUE)
                .when(exchange -&gt; {
                    final String day = exchange.getMessage().getHeader(DAY_OF_WEEK, String.class);
                    return day.contains(WeekDays.Sun.getName()) ||
                            day.contains(WeekDays.Tue.getName()) ||
                            day.contains(WeekDays.Thu.getName());
                }).to(ODD_QUEUE)
                .otherwise().to(ANOTHER_QUEUE)
            .end()
            .log(&#039;${body} on ${header.&#039; + DAY_OF_WEEK + &#039;}&#039;);
        
            // We have to process all queues in our messaging system
           from(EVEN_QUEUE).process();
           from(ODD_QUEUE).log(&#039;I\&#039;ll be processed before logging body and header&#039;).process();
           from(ANOTHER_QUEUE).process();
    }
}مشاهده می کنید که پیام ها با توجه به مقدار هدر DAY_OF_WEEK، به یکی از کامپوننت های direct:even، direct:odd یا direct:another هدایت می شوند. کامپوننت direct، امکان فراخوانی سنکرون برای پردازش پیام ها را فراهم می کند؛ به عبارت دیگر تا زمانی که پیام به وسیله زیر مجموعه های آن direct پردازش نشود؛ سراغ کامپوننت های دیگر نخواهد رفت. در ادامه پیام های دریافتی از هر یک از صف ها را به طور نمونه پردازش خواهیم کرد که منجر به خروجی زیر خواهد شد: direct componentبرخلاف direct، کامپوننت SEDA امکان فراخوانی آسنکرون را فراهم می کند؛ لذا با تغییر نام direct به seda خروجی به شکل زیر غیر قابل پیش بینی خواهد بود:seda componentاستفاده از Message brokerدر ادامه پیام های تولید شده به وسیله تایمر را به یک کارگزار پیام ارسال می کنیم. در این مثال ما از ActiveMQ استفاده می کنیم؛ بنابراین وابستگی مربوط کامپوننت آن را به پروژه خود اضافه می کنیم:&lt;dependency&gt;
  &lt;groupId&gt;org.apache.camel&lt;/groupId&gt;
  &lt;artifactId&gt;camel-activemq&lt;/artifactId&gt;
&lt;/dependency&gt;همچنین برای اتصال به ActiveMQ:&lt;dependency&gt;  
    &lt;groupId&gt;org.apache.activemq&lt;/groupId&gt;  
    &lt;artifactId&gt;activemq-all&lt;/artifactId&gt;  
    &lt;version&gt;5.15.2&lt;/version&gt; 
&lt;/dependency&gt; 
حال ابتدا کامپوننت مورد نیاز را به Camel context اضافه می کنیم:var connectionFactory = new ActiveMQConnectionFactory(&#039;vm://localhost&#039;);
var context = new DefaultCamelContext(); 
context.addComponent(
    &#039;amq&#039;,    
    JmsComponent.jmsComponentAutoAcknowledge(connectionFactory)
); 
در اینجا برای اتصال به ActiveMQ از شی connectionFactory استفاده کرده ایم. ورودی vm://localhost امکان استفاده از یک Embedded broker را فراهم می کند. درنهایت پیام ها را به صف sample ارسال می کنیم:from(&#039;timer:foo?period=1000&#039;)
.transform(simple(&#039;Hello&#039;))
.to(&#039;amq:queue:sample&#039;);پیوند های مفیدایجاد پروژه اولیه کمل با توجه به وابستگی های مشخص شده: Kameleonلیستی کامل از کامپوننت های کمل: Componentsمثال هایی از پیاده سازی الگوهای سازمانی با استفاده از کمل: Camel-Enterprise-Integration-Patterns</description>
                <category>انتشارات جاواکاپ</category>
                <author>محمد سپهر ملائی</author>
                <pubDate>Fri, 26 Aug 2022 11:26:32 +0430</pubDate>
            </item>
                    <item>
                <title>مقدمه ای بر الگوهای ادغام سازمانی</title>
                <link>https://virgool.io/javacup/%D9%85%D9%82%D8%AF%D9%85%D9%87-%D8%A7%DB%8C-%D8%A8%D8%B1-%D8%A7%D9%84%DA%AF%D9%88%D9%87%D8%A7%DB%8C-%D8%A7%D8%AF%D8%BA%D8%A7%D9%85-%D8%B3%D8%A7%D8%B2%D9%85%D8%A7%D9%86%DB%8C-ljct3rwtqyxu</link>
                <description>پیامگرایی (Messaging) از جمله رویکردهایی هست که برای ارتباط بین میکروسرویس ها استفاده می شود و همچنین الگوهای ادغام سازمانی (Enterprise Integration Patterns) به اختصار EIP، به الگوهای طراحی اشاره می کنند که برای ادغام نرم افزار هایی استفاده می شود که از رویکرد Messaging استفاده می کنند.کتاب الگوهای ادغام سازمانی به طور ویژه رویکرد Messaging را بررسی میکنداصطلاح EIP دقیقا برگرفته از کتابی با همین نام است که اولین بار در سال 2003 منتشر شد. در این کتاب راهکارها و استاندارد های مختلفی برای طراحی سیستم های پیامگرا پیشنهاد می شود و سپس یک پیاده سازی ابتدایی برای آن ها ارائه می شود. در ادامه برخی از این الگوها و استاندارد ها را معرفی می کنیم.جهت بررسی بیشتر می توانید به enterpriseintegrationpatterns.com مراجعه کنید.مقدمهفارغ از مزایایی که میکروسرویس ها می توانند برای ما داشته باشند، ادغام آنها چالش های زیادی برای ما دارد که برخی از مهمترین آنها عبارتند از:هر نرم افزاری پیاده سازی مخصوص به خودش را دارد: ادغام سرویس ها به دلیل نوع پیاده سازی مختلف آنها (زبان برنامه نویسی، معماری و ...) چالش های مخصوص به خودش را خواهد داشت. یک الگوی ادغام نرم افزار، باید واسط مناسبی برای از بین بردن تفاوت بین نرم افزار ها ارائه کند.تغییر در نرم افزار اجتناب ناپذیر است: نرم افزار به طور مداوم درحال تغییر است. اگر یکی از سرویس ها به هر دلیلی تغییر کند می تواند سایر بخش ها را تحت تاثیر قرار دهد. یک الگوی ادغام باید تا حد ممکن وابستگی میان سرویس ها را کاهش دهد.توسعه دهندگان برای غلبه بر این چالش ها از روش های گوناگونی استفاده کردند این کتاب به صورت اختصاصی رویکرد پیامگرایی را برای ادغام سرویس ها مورد بررسی قرار می دهد.پیامگرایی (Messaging)برای توصیفی دقیق از پیامگرایی اجازه بدهید مثالی خدمتتون ارائه بدهیم. فرض کنید با یک نفر از دوستان خودتان تماس تلفنی برقرار می کنید. در این حالت ارتباط شما از نوع سنکرون می باشد چرا که تا زمانی که با او مکالمه می کنید، نمیتوانید با شخص دیگری تماس بگیرید. حال فرض کنید به هر دلیل امکان تماس با دوستتان را نداشته باشید یا آنقدر مشغول باشید که نتوانید با او مکالمه کنید. در این حالت شما از طریق ایمیل، پیامی برای او ارسال کرده و کار خودتان را از سر میگیرید. دوستتان هر زمان که خواست، ایمیل خود را چک کرده و پیام شما را می خواند این همان چیزی است که به عنوان ارتباط آسنکرون شناخته می شود. پیام گرایی در حقیقت امکان تعامل آسنکرون میان سرویس های شما را فراهم می کند. هر سرویس پیام خود را در کانال قرار داده و کار خودش را ادامه می دهد بدون آنکه منتظر پاسخ گیرنده بماند.اجزاء اصلی در یک معماری پیامگرا عبارتند از:پیام(Message): که میان سرویس ها رد و بدل می شودکانال(Channel): اتصال میان سرویس هارا برقرار کرده و امکان انتقال پیام را فراهم می کنند کانال ها به وسیله سیستم پیامگرا مدیریت می شودتولید کننده(Producer)مصرف کننده(Consumer)قابلیت های پیام گرایی در حقیقت به وسیله واسط جداگانه به نام Messaging system ارائه می شود که با عنوان (message-oriented middleware (MOM هم شناخته می شود. در این واسط، اقدامات مربوط به مدیریت پیام انجام می شود و وظیفه هدایت پیام از تولید کننده به مصرف کننده را دارد. یک سیستم پیامگرا قابلیت ها و اجزاء متفاوتی دارد که خدمت شما شرح خواهیم داد.در حالت کلی برای انتقال داده در یک معماری پیامگرا:آنچه در یک معماری توزیع شده پیامگرا می گذردساخت: تولید کننده پیام را ایجاد و داده مورد نظر خودش را در آن قرار می دهد.ارسال: تولید کننده پیام را به کانال انتقال می دهد.تحویل: سیستم پیام گرا با مدیریت پیام دریافتی، آن را به مصرف کننده هدایت کرده و از دریافت آن اطمینان حاصل می کند.دریافت: دریافت کننده پیام را از کانال می خواندپردازش: دریافت کننده داده را از پیام استخراج کرده و آن را پردازش می کند.Messaging systemهمانطور که اشاره کردیم Messaging system در حقیقت مانند واسطی میان تولید کننده و مصرف کننده عمل می کند و مدیریت پیام ها را بر عهده دارد. در یک Messaging system باید قابلیت های زیر را وجود داشته باشد:کانال (Message Channel)پیام ها به دلایل مختلف و بین سرویس های متفاوت رد و بدل می شود. سرویس مقصد، قابلیت دریافت هر پیامی را ندارد زیرا برای هر کاربردی ساخته نشده است. سرویس پیامگرا مجموعه ای از اتصالات را دارد که برنامه های کاربردی را قادر می سازد با انتقال اطلاعات به روش های از پیش تعیین شده و قابل پیش بینی ارتباط برقرار کنند. در حقیقت سرویس ها از طریق کانال با یکدیگر ارتباط برقرار می کنند به طوری که تولید کننده داده را متناسب با نوع استفاده، در کانال مناسب قرار داده و مصرف کننده آنها را به همان شکلی که انتظار دارد از کانال می خواند. هر کانال برای کاربرد ویژه ای استفاده می شود.پیام (Message)سرویس ها برای تعامل با یکدیگر پیام رد و بدل می کنند. یک پیام از دو بخش اساسی تشکیل شده است:هدر (Header): اطلاعاتی که توسط سیستم پیامگرا استفاده می شود و داده های در حال انتقال، مبدا، مقصد و غیره را توصیف می کند.بدنه (Body): به طور کلی بدنه صرفا برای مصرف کننده در نظر گرفته می شود و سیستم پیامگرا در آن نقشی ندارد.ترتیب پذیری (Pipes and Process)در بسیاری از شرایط ممکن است که یک پیام به مجموعه ای از عملیات برای پردازش نیاز داشته باشد. فرض کنید پیامی از جانب کلاینت برای سرویس ما ارسال می شود. ما ابتدا باید آن را رمزگشایی کرده سپس عملیات احراز هویت برای آن مشتری را انجام داده و در نهایت با حذف پیام های تکراری و اسپم کار خودمان را ساده تر کنیم. اولین راه حل این است که تمام این نیازمندی ها را به صورت یکجا پیاده سازی کنیم. اما انعطاف پذیری را از دست می دهیم، امکان استفاده مجدد را نداریم و همچنین برای آزمون نرم افزار، دچار مشکل می شویم. راه حل دیگر این است که هر کدام از این نیازمندی ها را در مؤلفه های جداگانه پیاده سازی کنیم. با این وجود مشکل ما به طور کامل حل نمی شود. به عنوان مثال، در نظر بگیرید که مولفه احراز هویت برای عملکرد درست نیاز دارد تا پیام را به صورت رمزگشایی شده دریافت کند. در این شرایط مجبوریم مولفه ها را به صورت ترتیبی از مراحل پشت سرهم، ترکیب کنیم.یک سیستم پیامگرا باید این امکان را فراهم کند تا بتوانیم یک پردازش بزرگ را در قالب مجموعه ای از پردازش های کوچکتر (Process) و به صورت پشت سرهم (Pipe) انجام دهیم.مسیریابی (Message Router)مسیریاب پیام را در حقیقت می توان فیلتری در نظر گرفت که پیام را از کانال ورودی دریافت کرده و با توجه به مجموعه ای از شروط مشخص می کند که آن را برای کدام یک از کانال های خروجی هدایت کند. گفتیم که هر پیام علاوه بر بدنه می تواند مجموعه ای هدر ها را هم داشته باشد که یکی از مهمترین کاربرد آن ها در این قسمت می باشد. مسیریاب از این هدر ها استفاده کرده و آن را برای کانال مشخصی ارسال می کند.تبدیل کننده پیام (Message Translator)گفتیم که یکی از چالش های مهم ادغام میکروسرویس ها، پیاده سازی مختلف آنهاست. هر سرویس برداشت متفاوتی از &lt;&lt;مشتری&gt;&gt; خواهد داشت و به شکل جداگانه ای آن را پیاده سازی می کند. در این شرایط باید داده دریافتی را به شکل صحیح برای سرویس گیرنده تبدیل کنیم.تبدیل کننده پیام در حقیقت فیلتر مخصوصی است که داده دریافتی را به فرمت قابل قبول برای گیرنده تبدیل می کند.نقطه پایان (Message Endpoint)سرویس و سیستم پیامگرا دو مفهوم جداگانه هستند. سیستم های پیامگرا را می توان در حقیقت به عنوان یک سرور در نظر گرفت که وظیفه آن صرفا مدیریت پیام ها و هدایت آن ها به سمت مقصد می باشد. در حالی که سرویس چیزی از مفهوم پیام نمی داند و صرفا با داده خاصی کار می کند که از پیام استخراج می شود. سرویس ها در حالت عادی نمی دانند که چگونه از سیستم پیامگرا استفاده کنند. Message Endpoint در حقیقت واسطی است که به سرویس امکان بهره برداری از سیستم پیامگرا را می دهد. سرویس با استفاده از نقطه پایان، پیام ها را به کانال ارسال می کند یا از آن دریافت می کند.نگاهی جزئی تردر این قسمت برخی از خصوصیات بخش قبل را به صورت دقیق تر بررسی می کنیمکانال هادر حالت کلی کانال ها به به دو شکل میتوانند باشند:کانال همتا به همتاهمتا به همتا(Point to Point): در این نوع از کانال ها معمولا تعامل میان یک تولید کننده و یک مصرف کننده صورت می گیرد. در صورتی که چندین مصرف کننده بخواهند همزمان از کانال همتا به همتا استفاده کنند، در این صورت هر پیام داخل کانال فقط به وسیله یکی از مصرف کننده ها استفاده می شود.کانال پخشیپخشی(Publish-Subscribe): این نوع کانال معمولا به وسیله یک تولید کننده و چندین مصرف کننده استفاده می شود. هر مصرف کننده در حقیقت یک کپی از پیام داخل کانال را دریافت می کند.Channel Adapterنقطه پایان (Message Endpoint) واسط میان سرویس و سیستم پیامگرا می باشد و سرویس از طریق آن پیامی را به کانال ارسال می کند. آداپتور کانال در حقیقت برعکس عمل کرده و میان سیستم پیامگرا و سرویس عمل می کند. در یک معماری پیام گرا همه سرویس ها لزوما به وسیله خود شما توسعه داده نمی شود. برای مثال برای کار با یک پایگاه داده خاص یا بهره گیری از واسط های ارائه شده یک نرم افزار دیگر از آداپتور کانال استفاده می شود.سرویس ها به وسیله کانال با یکدیگر ارتباط دارند. سیستم های پیامگرای مختلف برای تعامل از پل پیام استفاده می کند. یک پل پیام در حقیقت از مجموعه ای از آداپتورها استفاده می کند که ارتباط میان سیستم های پیامگرا را تسهیل می کنند. کارگزاران پیام، نظیر ActiveMQ، Apache Kafka یا RabbitMQ به عنوان پل پیام استفاده می شوند.ساخت و ساز پیام در حالت کلی پیام های رد و بدل شده در معماری پیامگرا در سه دسته تقسیم می شوند:پیام فرمان (Command Message): برای فراخوانی روند در سرویس دیگر استفاده می شود. پیام داده (Document Message): داده خاصی را به سرویس دیگر ارسال می کند. مصرف کننده آزاد است که هر کاری با سند دریافتی انجام دهد.پیام رویداد (Event Message): به طور خاص برای کاربرد های آسنکرون استفاده می شود که تولید کننده وقوع رویدادی را به مصرف کننده اطلاع می دهد.  در بسیاری از شرایط نیاز است تا تولید کننده به ازای هر پیام ارسالی، پاسخی از گیرنده دریافت کند. به عنوان یک مثال ساده تولید کننده ای را در نظر بگیرید که از یک سرویس Restful استفاده می کند و طبعا برای هر درخواست به پاسخی نیاز دارد. برای پیاده سازی این حالت در معماری پیامگرا از یک کانال برای درخواست و کانال دیگر برای پاسخ استفاده می شود. نقطه پایان (Message Endpoint)مصرف کننده از طریق نقطه پایان، با سرویس پیامگرا تعامل داشته و پیام ها را دریافت می کند. نقطه پایان ها برای مصرف کننده دو حالت را فراهم می کنند:مصرف کننده رویداد محور (Event Driven Consumer): که به عنوان دریافت کننده آسنکرون هم شناخته می شود. در این حالت مصرف کننده منتظر دریافت پیام بوده و بلافاصله پس از دریافت، آن را پردازش می کند.مصرف کننده خودمختار (Polling Consumer): دریافت کننده سنکرون که برای گرفتن پیام از یک ساختار خارجی استفاده می شود (برای مثال یک پایگاه داده یا استفاده از واسط های نرم افزاری دیگر). در حقیقت  مصرف کننده، هر زمان که بخواهد پیامی را دریافت کرده و آن را پردازش می کند.مدیریت سیستم(System Management)در معماری پیامگرا مدیریت سیستم شامل موارد زیر می باشد: نظارت و کنترلبررسی و تجزیه تحلیل ترافیک پیام آزمون و رفع اشکالدر ادامه ویژگی های هر کدام را به صورت مختصر شرح می دهیمنظارت و کنترلدر حالت کلی، نظارت و کنترل شامل انجام کارهایی است که به منظور بررسی و کنترل یک سیستم پیامگرا انجام می شود. معمولا سیستم های پیامگرا توزیع شده هستند و نیازمند ساز و کاری هستیم که بتوانیم کنترل کاملی بر همه اجزاء داشته باشیم.Control Busگذرگاه کنترل (Control Bus)، امکان مدیریت کل سیستم را برای ما فراهم می کند. این رویکرد در حقیقت از همان مکانیزم کانال برای ارسال پیام استفاده می کند با این تفاوت که از کانال‌های جداگانه برای انتقال داده‌هایی استفاده می‌کند که مربوط به مدیریت اجزای درگیر در سیستم پیامگرا است.Detourدر شرایط خاصی ممکن است نیاز باشد که پردازش های اضافه تری را بر پیام ها انجام بدهیم (مثلا به دلایل رفع اشکال یا بررسی داده هایی که در یک کانال رد و بدل می شوند). در این حالت می توانیم با ایجاد یک انحراف(Detour) در کانال عملیات بیشتری را روی داده ها انجام بدهیم. اینکه مشخص کنیم چه زمانی و کدام پیام ها از کانال انحراف عبور کنند به کمک گذرگاه کنترل انجام می شود. تجزیه و تحلیل ترافیک پیامکانال نقطه به نقطه به طور معمول برای پیام های نوع داده استفاده می شود زیرا همانطور که گفتیم، این اطمینان وجود دارد که هر پیام صرفا به وسیله یک مصرف کننده استفاده می شود. با این وجود برای اهدافی مانند بازرسی پیام ها، آزمون و رفع خطا این کانال ها گزینه خوبی هستند. برای اینکه بتوانیم پیام های یک کانال را به صورت جداگانه بازرسی کنیم، معمولا با ایجاد یک کانال اضافه تر به وسیله Wire Tap، یک کپی از پیام داخلِ کانالِ فعلی، به کانال دیگری هدایت می شود تا بتوانیم حالت فعلی یک پیام را به خوبی بررسی کنیم.وابستگی کم از ویژگی های مهم یک معماری پیامگرا می باشد. مصرف کننده با دریافت پیام نمی داند که دقیقا کدام تولید کننده آن را ارسال کرده و پیام ها ساختار مشخصی داشته و به تولید کننده اش ارتباطی ندارد. این ویژگی به طور خاص رفع اشکال و آنالیز یک سیستم پیامگرا را با چالش هایی مواجه می کند چرا که دقیقا نمی دانیم که یک پیام چه مسیری را برای رسیدن به مقصد طی کرده است. چگونه می‌توانیم جریان پیام‌ها در یک سیستم را به طور مؤثر تجزیه و تحلیل و اشکال‌زدایی کنیم؟ برای حل این مشکل می توانیم در هر سرویس به پیام تاریخچه ای از آن را پیوست کنیم. این اطلاعات در هدر یک پیام ثبت می شود و در نهایت می دانیم که چه اتفاقاتی برای آن پیام در طول مسیر افتاده است.آزمون و رفع اشکالآزمون یک سیستم پیامگرا قبل از استقرار آن مهم است اما نباید صرفا به قبل از استقرار محدود شود. قابلیت پیام آزمون (Test Message) این امکان را برای ما فراهم می کند تا بتوانیم پس از استقرار نرم افزار عملکرد آن را زیر نظر داشته باشیم. در این رویکرد، پیامی صرفا برای بررسی عملکرد مولفه ها میان کانال های مختلف رد و بدل می شود. برای به کار بردن این الگوها نیاز به چارچوبی داریم که آن ها را از قبل پیاده سازی کرده باشد. در قسمت بعد سعی می کنیم یکی از مهمترین ابزارهای این رویکرد را به شما معرفی کنیم.</description>
                <category>انتشارات جاواکاپ</category>
                <author>محمد سپهر ملائی</author>
                <pubDate>Fri, 22 Jul 2022 10:43:05 +0430</pubDate>
            </item>
                    <item>
                <title>درس‌هایی از سیستم‌عامل برای زندگی روزمره: ارسال پیام</title>
                <link>https://virgool.io/javacup/%D8%AF%D8%B1%D8%B3-%D9%87%D8%A7%DB%8C%DB%8C-%D8%A7%D8%B2-%DA%A9%D8%A7%D9%85%D9%BE%DB%8C%D9%88%D8%AA%D8%B1-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%B2%D9%86%D8%AF%DA%AF%DB%8C-%D8%B1%D9%88%D8%B2%D9%85%D8%B1%D9%87-%D8%A7%D8%B1%D8%B3%D8%A7%D9%84-%D9%BE%DB%8C%D8%A7%D9%85-i8aafhcffhc7</link>
                <description>همانطور که از قسمت قبل سری «درس‌هایی از سیستم‌عامل» یادتان هست، در این سری کاربردهای مفاهیمی که در سیستم‌عامل‌ها وجود دارد را در زندگی روزمره بررسی می‌کنیم. در قسمت قبل الگوریتم‌های زمان‌بندی را بررسی کردیم و یاد گرفتیم چه روش‌هایی برای مدیریت زمانمان داریم و چگونه می‌توانیم با الهام از سیستم‌عامل آن‌ها، از زمانمان بهتر استفاده کنیم، مثلا از روش‌های مرسوم زمان‌بندی و اولویت‌بندی استفاده کنیم یا از شیوه‌های پیچیده‌تر مثلا چند صف استفاده کنیم.در این قسمت می‌خواهم منطق‌های پشت ارسال پیام و ارتباط را بررسی کنیم. (از ارسال پیام منظورم همان message passing است.)در سیستم‌عامل چه اتفاقی می‌افتدچرا در سیستم‌عامل نیاز به ارسال و دریافت پیام وجود دارد؟ اصلا مگر چند جزء متفاوت هستند که بخواهند با هم ارتباط برقرار کنند؟ بله در سیستم‌عامل چند جزء متفاوت وجود دارد. هر برنامه‌ای که در حال اجرا می‌بینیم خودش یک (یا بیشتر) پروسس است. یک‌سری پروسس هم  مستقل از برنامه‌های در حال اجرا در پس‌زمینه مشغول سرویس‌دهی هستند. هر پروسس همچنین می‌تواند قسمت‌های هم‌روند متفاوتی داشته باشد، مثلا threadها در جاوا یا گوروتین‌ها. این قسمت‌های هم‌روند به شکل طبیعی بدون ترتیب خاصی و به شکل مستقل اجرا می‌‌شوند اما اگر این‌ها (ترد‌ها و پروسس‌ها) بخواهند برای یک هدف معین فعالیت کنند، باید با هم در ارتباط باشند. مثلا همین مرورگری که این متن را در آن می‌خوانید چند پخش مختلف دارد که برای یک هدف فعالیت می‌کنند. در واقع حداقل یک بخش برای تعامل‌ها با کاربر دارد مثلا فرمان اسکرول را اعمال می‌کند اما بخشی که صفحه را از سرور دریافت می‌کند با بخش اول به شکل هم‌روند و برای یک هدف خاص فعالیت می‌کنند.از کجا فهمیدم این بخش‌ها جدا هستند؟ اگر مرورگر فقط یک بخش پردازشی داشته‌باشد، زمانی که مشغول دریافت اطلاعات از سرور باشد، دیگر به دستورات شما گوش نمی‌کند و اصطلاحا فریز می‌شود اما در واقعیت (با فرض اینکه پیاده‌سازی‌ صحیح و بدون باگی دارد!) اینگونه نیست. شما در حالی یک صفحه دارد لود می‌شود می‌توانید با بخش‌های مختلف رابط کاربری کار کنید و مشکلی هم نباشد یعنی یک بخش مسئول دریافت اطلاعات از سرور است و بخش دیگر مشغول پاسحگویی به فرمان‌های شماست.این بخش‌های جدا احتیاج به ارسال پیام برای همکاری با هم دارند. مثلا اینکه شما روی یک لینک کلیک می‌کنید، بخش تعامل با کاربر باید به بخش دریافت از سرور بگوید که این صفحه را لود کن (و سپس به قسمت رندر کردن خبر بده و .. )(بر حرفه‌ای‌ترها مشخص است که اجزای مرورگر به همین ۲ قسمت محدود نمی‌شود و چندین بخش مختلف وجود دارد ولی این مثال صرفا برای تقریب به ذهن بود.)انواع ارسال پیامدر پاراگراف‌های بالا صحبت از ترد و پروسس به عنوان پخش‌های مختلف پردازشی شد، اما به فرق آن‌ها اشاره نکردم. ترد‌ها در واقع پخش‌های موازی داخل یک پروسس هستند و می‌توان گفت یک پروسس از یک یا چند ترد تشکیل می‌شود. ترد‌ها از نظر سیستم‌عامل یک برنامه محسوب می‌شوند و یک فضای آدرس دارند، یعنی همگی یک حافظه‌ی مشترک داشته‌باشند و اگر آدرسی تخصیص می‌یابد همگی هم می‌توانند هم بخوانند و هم بنویسند. (البته این بستگی به سیاست‌های زبان هم دارد ولی به طور کلی مثلا در جاوا یا سی می‌گویم.) اما فرق پروسس‌ها این است که از نظر سیستم‌عامل دو برنامه جدا هستند (هرچند بخواهند برای یک هدف معین کار کنند) بنابراین سیستم‌عامل اجازه نمی‌دهد به حافظه‌ی هم دسترسی داشته‌باشند و هر کدام فضای آدرس خودش را دارد. فضای آدرس جدا به این معنی است که حتی اگر آدرسی که در برنامه الف، به یک متغیر اشاره دارد را خودمان دستی به برنامه‌ی ب بدهیم، نمی‌تواند به این متغیر دسترسی داشته‌باشد چرا که این آدرس در فضای برنامه‌ی ب معنی ندارد یا معنی متفاوتی دارد. می‌توانید در مورد حافظه مجازی بخوانید. حالا هم ترد‌ها و هم پروسس‌ها نیاز به پیام‌رسانی دارند. تردها که اصلا مربوط به یک پروسس هستند و تحت فضای آدرس یک برنامه اجرا شده‌اند و به یک مموری واحد دسترسی دارند، بنابراین دغدغه‌ی پیام‌رسانی آن‌ها دغدغه سیستم‌عامل نیست، مثل اینکه دو نفر در یک خانه بخواهند زندگی کنند، دیگر دولت/پست درباره پیام‌رسانی آن‌ها کاری انجام نمی‌دهد. برای پیام‌رسانی بین دو ترد هم راه‌های متفاوتی در زبان‌های متفاوت تعبیه شده‌است، مثلا می‌توان یک متغیر (یا همان مقداری حافظه) را به اشتراک گذاشت و با mutex از آن محافظت کرد یا چیزی مثل صف بین آن‌ها برقرار کنیم (مشابه چنل‌ها در گولنگ). حالت صف هرچند در ظاهر اینطور نباشد حالت خاصی از حالت اول است، یعنی مموری یک مموری است حتی اگر قرار باشد به شکل یک صف به آن نگاه کنیم. چنل‌های گو هم همینطوری پیاده شده‌اند. اما پیام‌رسانی بین پروسس‌های متفاوت به سادگی خواندن و نوشتن و مدیریت یک حافظه نیست، چون اصلا حافظه مشترکی ندارند، بنابراین باید سیستم‌عامل راهکاری برای این موضوع ارائه دهد.راه‌های ارسال پیام بین پروسس‌ها در سیستم‌عاملاول بگذارید قضیه را روشن کنم، سیستم‌عامل پیام‌رسان ندارد که بگوییم خب اگر خواستی پیام بدهی به آی‌دی مقصد پیام بده! اما راه حلی که داریم چیزی در همین حدود است!راه اول، حافظه مشترک (shared memory)فرض کنید یک برگه دارید و دو قلم متفاوت، یکی دست شما و یکی دست دوست شما. به شما گفته می‌شود که برای برقراری ارتباط با دوستتان از این برگه استفاده کنید. هرجا از آن که دوست داشتید بنویسید و دوستتان هم هر کجا دلش خواست می‌نویسد. برقرار ارتباط کار ساده‌ای نیست چرا که هر مرتبه باید کل صفحه را بررسی کنید و ببینید چه قسمت‌های جدیدی به آن اضافه شده. اصلا هر مرتبه یعنی چه؟ هر چند وقت یکبار باید چک کنید؟ اگر دوست شما هم همزمان مشغول نوشتن بود چی؟راه دوم، صف ارسال پیام (message queue)ارسال و دریافت پیام می‌تواند در قالب بسته‌های اطلاعاتی انجام شود، به پست فکر کنید، دوست شما چیزی برای شما پست می‌کند و بعد به کارهای خودش می‌رسد، مدت زمانی بعد بسته به دست شما می‌رسد بدون اینکه با خود دوستتان کاری داشته باشید یا اینکه نیاز باشد در یک خانه زندگی کنید. بعد شما هم می‌توانید برای دوستتان یک بسته بفرستید و دوستتان هرموقع دلش خواست صندوق ورودی‌اش را چک کند.این شیوه نه تنها در پست بلکه در پیام‌رسان‌ها و شبکه‌های اجتماعی انجام می‌شود و بسیار در زندگی واقعی پرکاربرد است، فقط محدودیتی که وجود دارد این است که اگر شما هنوز پیام قبلی دوستان را باز نکرده‌اید آیا اون باز هم می‌تواند پیام بفرستید؟ اگر باز هم باز نکردید چی؟ صندوق ورودی شما چند تا باید جا داشته باشد؟ اگر آن هم پر شود پیام ها دور ریخته شود یا دوستتان بابت زیاد پیام فرستادن دستگیر شود (مثلا دیگر نتواند به شما پیام بفرستد یا به دید کامپیوتر پروسس بلاک/ترمینیت شود)شاید بگویید این هم یک حالت خاص از بالایی است، بلکه هست اما بسیار محدود تر، یعنی شما فقط می‌ توانید چیزی داخل صف بنویسید اما اینکه کجای حافظه‌ی مشترک (بافر) نوشته شود به عهده پست‌چی یا همان سیستم‌عامل است.راه سوم: جویبار داده اگر کاربر لینوکس باشید حتما از pipe استفاده کرده‌اید، مثلا cat a.txt | grep salam این خط یعنی محتوای a.txt  را چاپ کن (دستور cat) و خروجی آن را به ورودی grep لوله‌کشی کن، در این حالت هرخطی که از stdout دستور cat خارج شود، وارد stdin دستور grep می‌شود. با این روش حتی برنامه‌هایی که خودشان برای همکاری طراحی نشده‌اند ولی از ورودی و خروجی استاندارد استفاده می‌کنند را می‌توانید به هم متصل کنید تا تحت یک هدف واحد کار کنند، در واقع به عنوان کاربر برنامه‌ها را متحد کنید نه به عنوان برنامه‌نویس. البته این حالت باز هم حالت خاص از حافظه‌ی مشترک است اما به شکلی عملی‌تر، در واقع بدون نیاز به هیچ کانفیگ خاصی با حداقل کد (یک علامت پایپ |) می‌توانید اتصال دو برنامه را برقرار کنید. در این حالت هم مشکل اندازه بافر وجود دارد چرا که ممکن است برنامه‌ی تولید کننده بسیار سریع تولید کند ولی برنامه‌ی مصرف کننده در مصرف سریع نباشد، در این بین اطلاعات باید بافر شوند. لینوکس اندازه‌ی این بافر را عددی مثل ۶۴ کیلوبایت می‌گیرد. در حالتی که هم بافر پر شود تولید کننده صبر می‌کند تا مصرف کننده مقداری مصرف کند.ارسال از طریق شبکهاین راه، عمومی‌تر از ارتباط داخل یک سیستم‌عامل است و می‌توانیم با آن به سراسر جهان (اگر فیلتر و تحریم نباشد البته) مسیج ارسال کنیم، مثلا همین مطلب را از طریق شبکه از سایت ویرگول دریافت کرده‌اید! اما داخل یک سیستم هم می‌توان با باز کردن سوکت به localhost یا 127.0.0.1 و مشخص کردن پورتی که برنامه‌ی دیگر روی آن گوش می‌کند یک کانکشن باز کرد، این روش البته سربار شبکه را دارد اما در اکثر سیستم‌عامل ها جواب می‌دهد و برای همین جذابیت خاص خودش را دارد.در زندگی واقعی مثل این است که یک بسته پستی را با پست بین‌الملل برای یک نفر در کشور خود بفرستید، بله هزینه احتمالا بیشتر می‌شود ولی اگر کشور شما سامانه پست ندارد (سیستم‌عاملتان) این روش می‌تواند جوابگو باشد.روش‌های دیگرالبته خلاقیت بشر و روش‌ها نامحدودند! در ویکیپدیا می‌توانید چند مورد آن را بخوانید، اگر دوست داشتید در کامنت‌ها به راه‌هایی که من اشاره نکرده‌ام اشاره کنید.  https://en.wikipedia.org/wiki/Inter-process_communication منابع خواندنی دیگر: https://www.cs.princeton.edu/courses/archive/fall16/cos318/lectures/11.MessagePassing.pdf  https://www.mtholyoke.edu/courses/dstrahma/cs322/ipc.htm </description>
                <category>انتشارات جاواکاپ</category>
                <author>روزبه شریف‌نسب</author>
                <pubDate>Thu, 02 Sep 2021 20:15:19 +0430</pubDate>
            </item>
                    <item>
                <title>مدل آبشاری(waterfall) و چابک(agile) در توسعه نرم افزار</title>
                <link>https://virgool.io/javacup/%D9%85%D8%AF%D9%84-%D8%A2%D8%A8%D8%B4%D8%A7%D8%B1%DB%8Cwaterfall-%D9%88-%DA%86%D8%A7%D8%A8%DA%A9agile-%D8%AF%D8%B1-%D8%AA%D9%88%D8%B3%D8%B9%D9%87-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-ldirdghrnejc</link>
                <description>از اونجایی که متد های توسعه این روزا خیلی هارو سردر گم کردن و تو اکثر آگهی ها اون پایین مایینا نوشتن &quot;آشنا با اجایل&quot;، تصمیم گرفتم یه مقاله مختصر بنویسم و این اصطلاحات رو براتون باز کنم تا بهتر درکشون کنید.اصلا متدی که میگیم چی هست ؟منظور فرایند یا چرخه حیات تولید نرم افزار هست. هر تیمی بسته به شرایط، منابع، جغرافیا و کلی دلیل دیگه به روش خاصی برای توسعه محصولات خودش انتخاب میکنه.برای مثال تیمی که منابع مالی محدودی داره در مقایسه با تیمی که منابع مالی زیادی داره روش متفاوتی رو پیش میگیره تا بتونه محدودیت هارو نادیده بگیره.یا تیمی که تو شهر ظلم آباد از کشور ناکجا آباد داره کار میکنه مسلما روش متفاوتی در مقایسه با تیمی که تو نیویورک کار میکنه داره.بطور کلی به این روش ها، فرایند یا متد یا مدل های توسعه گفته میشه.چند تا مدل توسعه وجود داره ؟مدل و فرایند تا دلتون بخواد داریم ( اصلا کی به کیه خودمون هم میتونیم یه متد بصورت کاملا دیمی خلق کنیم و با همون پیش بریم :) ولی یه سری از این متد ها و فرایند ها هستن که خیلی معروف هستن و تیم های زیادی باهاشون کار میکنن. مثل scrum, kanban, agile, scrumban, lean, XP, waterfall, PMBOK و ... .اگه بخوایم همه این متد های توسعه رو بچپونیم تو مقاله فکر نکنم کسی حوصله کنه و تا ته اسکرول کنه :)از این گذشته تو کشور خودمون ایران هم همه این متد ها مرسوم نیستن و معروف ترین ها همین متد های مرتبط با اجایل و مدل آبشاری هستن که قراره این موارد رو بررسی کنیم در ادامه. آبشاری (WaterFall)مدل آبشاری که بهش linear-sequential هم گفته میشه، میشه گفت قدیمی ترین و اولین مدل فرایندی معرفی شده هست. تو این مدل توسعه، همه چیز بصورت یک جریان خطی رو به پایین وجود داره (مثل یه آبشار). یعنی چی ؟این مدل شامل چند فاز توسعه مختلف هست که هر کدوم تو یه بخشی از این مسیر به اصطلاح آبشار قرار دارن و فرایند طوری هست که هر فاز باید تموم بشه تا به فاز بعدی برسیم. هیچ ارتباطی هم بین این فاز ها وجود نداره این وسط.به عکس زیر توجه کنید :مراحل و فاز های مدل آبشاریهمونطور که تو عکس هم میبینید، ما از فاز بررسی نیازمندی ها باید شروع کنیم و به ترتیب بیایم و برسیم به آخر خط تا بتونیم محصول خودمون رو ارائه بدیم. دقت کنید که این مراحل یکبار ۰ تا ۱۰۰ برنامه ریزی میشن و تا رسیدن به محصول نهایی قابل بازبینی نیستن.برای مثال اگر شما برنامه نویس سایت باشد، باید کل طرح ui سایت رو که از فاز طراحی به دستتون رسیده کدنویسی کنید و تحویل فاز بعدی بدید.حالا با توجه به این تعریف بریم ببینیم این مدل چه مزایا و چه معایبی داره :مزایای مدل آبشاریساده و قابل فهم: این مدل بیشتر بخاطر سادگی و عدم پیچیدگی که داره انقدر محبوب شده و هنوزم که هنوزه خیلی جاها ازش استفاده میکنن. منظور از سادگی اینه که ما هیچ مفهوم و اصطلاح و نقش سازمانی پیچیده ای نداریم و همه چیز مشخص و قابل فهم هست.سرعت بالا در پروژه های کوچک: این مدل اصلا خوراک پروژه های کوچیکی هست که نیازمندی های اون ها کم و قابل ارزیابیه( مثلا یه سایت معمولی لیندینگ طور ).عدم تداخل فاز ها: همونطور که بالاتر هم گفتم تو این مدل فاز ها هیچ تداخل و همجوشی با هم دیگه ندارن و هر فاز فقط در مرحله خودش انجام میگیره و.مشخص بودن بازه و ملزومات فاز ها: از اونجایی که فاز ها با همدیگه تداخلی ندارن و باعث بروز مشکل توی فاز های دیگه نمیشن، تقریبا میشه زمان دقیق شروع و پایان هر فاز رو تخمین زد و تعیین کرد که چه کار هایی باید داخلش انجام بشه ( با توجه به کار هایی که تو فاز قبلیش انجام شده ).مدیریت ساده: از اونجایی که این مدل قابل درک برای تمام اعضای تیم هست، مدیریت فاز ها و وظایف کار راحت تری هست.معایب مدل آبشاریعدم وجود demo های متعدد برای مشتری: یکی از بزرگترین ایراداتی که این مدل داره اینه که تا وقتی به فاز آخر نرسیم، عملا هیچ پیش نمایشی از محصول برای ارائه به مشتری نداریم.سختی در تغییر نیازمندی ها: اگر مشتری یا هرکس دیگه ای آخر کار یا حتی حین کار خواستار تغییری باشه، اعمال این تغییرات خیلی سخته چون باید برگردیم به فاز اول و دوباره شروع به بررسی کنیم. این کار بصورت غیرمستقیم باعث بروز مشکلاتی که تمامی فاز های بعدی میشه و نیازه که اوناهم تغییر داشته باشن.دیباگ کردن طاقت فرسا: فرض کنیم ما تمام فاز هارو تموم کردیم و نسخه نهایی رو هم پابلیش کردیم و پولمونو هم گرفتیم و رفتیم باهاش بستنی بخوریم. تو همین حین مشتری زنگ میزنه و میگه فلان جای سایتم فلان مشکل رو داره؛ بی زحمت درستش کنید.اینجاست که بستنیه میپره تو گلوتون:) چرا ؟چون دیباگ کردن تو مدل آبشاری به این معنیه که برای اصلاح یه باگ کوچولو باید بریم دوباره از فاز های بالایی شروع به تغییر دادن بکنیم و پله پله بیایم پایین تا برسیم به فاز آخر و نسخه جدیدی رو ارائه بدیم.ناکارآمدی در پروژه های بزرگ و ریسک بالا: همونطور که گفتم تو این مدل هیچ چیز قطعی نیست( حتی بعد از رسیدن به نسخه نهایی، چون ممکنه تغییراتی اعمال بشه ). در نتیجه اصلا توصیه نمیشه برای پروژه هایی که نیازمندی های پیچیده ای دارن و طولانی مدت هستن از این مدل استفاده کنید.خب، این بود مفهوم و مزایا و معایب مدل آبشاری. فکر کنم دیگه براتون جا افتاده باشه کاملا. چابک (Agile)حلقه های تکرار در اجایلاولین چیزی که باید بدونید اینه که اجایل مساوی با اسکرام نیست. خیلیا به اشتباه فکر میکنن اسکرام اسم دیگه ای برای اجایل یا بالعکس هست و این کاملا غلطه.اجایل یک سری اصول و رویکرد های خاص و درواقع به نوع تفکر هست که تو اون، هدف ما تقسیم مکرر و متوالی کار به بخش های کوچیک برای ارائه های سریع و متوالی و در نتیجه جلب رضایت مشتری و پاسخ به تغییراتی هست که مشتری نیاز داره.این تقسیمات باید مدام در بازه های زمانی مشخص و یکسان تکرار بشن که اصطلاحا به این تکرار ها iteration گفته میشه.همون طور که تو عکس بالا مشاهده میکنید، ما یک نمود تصویری از یک iteration داریم که داخلش برنامه ریزی بخش کوچیکی از توسعه و نقشه راه رو وارد میکنیم و بعد از مراحل داخل عکس، اون بخش کوچیک رو عرضه میکنیم.درست مثل یه آشپز که حین پختن غذا، همه مواد غذایی رو یکجا نمیریزه تو ظرف و هر چیزی رو جداگانه آماده و رفته رفته ادغام میکنه و مدام غذا رو مزه میکنه تا مطمئن بشه توی تمامی مراحل پخت، غذا همون چیزیه که باید باشه؛تو اجایل هم ما پروژمون رو بجای اینکه بصورت یکپارچه وصفر و صدی توسعه بدیم، اون رو تو بخش های کویچک  در بازه های زمانی کوتاه مدت توسعه میدیم و بعد از اتمام هر بخش، تست و بررسیش میکنیم و پیش نمایش هایی رو ارائه میدیم تا مطمئن بشیم مورد رضایت مشتری یا ذینفع پروژه هست.تکه تکه پیش بردن مسیر به روایت تصویر :)اصول اجایلارتباط نزدیک و سازنده تمامی افراد و برنامه نویس های تیم باهمدیگه.تعامل موثر و مرتب با مشتری طی فرایند توسعه برای درک بهتر نیازمندی های پروژه و درخواست های مشتری.ارائه نسخه های متعدد حین توسعه پروژه به مشتری برای درک بهتر درخواست ها و نیازمندی ها.پاسخ به تغییرات و پذیرش اونها طی فرایند توسعه.متد های اجایلیهمون طور که گفتیم اجایل فقط یه طرز تفکر هست و نه متدولوژی. اما متد هایی وجود دارن که با همین طرز تفکر زاده شدن و یه جورایی زیرمجموعه ای از اجایل هستن.از معروف ترین متد ها، میشه Scrum رو اسم برد که احتمالا اسمش رو زیاد شنیدید.این متد ها معمولا اصول و ارزش های مشترکی دارن اما یه سری تفاوت هایی هم ممکنه داشته باشن با هم.- متد scrumاسکرام یه متد خیلی کارآمد برای پرداختن به پروژه های پیچیده و دارای نیازمندی های متعدد هست.تمرکز اصلی این متد روی همکاری و تعامل اعضای تیم و ارتباط اونها با همدیگه هست. این تعامل به کمک وجود نقش های مختلف در تیم و جلسات متعددی که تو این متد وجود داره به راحتی دست یافتنی هست.قراره نقش ها و اصطلاحات و فرایند های این متد رو با هم دیگه بررسی کنیم.(یک سری از اصطلاحات، تو متد های دیگه هم وجود داره که همینجا کاملا میپردازیم بهشون) یه نگاهی به این عکس بندازید :سیستم کلی اسکراماصطلاحات:داستان کاربر(user story): تعاریف و توصیف‌هایی شفاف از ویژگی‌های مورد انتظار مشتری هست که ممکنه هم توسط مشتری و هم توسط مدیران پروژه نوشته بشه.برای مثال &quot;امکان سفارش آنلان غذا&quot; یک استوری برای یک پروژه فروشگاهی هست.بک لاگ محصول(product back log): بک لاگ رو میتونیم انباری از داستان ها و کار های در انتظار انجام تصور کنیم که برای تهیه لیست کار های روزمره، به این انبار سر میزنیم و موارد مورد نیاز رو با خودمون برمیداریم و میبریم(اصطلاحا pull میکنیم) و اگر کاری قابل انجام نبود دوباره برمیگردونیمش به انبار(یا push میکنیم).اسپرینت (sprint): به بازه های زمانی شخص که برای توسعه بخش های کوچک و شکسته شده در نظر گرفته میشن، اسپرینت گفته میشه. اسپرینت ها در متد اسکرام، بسته به عواملی ممکنه ۲ هفته الی ۴ هفته طول بکشن.تو این بازه ها هر کدوم از اعضای تیم مسئول انجام کاری هست که بهشون محول شده.بکلاگ اسپرینت (Sprint Backlog): به لیست کارهایی که در طول یک اسپرینت باید انجام داده بشه گفته میشه. این لیست از لیست بک لاگ محصول بیرون کشیده میشه.وظیفه(task): به هر کدوم از آیتم های موجود در بک لاگ اسپرینت که باید توسط تیم انجام بشن task گفته میشه.بُرد(Board): در تمام مراحل کار باید یک بُرد فیزیکی یا دیجیتالی داشته باشیم که اعضای تیم بتونن از وظایف خودشون و بقیه اعضای تیم مطلع باشن و روند کاری و وضعیت فعالیت های خودشون رو بصورت تصویری پیگیری کنن. ورودی های این بُرد همون بک لاگ اسپرینت هست و بعد از شروع اسپرنت همه روزه به روز رسانی میشه.این بُرد ها شامل ستون های مختلفی هستن که ممکنه متغیر باشن تو هر متد یا تیمی و حتی اسامی مختلفی داشته باشن. اما در ساده ترین حالت حداقل سه ستون زیر رو شامل میشن :منتظر انجام یا todo ،در حال انجام یا in progress،  انجام شده یا done.یک نمونه boardتسک های موجود در بُرد ممکنه بسته به اولویت، ستون یا موضوعی که دارن رنگ های مختلفی داشته باشن تا بهتر دسته بندی بشن. همچنین ممکنه یک سری point بر حسب درجه سختیشون داشته باشن.اگر بخوام تصویر بالا رو توضیح بدم :-لیست to do از بک لاگ به بُرد تزریق میشه.-هر شخصی تسک خودش رو از ستون to do وارد ستون in progress یا develop میکنه و شروع به کار میکنه.-بعد از اتمام کار، کد میتونه وارد ستونی به اسم in review بشه که تو این مرحله شخص دیگه ای مسئول مرور کردن این کد ها میشه.-ستون بعدی ستون تست هست که تو این قسمت تستر شروع به تست کردن کار های انجام شده میکنه.در نهایت اگر همه چیز اوکی بود، تسک مورد نظر ادغام میشه و میره تو ستون done. جلسات برنامه ریزی(planning): جلساتی که قبل از شروع هر اسپرینت برگزار میشن و همه افراد تیم به کمک استاد اسکرام، با توجه به اولویت بندی های موجود و زمان و توان انجام، شروع به بیرون کشیدن لیستی از بک لاگ میکنن تا به اسپرینت تزریقش کنن.جلسات سرپایی(Stand up Meeting): همه روزه و معمولا قبل از شروع به کار، جلساتی به مدت ۱۵ دقیقه بین اعضای تیم برگزار میشه که درمورد کار های روز قبل، مشکلات پیش اومده و برنامه کارهای روز جاری صحبت میشه( این جلسات معمولا بصورت ایستاده برگزار میشه ).جلسه گذشته نگر(retro): بعد از اتمام هر اسپرینت، جلسه ای برگزار میشه که تو اون تمامی اعضای تیم درمورد تجربیات، آموخته ها، مشکلات و کمبود هایی که تو اسپرینت به اتمام رسیده داشتن صحبت میکنن.جلسه نسخه نمایشی(demo): این جلسه بسته به پیشنهاد ذینفع یا ذینفعان پروژه و یا درخواست مشتری، هر یک یا چند اسپرینت یک بار برای مشاهده demo یا پیش نمایش از نتیجه اسپرینت های به اتمام رسیده برگزار میشه.نقش ها:اگر شما مشتری بودید که با تیم اسکرام کار میکردصاحب محصول(product owner): به عنوان ذی نفع پروژه و نماینده مشتری، مسئولیت جمع آوری و اولویت بندی بک لاگ ها و تعیین نقشه راه رو داره. همچنین دائما با مشتری در ارتباط هست و feedback هایی رو دریافت و منتقل میکنه.استاد اسکرام(scrum master): شخصی هست که مسئولیت برنامه ریزی اسپرینت و تزریق لیست کار ها،نظارت بر پیشبرد و اتمام به موقع کار ها، اطلاع از کار اعضا و متمرکز کردن اون ها رو به عهده داره.تیم توسعه(develop team): تیمی متشکل از افرادی با تخصص های مختلف که مسئول به تحقق رساندن اهداف اسپرینت هستن. تعداد این اعضا متغیر هست اما معمولا بیشتر از ۱۰ نفر نیستن.هیچ کدوم از این اعضا نسبت به دیگری برتری و رتبه ندارن و همیشه در تعامل سازنده با همدیگه هستن.بررسی فرایند کاری :حالا که کاملا با این اصطلاحات آشنا شدید، میخوام اتفاقات یک اسپرینت رو بصورت خلاصه وار با استناد به عکس بالایی توضیح بدم :-اولین اتفاقی که باید بیفته، جلسه planning هست تا بک لاگ اسپرینت مشخص بشه.-بعد از اون board آماده میشه و تسک ها شروع به پیشروی میکنن و این کار تا انتهای اسپرینت ادامه داره.-هر روز صبح توی جلسات روزانه یا سرپایی درمورد کار های روز گذشته و برنامه روز جاری صحبت میشه.-بعد از اتمام اسپرینت، تو جلسه retro درباره تجربیات اسپرینت تموم شده صحبت میشه.-در صورت نیاز جلسه demo هم با حضور مدیران یا مشتری برگزار میشه و نتایج کار به نمایش گذاشته میشه.بعد از همه این کار ها، دوباره این حلقه از اول تکرار میشه و روز از نو و روزی از نو :):))))حالا که با متد اسکرام آشنا شدیم بریم یه نگاه کوچیکی به دوتا از متد های دیگه‌ی اجایلی داشته باشیم.- متد XPمتدولوژی XP که مخخف عبارت Extreme Programming یا برنامه نویسی مفرط هست.البته گیف بالا شوخیه:) این متد به معنی زیاد کار کردن نیست و با همون طرز تفکر اجایلی و مختص توسعه نرم افزار طراحی شده.این متد از practice های مختلفی که در تصویر بالا هم مشاهده میکنید تشکیل شده که بر نحوه انجام کار ها تاکید دارن. هر حلقه رنگی نشون دهنده گروهی از این practice ها هست که بصورت دوار انجام میگیرن.به چند تا از این practice ها در ادامه اشاره میکنم.تمرکز اصلی متد روی کاهش هزینه های توسعه و افزایش کیفیت محصول، به کمک feedback های دریافتی از طریق practice ها در هر بخشی از کار و پاسخ گویی سریع به نیازمندی های درحال تغییر هست.اگر نقشه راه محصول رو مثل یک جاده پر پیچ و خم در نظر بگیریم، متد XP مثل راننده ماشینی هست که دائما چشم هاش به جاده هست و با هر پیچی سریعا واکنش نشون میده و سریعا فرمون رو میچرخونه.همچنین تو این متد باید تصور کنید زمان نامحدودی در اختیار دارید و دائما در حال refactor کردن کدها، تست نویسی و ارتباط با مشتری و اعضای تیم باشید(مهم کیفیته).عکس زیر به خوبی فرایند کاری و ترتیب مراحل رو تو این متد نشون میده :XP diagramتفاوت متد اسکرام و XP :برخلاف اسکرام، اسپرینت ها تو این متد بین ۱ تا ۲ هفته تنظیم میشن.برخلاف اسکرام، تو این متد برنامه نویسی بصورت جفت یا pair انجام میشه.یعنی برنامه نویس ها، طراح ها و حتی تستر ها بصورت جفت و دوتایی با هم کار میکنن.(این یکی از مهم ترین practice هاست).یه نفر مسئول کد نویسی یا طراحی هست که بهش navigator گفته میشه و نفر دوم مسئول کنترل و ایده پردازی برای نفر کناری هست که بهش observer گفته میشه( البته چند وقت یکبار جای این دوتا با هم عوض میشه ).همچنین این دو نفر مسئول integration testing هم هستن که به معنی تست کردن کار های انجام شده بعد از اتمام کار هست و یکی دیگه از practice ها محسوب میشه.برعکس متد اسکرام، تو این متد اعضای تیم میتونن اسپرینت و بک لاگ اون رو در صورت نیاز تغییر بدن.تو متد اسکرام، تسک هایی که برای بک لاگ اسپرینت از بک لاگ محصول pull میشن رو خود اعضای تیم با نظارت اسکرام مستر مشخص میکنن؛ اما تو این متد این تسک ها رو مشتری با اولویت بندی که داره مشخص میکنه و تیم موظف هست که طبق همون بک لاگ پیش بره و به اهداف برسه.از ویژگی های این متد که خیلی بهش توجه میشه و جزو core practice های اون محسوب میشه، نوشتن تست ها و اجرای اونها قبل و بعد از برنامه نویسی و آزمایش کل سیستم هر چند روز یکبار هست( درکل کیفیت کد ها خیلی مهمه تو این متد و مدام باید مرور و تست بشن و یجورای منظور از &quot;مفرط&quot; همینه ).- متد kanbanاین متدولوژی از اجایل هم بر پایه همون تفکرات و البته فلسفه ی سیستم Just-In-Time شرکت تویوتا بنا شده. کانبان متدی هست که با روش های سخت گیرانه ای که داره باعث مدیریت بهتر گردش کار بین اعضای تیم میشه و کمک میکنه تا لیست کار های روزانه‌ی مشخص و شفافی، بدون multitasking داشته باشیم.همه این ها در کنار هم باعث افزایش بازدهی میشن و از این منظر بسیار مناسب تیم هایی هست که منابع محدودی دارن.نحوه کار و فرایند توسعه تو این متد بسیار نزدیک به متد اسکرام هست و وجوه مشترک خیلی زیادی دارن. اما تفاوت هایی هم دارن که اونها رو از هم جدا میکنه.تفاوت متد اسکرام و کانبان :بجای scrum master که تو اسکرام داشتیم، تو این متد agile coach یا مربی اجایل رو داریم که تقریبا همون نقش رهبر و استاد رو داره.سیستم pull از بک لاگ در این متد تفاوت هایی داره. تو متد اسکرام تسک های داخل برد یکجا وارد میشدن و همه شروع به کار و به عهده کردن تسک ها میکردن( اصلا خود لغت اسکرام اشاره به نوعی بازی فوتبال داره که تو اون همه یهو مثل گیف زیر حمله میکنن به توپ:) ).اما تو متد کانبان ورودی ها محدود هست و همه چیز بستگی به ظرفیت و توانایی تیم داره. برای مثال اگر تیم ما ۴ نفره باشه نهایتا باید ۵ تسک وارد برد بشه(مثلا). تو این متد وقتی یکی از تسک ها به مرحله done برسه از برد خارج میشه و به ستون قبلی خودش سیگنالی میده که موقع تزریق تسک جدید رسیده. اون ستون هم به ستون قبلی خودش سیگنال میده و اینطوری تسک جدیدی از بک لاگ تزریق میشه در لحظه.تو این متد محدودیت ویژه ای برای WIP یا کار های در حال انجام داریم. هر شخص نمیتونه بیشتر از یک محدوده ای تسک(معمولا ۲ تا) در حال انجام داشته باشه.جمع بندی یکم طولانی شد. اما شاید بتونه فقط مفاهیم خیلی پایه از این مواردی که بررسی شدن رو بهتون یاد بده. مواردی که برای یه برنامه نویس یا طراح یا تستر که میخواد تو یه تیم اجایلی کار کنه کافیه؛ اما برای کسی که میخواد یه scrum master بشه نه.این متدولوژی ها و سیستم ها برای خودشون دنیای دیگه ای هستن و کتاب های زیادی برای یادگیریشون منتشر شده. برای مثال اسکرام مستری یا coach بودن به قدری وسیعه که یک شغل حرفه ای محسوب میشه.اگر دوست دارید خیلی عمیق تر این متد ها و سیستم ها رو یاد بگیرید و تبدیل به یه master بشید، پیشنهاد میکنم سمت دوره ها و کتاب های تخصصی برید.اگر خوشتون اومد لایک یادتون نره... اگر هم ایرادی(چه گرامری چه علمی) تو مقاله دیدید خوشحال میشم درجریانم بزارید تا اصلاحش کنم. </description>
                <category>انتشارات جاواکاپ</category>
                <author>beardy developer</author>
                <pubDate>Mon, 02 Aug 2021 18:56:41 +0430</pubDate>
            </item>
                    <item>
                <title>گیت چیه و کجا به کارمون میاد؟</title>
                <link>https://virgool.io/javacup/%DA%AF%DB%8C%D8%AA-%DA%86%DB%8C%D9%87-%D9%88-%DA%A9%D8%AC%D8%A7-%D8%A8%D9%87-%DA%A9%D8%A7%D8%B1%D9%85%D9%88%D9%86-%D9%85%DB%8C%D8%A7%D8%AF-frbn1ylu1fy2</link>
                <description>فرض کنید شما مدیر یک پروژه هستید و تعدادی برنامه نویس تحت نظارت شما همزمان روی یک پروژه کار میکنن. یک هفته از شروع کار گذشته و میخواین کد هایی که برنامه نویس ها نوشتن رو باهم merge کنید. چه مشکلاتی ممکنه داشته باشید؟ حجم کد ها بالا باشه و برای ترکیب کردن اونها به صورت دستی زمان زیادی نیاز باشه که البته احتمال خطا نیز وجو داره ،و یا بخش های مختلفی از چند کد نوشته شده توسط برنامه نویس ها باهم تطابق نداشته باشن و مسائلی از این قبیل...گیت نرم افزار و سیستم کنترل ورژنی هستش که مشکلاتتون رو حل میکنه. در واقع وقتی یک پروژه رو شروع میکنید به گیت دستور میدید که این پروژه رو تحت نظارت خودش قرار بده . بهتون این امکان رو میده که چند شاخه یا به اصطلاح fork برای پروژه تعیین کنید که هر شخص رو شاخه خودش مشغول کد زدن باشه. و هروقت نیاز بود مدیر پروژه با کمک گیت میاد شاخه های مختلف رو باهم merge میکنه.تا اینجا همه چیز معمولیه پس کاربرد اصلیه گیت کجاست؟هر کامیتی (commit) که داخل گیت انجام بشه داخل تاریخچه یا بهتر بگم git log ‌ به صورت اتوماتیک ذخیره میشه ، اونوقت اگر جایی از کد ها تطابق نداشته باشه باهم و یا تغییری تو برنامه ایجاد شده باشه میتونیم بریم سراغ تاریحچه و چک کنیم این تغییر کی و توسط کی انجام شده که اگر مشکلی بود حل کنیم.گیت عمل merge کردن کد ها و یا همون شاخه هارو با دستور git merge به صورت خودکار انجام میده و زمانی به ما ارور نشون میده که ببینه حداقل دو نفر دو تغییر متفاوت در یک خط از کد ایجاد کردن و چون نمیدونه کدوم تغییر باید ثبت بشه به ما ارور نشون میده که بتونیم تغییر نهایی رو براش تعریف کنیم.یکی از جالب ترین ویژگی های گیت به نظرم قابلیت ورژن گذاشتن روی برنامه ست. یک پروژه ای آماده شده و در حال حاضر دارن ازش استفاده میکنن حالا اگر بعد از مدتی بخوایم یک نسخه جدید از برنامه رو آماده کنیم چیکار کنیم که نسخه قبلی از دسترس خارج نشه؟با استفاده از گیت شما میتونین تو هر مرحله ای که میخواین برای برنامتون یک برچسب بزارید فرضا بگید این نسخه ۱.۱.۱ از برنامه ی منه که میخوام رو سرور اجرا بشه. بعد از این برچسب گذاری اگر تغییری در کدتون ایجاد کردید، باز هم به سرور بگید نسخه ۱.۱.۱ رو اجرا کن. گیت میاد کد برنامه رو تا جایی که شما با برچسب زدن براش تعیین کرده بودین رو حفظ میکنه و همون برنامه ی قدیمی رو اجرا میکنه تا زمانی که بهش بگین این تغییرات جدید نسخه ۱.۱.۲ برنامه منه. نکته اینه حتی اگه به طور ناگهانی مشکلی تو نسخه جدیدتون پیش بیاد میتونید به گیت بگید نسخه قبلی رو اجرا کن و اینطوری نسخه ۱.۱.۱ رو سرور اجرا میشه تا وقتی مشکل نسخه جدید حل بشه.شاید براتون سوال پیش بیاد که آیا گیت فقط برای پروژه های بزرگ و کار های تیمی لازمه؟ نه !گیت امکانات خوبی برای منظم و مرتب کردن کد های شما داره و شما میتونید از گیت برای پروژه های شخصیتون هم استفاده کنید. نکته مهم دیگه اینکه گیت فقط برای برنامه نویسی نیست شما میتونید از اون برای پروژه خودتون مثلا نوشتن مقاله ها استفاده کنید. بعد از مدتی پیشرفت پروژتون رو با گیت بررسی کنید.بخاطر تشابه اسمی که وجود داره بعضا پیش میاد که افراد گیت و گیت هاب رو اشتباه میگیرن ، اما گیت هاب تنها یک هاست هستش که برای اشتراک گذاری پروژه ها استفاده میشه و البته که از گیت استفاده میکنه اما دقیقا خود گیت نیست.در حال حاضر بلد بودن گیت نکته مثبتی تو رزومه‌ی کاری شماست.آموزش های متعددی هم براش وجود داره حتی میتونید از داکیومنت های خودش هم استفاده کنید برای یادگیری چون بسیار ساده ست و البته کاربردی.امیدوارم این مقاله کمکی بهتون کرده باشه.روزتون خوش.</description>
                <category>انتشارات جاواکاپ</category>
                <author>پرستو هدایتی</author>
                <pubDate>Mon, 19 Jul 2021 10:51:33 +0430</pubDate>
            </item>
                    <item>
                <title>Git workflow | Centralized workflow</title>
                <link>https://virgool.io/javacup/git-workflow-centralized-workflow-vcniikmnww07</link>
                <description>? مراقب باشیم!زﻣﺎﻧﯽ ﮐﻪ ﻣﺒﺤﺚ workflow ﻣﻄﺮح ﻣﯿﺸﻪ، ﺗﺼﻤﯿﻢ‌ﮔﯿﺮی اﯾﻦ ﻣﻮﺿﻮع ﺧﯿﻠﯽ ﺑﺴﺘﮕﯽ ﺑﻪ ﻓﺮﻫﻨﮓ ﺗﯿﻢ ﯾﺎ culture داره. ﺑﺎ اﺿﺎﻓﻪ ﺷﺪن workflow اﯾﻦ اﻧﺘﻈﺎر ﻣﯿﺮه ﮐﻪ، ﮐﺎراﯾﯽ ﺗﯿﻢ اﻓﺰاﯾﺶ ﭘﯿﺪا ﮐﻨﻪ! ﮔﺮدش ﮐﺎر ﻣﯿﺘﻮﻧﻪ ﯾﻪ مسئولیت اﺿﺎﻓﻪ روی ﺗﯿﻢ اﯾﺤﺎد ﮐﻨﻪ و ﻃﺒﯿﻌﺘﺎ ﮐﺎﻫﺶ productivity در ﺗﯿﻢ و ﻣﺤﺼﻮل رو ﺑﻬﻤﺮاه داره.انتخاب استراتژیبرای انتخاب استراتژی مناسبِ تیم و محصول خودمون، باید این موارد رو درنظر بگیریم:? آیا این workflow مناسب سایز تیم یا محصول من هست؟? اگه به اشتباه یا خطایی برخورد کردم، این workflow به داد من میرسه؟? آیا این workflow با اضافه شدنش، سربار ذهنی غیرضروری جدیدی به تیم وارد میکنه؟ورک‌فلِو متمرکز | Centralized Workflowمیشه گفت این استراتژی در git، ساده ترین روش برای مدیریت codebase محصول به حساب میاد. در این روش، یک default branch وجود داره و اون master نامیده میشه. در این روش فقط یک نقطه ی ورود برای همه ی تغییرات در پروژه وجود دارد. درسته که این روش فرق چندانی با نگهداری کد بصورت local نداره، ولی باعث میشه برنامه نویس ها فارق از بقیه ی تغییرات اعمال شده توسط بقیه افراد تیم، بتونن کد بزنن و فیچر خودشون رو به repository اضافه کنند.#نظرشخصی: این روش بنظر من واسه تیم های کوچک و کمتر از ۵ نفر مناسبه⚫️ ایجاد تغییرات و commitزمانی که توسعه دهنده repository رو clone میکنه، میتونه با استفاده از فرآیند های گیت مثل edit،stage،commit تغییرات جدیدی رو بصورت local در repository اعمال کند.برای بررسی تغییرات میتوانید از این دستور استفاده کنید:⚫️ انتقال کامیت های جدید به central repositoryزمانی که تغییرات جدیدی در local repository کامیت شد، نیازه که این تغییرات با بقیه ی برنامه نویس های محصول، به اشتراک گذاشته شود. با اجرا کردن این فرمان کامیت های جدید، در برنچ master که از اون بعنوان central repository استفاده میکنیم، push میشه. این احتمال وجود داره که تغییرات جدید کد، باعث بشه هم تیمی شما هنگام push کردن کدهای جدید به خطای مغایرت یا conflict error برخورد کنه!⚫️ اولین راهِ چارهاولین راهکار برای رفع conflict در این شرایط اجرای git pull هست که در ادامه راهکار جامع تری رو توضیح میدم.⚫️ مدیریت conflictsاگه local commit های توسعه با central repository هم‌خوانی نداشته باشه، گیت از push کردن تغییرات خودداری میکنه به این دلیل که این امکان وجود داره که central repository دچار overwrite شود.? یک مثال از این ورک‌فلوبیایید یک مثال کلی در مورد چگونگی همکاری یک تیم کوچک معمولی با استفاده از این گردش کار بیاوریم. خواهیم دید که چگونه دو برنامه نویس ، John و Mary ، می توانند روی ویژگی های جداگانه کار کنند و مشارکت های خود را از طریق یک مخزن متمرکز به اشتراک بگذارند.توسعه feature توسط Johnدر local repository خود ، John می تواند فیچر خود را با استفاده از فرآیند استاندارد Git توسعه دهد. به یاد داشته باشید از آنجا که این دستورات کامیت های local را ایجاد می کنند ، John می تواند این روند را هر چند بار که بخواهد تکرار کند بدون اینکه نگران تغییرات موجود در central repository باشد.توسعه feature توسط Maryدر همین حال ، Mary با استفاده از همان فرایند در حال کار بر روی feature خود در local repository خود است. برای Mary مانند John مهم نیست که در central repository چه می گذرد و اهمیتی ندارد که John مشغول چه کاری است. زیرا همه repository ها local و خصوصی هستند.انتشار feature توسط Johnهنگامی که John فرآیند توسعه ی feature خود را به پایان رساند باید local commit های خود را در central repository منتشر کند تا سایر اعضای تیم بتوانند به آن دسترسی پیدا کنند. او می تواند این کار را با دستور git push انجام دهد:انتشار feature توسط Maryبیایید ببینیم اگر Mary سعی کنه feature خود را انتشار دهد، پس از اینکه John با موفقیت تغییرات خود را در central repository منتشر کرد ، چه اتفاقی می افتد. اون نیز مانند John از دستور     git push استفاده میکند ولی با خطا مواجه میشود:استفاده از rebase توسط Maryکاری که Mary میتواند انجام دهد استفاده از git pull است. با این کار تغییراتی که قبلا John در central repository منتشر کرده است، به local repository مری انتقال می‌یابد و کامیت های John هم با کامیت های Mary ادغام میشود:در دستور بالا، با اضافه کردن rebase-- پس از یکسان سازی local repository با central repository، تمام کامیت های Marry به ابتدای برنچ master انتقال می‌یابد: رفع یک تداخل ( merge conflict ) توسط Marryفرآیند rebasing با انتقال هر کامیت local به برنچ master انجام میشود. این به این معناست که تداخلات کد بجای حل شدن در یک merge commit بزرگ، کامیت به کامیت حل میشوند. این قابلیت به نگهداری تمیز تر کد کمک زیادی میکند. از طرف دیگر، این امر باعث میشود که ریشه ی اشکالات را راحت‌تر پیدا کنید و درصورت نیاز، بازگرداندن تغییرات ( roll back ) با کمترین تاثیر بر روی پروژه و محصول انجام شود.اگر Mary و John روی دو feature مختلف کار کنند، بعید بنظر میرسد که روند rebasing دچار تداخل شود. درغیر اینصورت git فرایند را با این پیام متوقف میکند:نکته ی جالب در مورد git این است که هر کس میتواند merge conflict خود را حل کند. در مثال ما، Mary به سادگی با اجرای git status میتواند فایل های دارای تداخل را در بخش Unmerged paths مشاهده کند:سپس فایل (ها) را همانطور که میخواهد ویرایش میکند. زمانی که به نتیجه ی مطلوب رسید، میتواند فایل ها را به stage اضافه کند و اجازه دهد git rebase بقیه ی کاراها را انجام دهد:این تنها کاری است که باید انجام شود. git به commit بعدی میرود و این فرایند را تکرار میکند تا همه ی تداخلات برطرف شود.اگر در این فرآیند به مرحله ای رسیدید که نمیدانید چخبر است، وحشت نکنید! فقط دستور زیر را اجرا کنید و به همان مکانی که شروع کردید برمیگردید:انتشار موفق feature توسط Maryبعد از انجام مراحل قبل و همگام سازی هر دو ریپوزیتوری ( local و central ) Mary میتواند تغییرات خود را با موفقیت منتشر کند.? در پست های آینده راهکار های مناسب تیم های بزرگ تر را ارائه میکنم.خوش حال میشم از شبکه های اجتماعیم دیدن کنید و نظراتتون رو بنویسید ❤️https://zil.ink/devoker</description>
                <category>انتشارات جاواکاپ</category>
                <author>devoker</author>
                <pubDate>Sat, 29 May 2021 23:34:21 +0430</pubDate>
            </item>
                    <item>
                <title>سه سوال رایج همه مصاحبه‌های کاری</title>
                <link>https://virgool.io/javacup/%D8%B3%D9%87-%D8%B3%D9%88%D8%A7%D9%84-%D8%B1%D8%A7%DB%8C%D8%AC-%D9%87%D9%85%D9%87-%D9%85%D8%B5%D8%A7%D8%AD%D8%A8%D9%87-%D9%87%D8%A7%DB%8C-%DA%A9%D8%A7%D8%B1%DB%8C-eyaexkkf9jki</link>
                <description>یکی از دوستان اخیرا برای مصاحبه کاری‌اش ازم مشورت خواسته بود. وقتی داشتم جوابم رو براش آماده می‌کردم، مجبور شدم برای اولین بار بشینم فکر کنم تو مصاحبه‌ها چه نکاتی رو باید رعایت کرد. نکات رو که براش آماده کردم، به نظرم بد نیومد که اینجا هم بنویسمشون.من نزدیک دو سال هست که در گوگل برای استخدام مهندس نرم‌افزار و یادگیری ماشین مصاحبه می‌کنم و توصیه‌هام رو از لابلای مصاحبه‌های خودم در آوردم. ولی از اونجایی که سوالهای تخصصی هر رشته متفاوته، نمیشه راهنمایی کلی برای همه مصاحبه‌های فنی داشت. ولی قسمتهای رفتاری مصاحبه‌ها همه‌جا شبیه هم هستن.  به همین دلیل، تمرکز این نوشته روی سوالهای فنی مربوط به رشته کامپیوتر یا هوش مصنوعی نیست؛ بکله سوالهای رایج و نکاتی هستن که تقریبا برای همه مصاحبه‌ها و همه‌ی موقعیت‌های شغلی تکرار میشن.تو این پست، سه سوال رایجی رو که باید خیلی بدیهی باشن ولی معمولا همه بهشون کم توجهی میکنن، توضیح می‌دم.(source: insights.dice.com)خیلی خلاصه خودت رو معرفی می‌کنی؟همه مصاحبه‌های ما با همین سوال شروع میشن و انتظار میره که متقاضی بتونه خودش رو در حد پنج دقیقه معرفی کنه. ولی بطرز عجیبی اکثرا در معرفی خودشون آماده نیستن و یه سری جملات نامفهوم تحویل مصاحبه‌کننده می‌دن. آماده نبودن تو این قسمت خیلی‌ها رو دچار دستپاچگی هم می‌کنه؛ اینکه نتونستن همه کارهای مهم گذشته‌شون رو درست معرفی کنن روی ذهنشون سنگینی می‌کنه و تو قسمتهای بعدی هم عالی عمل نمی‌کنن.خب، چطور جواب این سوال رو بدیم؟ شخصا این روش رو بیشتر از بقیه می‌پسندم که سه قسمت داره:۱) معرفی خود در رشته و کار - در چه رشته‌ای درس خوندین، چه دانشگاهی بودین، محل کار فعلی شما کجاست، تو چه زمینه‌ای تخصص دارین (سابقه کار یا تحصیل) و مسئولیت‌هاتون چی‌ها هستن.۲) توضیح دادن چند پروژه یا دستاورد مشخص که از بقیه مهمترن. این پروژه‌ها رو با توجه به میزان اهمیت‌شون مرتب کنین - بزرگی پروژه و ارتباطش با موقعیتی که دارین براش مصاحبه می‌کنین. برای توضیح هر پروژه این ساختار رو در نظر بگیرین: i) شرح مساله و اهمیتش، ii) راه حل شما، و iii) نتیجه نهایی که بدست آوردین. بین این سه قسمت، شرح مساله از بقیه مهمتره. مصاحبه کننده باید بفهمه شما رو چه مشکلی کار کردین و چرا باید براش مهم باشه. احتمالا توضیح یک یا دوتا پروژه کفایت می‌کنه.۳) چرا شما دنبال این موقعیت هستین؟ (موقعیتی که دارین براش مصاحبه می‌کنین) جوابی که من دوست دارم تقریبا اینطوریه: &quot;اگرچه من از موقعیت و شرکت فعلی‌ام خیلی راضی ام، ولی فکر کردم الان می‌تونه وقت یک چالش جدید باشه. تیم شما در [فلان حوزه] کارهای مهمی انجام داده (یا قراره انجام بده) و برای من که تو این زمینه کار می‌کنم (یا می‌خوام کار بکنم) بسیار هیجان انگیزه.&quot;باز هم تاکید کنم که برای این قسمت باید تمرین کرد. خیلی‌ها همه تمرکزشون رو می‌ذارن رو قسمتهای فنی مصاحبه و از معرفی خودشون غافل میشن. دوستان، باور کنید این قسمت اصلا راحت نیست! تمرین کنید!در پنج سال آینده خودت رو کجا می‌بینی؟این سوال هم نسبتا رایجه و به نظر من سوال بدی هم نیست. اتفاقا نشون می‌ده طرف چقدر خودش و حوزه‌ی کاریش رو می‌شناسه و تونسته برای آینده‌اش یه مسیر معقول و منطقی متصور باشه. از بین جوابهایی که شنیدم، این ساختار رو بیشتر از بقیه می‌پسندم که این هم سه قسمت داره:۱) مشخص کنید چکار می‌کنید. مثلا &quot;من در ۱-۲ سال آینده سعی می‌کنم تمام جزییات [موقعیت شغلی] رو بشناسم و با توجه به پیشینه‌ای که در [فلان حوزه] دارم، تو این قسمت کاملا مسلط باشم. بعد، برای ۲-۳ سال سعی می‌کنم که مسئولیت‌های بیشتری بپذیرم و ببینم رو [موضوع‌های دیگه] چه کارهایی میشه کرد و اون پروژه‌ها رو رهبری بکنم.&quot;۲) علاقه‌تون چیه: مثلا &quot;...من خیلی به [این صنعت] علاقه دارم و به نظرم در آینده نقش مهمتری هم خواهد داشت.&quot;۳) برجسته کردن تعهدتون به شرکت: مثلا &quot;... به نظرم این شرکت برای رشد و کار کردن در [فلان تخصص] گزینه‌ی عالی‌ای هست که اجازه میده من تجربه مرتبط با علاقه‌ام رو بدست بیارم و رشد کنم.در آخر، سوالی از من نداری؟وقتی مصاحبه داره تموم میشه معمولا در حد ۵ دقیقه به متقاضی وقت می‌دن که اگه اون سوالی داره بپرسه. مثلا کاندیداها می‌پرسن  &quot;شرایط شرکت چطوره؟&quot;، &quot;چیزی بوده که ازش ناراضی بودی؟&quot; و غیره. (حتی یکی پرسیده بود &quot;غذای ایرانی هم دارین اونجا؟&quot; ?)این قسمت جز ارزیابی نیست و جواب غلط (در واقع سوال غلط) وجود نداره. ولی یه سوال هست که من توصیه می‌کنم حتما بپرسین: &quot;فرض کنید به تیم شما اضافه شدم. دوست دارم بدونم چطور میشه تو این تیم موفق بود؟ به عنوان کسی که چند ساله توی این تیم هستین، چه توصیه‌ای برای منِ تازه‌وارد دارین که بتونم موفق بشم؟&quot;چرا پرسیدن این سوال رو توصیه می‌کنم؟ چون این سوال یه جورایی کمک دریافت کردن هست. مصاحبه‌کننده برای اولین بار تو مصاحبه خودش رو در سمت شما می‌بینه و سعی می‌کنه شرایط شما رو درک کنه و بهتون راهنمایی مفیدی بکنه. یه چیزی شبیه مشاوره دادن هست. طرف سعی می‌کنه در موفقیت شما، به عنوان مشاور و راهنما، سهیم بشه. از پرسیدن این سوال هم راهنمایی‌های خوبی دریافت می‌کنین و هم احتمالا اطلاعات مفیدی در مورد فرهنگ اون شرکت و تیم بدست میارین؛ ولی از همه مهمتر، این سوال باعث ایجاد یک ارتباط دوستانه و حرفه‌ای با مصاحبه‌کننده میشه.یه توصیه هم برای چگونه رفتار کردن سر مصاحبه دارم. دو تایپ شخصیتی هستن که برای ما خط قرمز به حساب میان:یک. آدمهای pushover: اونهایی که از خودشون هیچ نظری ندارن و هرچی شما می‌گین رو می‌پذیرن و تایید می‌کنن.دو. آدمهای arrogant: اونهایی که انقدر از خود راضی هستن که فقط حرف خودشون رو قبول دارن، با مصاحبه‌کننده از بالا به پایین صحبت می‌کنن، و موضع‌شون رو هیچوقت عوض نمی‌کنن؛ حتی وقتی دارن اشتباه می‌کنن، پذیرفتن اشتباه و اصلاح حرفشون براشون غیرممکنه.توصیه من هم همین هست؛ نه pushover باشید و نه arrogant. به حرف طرف مقابل خوب گوش کنید. اگه به نظرتون منطقی نمیاد، سوال بپرسید. اگه قانع نشدید، نقطه نظر خودتون رو توضیح بدید و بگید چرا براتون منطقی نیست (pushover نباشید و الکی چیزی رو تایید نکنید). در عین حال، اگه متوجه حرف طرف شدید و فهمیدید اشتباه کرده بودین، رو اشتباه‌تون پافشاری نکنید. پذیرش نقطه نظر مقابل نشون دهنده شخصیت بالغه (arrogant نباشید).</description>
                <category>انتشارات جاواکاپ</category>
                <author>مــتـیـن</author>
                <pubDate>Sun, 16 May 2021 22:57:17 +0430</pubDate>
            </item>
                    <item>
                <title>جلساتی که نباید به صورت ناهمزمان برگزار شوند</title>
                <link>https://virgool.io/javacup/%D8%AC%D9%84%D8%B3%D8%A7%D8%AA%DB%8C-%DA%A9%D9%87-%D9%86%D8%A8%D8%A7%DB%8C%D8%AF-%D8%A8%D9%87-%D8%B5%D9%88%D8%B1%D8%AA-%D9%86%D8%A7%D9%87%D9%85%D8%B2%D9%85%D8%A7%D9%86-%D8%A8%D8%B1%DA%AF%D8%B2%D8%A7%D8%B1-%D8%B4%D9%88%D9%86%D8%AF-xq24an6afnvm</link>
                <description>جلسات غیرمولد و بی‌فایده، افراد و شرکت‌ها را به سمت راه‌حل‌های بهتری برای برگزاری جلسات، هدایت کرده است. اکنون که بیش از یکسال از پاندمی کرونا گذشته، و اقبال شرکت‌ها به دورکاری کارمندان و استفاده از تیم‌های دورکار بیش‌تر شده است، نیاز داریم تا در مورد جلساتی که باید به صورت همزمان (آنلاین / برخط / حضوری) برگزار شوند و جلساتی که باید به صورت ناهمزمان برگزار شوند بازبینی کنیم.این متن در تکمیل راهنمای ارتباطات ناهمزمان در تیم‌های دورکار نوشته شده و امیدوارم مفید باشد.جلساتی که باید ناهمزمان باشنداز کجا باید تشخیص دهیم که کدامیک از جلسات‌مان با اعضای تیم‌ها می‌بایست به صورت همزمان برگزار شوند و کدامیک می‌تواند از الگوهای ناهمزمان استفاده کنند؟ از کجا بدانیم که این ناهمزمانی در جلسات می‌تواند مفید باشد؟با مثال‌هایی در ادامه می‌توانم اطمینان دهم که استفاده از این الگو، بسیار تاثیرگذار بوده و خود من هم در یکسال گذشته، نتایج خوبی از آن گرفته‌ام.اینجا در مورد پلنیست بخونید. پلنیست یک ابزار کاملا رایگان هست که احتمالا خیلی بهتون توی مدیریت جلسات کمک می‌کنه.اطلاع‌رسانی‌های عمومیبه‌جای صدا کردن همکاران و هم‌تیمی‌های خود برای یک اطلاع‌رسانی ساده که ممکن است زمان طولانی‌ای هم از آن‌ها درگیر کند، آن‌ها را در یک کانال عمومی یا از طریق ایمیل در اختیارشان قرار دهید تا سر فرصت و در زمان مناسب آن‌ها را ببینند.اطلاع‌رسانی‌های عمومی که در بسیاری شرکت‌ها از طریق SMS یا پرتال‌های داخلی سازمان منتشر می‌شوند بهترین نمونه‌های اجرا شده از این مواردند.به‌روز رسانی‌های وضعیتبه‌روز نگاه داشتن تیم‌ها در مورد حجم کار انجام شده و اطلاع‌رسانی به آن‌ها به صورت کتبی بسیار آسان است و نیازی به جلسات همزمان در آن دیده نمی‌شود. می‌توانید از طریق پیام‌رسان‌های سازمانی که در اختیار دارید یا ایمیل؛ گزارش پیشرفت کار هفته گذشته خود را به تمامی ذی‌نفعان ارسال کنید و به آن‌ها فرصت دهید تا آنچه را که در بازه زمانی هفته گذشته روی آن کار کرده‌اند ببینند و بدانند که برای هفته آینده چه برنامه‌هایی پیش‌روی‌شان قرار دارد. با این کار می‌توانید از هزینه‌های برگزاری جلسات همزمان در سازمان هم بکاهید.وقتی یک تیم ۱۲ نفره در طول هفته یک ساعت به جلسات همزمان دعوت می‌شود در پایان هفته ۱۲ ساعت و در طول سال ۶۲۴ ساعت از زمان خود را در از دست داده است.پس برای برگزاری جلسات همزمان وسواس بیشتری به‌خرج دهید.جلسات طوفان مغزی (Brain Storming)مطالعات نشان می‌دهد که جلسات طوفان فکری، ایده‌های کمتری را نسبت به سایر روش‌های همفکری تولید می‌کند. اما همچنان پیش‌فرض خیلی از تیم‌ها و سازمان‌ها برگزاری این سبک از جلسات است. شاید تعجب کنید اما واقعیت همین است.دیوید فیشلاک (توسعه دهنده) معتقد است به طور کلی، فقط تعداد محدودی از شرکت‌کنندگان جلسات طوفان فکری در ایده‌پردازی‌ها سهیم‌اند. در حالی که اگر شما یک تاپیک همفکری در پیام‌رسان سازمانی خود ایجاد کنید، می‌توانید تعامل بیشتری از افراد را انتظار داشته باشید چون هیچ‌کس صحبت فرد دیگری را قطع نمی‌کند و افراد زمان مناسبی برای فکر کردن روی موضوع موردنظر دارند.فراموش نکنید که جلسات طوفان فکری که به صورت ناهمزمان برگزار می‌شوند، در شرایط پراسترس و زمان محدود پاسخگو نیست و باید زمان مناسبی را به آن اختصاص دهید. به‌طور مثال تاپیک باز شده می‌بایست به مدت حداقل ۱۰ روز در اختیار اعضای تیم باشد و پس از آن جمع‌بندی اتفاق بیافتد.جلسات شروع و برنامه‌ریزیباز کردن دامنه کار، جدول زمانی برنامه‌ریزی و تکمیل ماتریس مسوولیت‌های اعضای تیم در شروع هر پروژه‌ای از اهمیت بالایی برخوردار است و این جلسات می‌تواند با حضور اعضای تاثیرگذار تیم برگزار شود.از لحظه شروع تا خاتمه این جلسه می‌توان محتویات و مهم‌ترین مباحث مطرح شده در جلسه را مکتوب و سپس آن‌را با تمامی اعضای حاضر/غایب به اشتراک گذاشت.نکته مهم در این بخش این است که این محتویات و تصمیمات مهم ثبت شده در این جلسات نباید از یک صفحه فراتر رود.پیش‌تر مطلبی با عنوان شروع پروژه‌های جدید با تیم‌های دورکار، در وبلاگ منتشر شده که می‌توانید آن‌را مطالعه کنید.پیشرفت کار تیم‌هاهنگامی که پروژه جدیدی را شروع می‌کنید، می‌توانید کارهای زیادی را همزمان با هم انجام دهید. از جذب نیروهای جدید و آن‌بردینگ آن‌ها به تیم گرفته تا حل تعارضات و مشکلات میان اعضای تیم و ذی‌نفعان. به شرطی که ساختار ارتباطات اعضای تیم را در ابتدای شروع پروژه به درستی تعریف کرده باشید.در بسیاری از گروه‌های اطلاع‌رسانی و به‌روزآوری اعضای تیم، تمامی ذی‌نفعان به درستی منشن کنید یا در زنجیره ایمیل‌های تبادل شده قرار دهید تا در جریان اتفاقات رخ داده در طول پیشرفت کار پروژه قرار گیرند.نکته مهم: هر مکالمه‌ای نیاز به یک ترد ایمیل مجزا یا یه اطلاع‌رسانی در گروه‌های عمومی ندارد. گاهی نیاز دارید تا موضوعی را از یک فرد خاص پیگیری کنید، بهترین و سریع‌ترین روش، برقراری یک چت خصوصی، یک ایمیل تک‌نفره با فرد مورد نظر است و اگر نیاز بود، سایر ذی‌نفعان را در ادامه به این گروه / ترد ایمیل اضافه کنید.جلسات بازبینی، دمو و دریافت فیدبکمفیدترین و بارزترین بازخوردها زمانی اتفاق می‌افتد که افراد وقت کافی برای تفکر و بیان صریح نظرات خود داشته باشند.فرصت دادن به افراد برای بررسی یک محصول قابل دمو، یا بازبینی کدهای تولید شده در یک محصول جدید می‌تواند با برگزاری ناهمزمان نتایج مطلوب‌تری را به‌همراه داشته باشد.محدودیت برگزاری جلسات همزمانمعمولا پیدا کردن زمان مناسب برای حضور تمامی ذی‌نفعان کلیدی در یک جلسه به صورت همزمان کار دشواری‌ست. نیازی به یادآوری نیست که برگزاری جلسات بدون حضور یک یا چند نفر از ذی‌نفعان کار درستی نیست و نباید اجازه دهید که چنین اتفاقی در جلسات مهم رخ دهد.بنابراین وسواس لازم در برگزاری جلسات حضوری را همیشه درنظر داشته باشید و تا حد امکان برگزاری جلساتی که در بالا به آن اشاره شد را به صورت ناهمزمان برگزار کنید تا مشارکت حداکثری افراد را با خود همراه داشته باشید.جلساتی که نباید ناهمزمان برگزار شوندحتی در یک تیم کاملا دورکار هم، خود من برخی از جلسات را به صورت همزمان برگزار می‌کنم و نمی‌توانم آن‌ها را به صورت ناهزمان پیش ببرم. برخی از این جلسات که به برگزاری همزمان آن اصرار دارم در ادامه آمده است.آن‌بردینگ و معرفی هم‌تیمی جدیدآشنایی اعضای تیم با یک عضو جدید، همواره می‌بایست به صورت همزمان اتفاق بیافتد. شنیدن صدای هم‌تیمی‌ها و دیدن تصویر آن‌ها، حالت بدن و چهره این افراد از مهمترین دلایلی است که این جلسات را به صورت همزمان برگزار می‌کنم.گاهی این جلسات معرفی به صحبت از علایق و موارد غیرکاری سپری می‌شود و این موضوع احساس بهتری را میان اعضای تیم برقرار می‌کند.رفاقت در گروه‌های غیرکاری، ارسال ویدیوها و نوشته‌هایی که حال و هوای غیرکاری دارند میان اعضای تیم صمیمیت آن‌ها را بیش‌تر کرده و به آن‌ها کمک می‌کند تا تیم منسجم‌تری را در سازمان شکل دهند.تصمیم‌گیری‌های مهمارتباطات ناهمزمان براساس آنچه گفته‌ام، کند است. بنابراین در صورت بروز یک وضعیت اضطراری، لازم است تا همه افراد در لحظه به صورت تلفنی یا تصویری در دسترس باشند.نکته مهم: هنگام بروز این موارد، یک اطلاع‌رسانی فوری به اعضای تیم داشته باشید و از آن‌ها بخواهید در یک زمان مقرر در دسترس باشند تا بتوانید موضوع را در سریع‌ترین زمان ممکن اطلاع‌رسانی و در مورد آن تصمیم‌گیری کنید.مستندات پیچیده یا با جزییات زیاداگر شما می‌توانید (و یا باید) دستورالعمل‌های گام‌به گامی از گردش دقیق کار را به صورت مکتوب آماده کنید، ممکن است بسیاری از وابستگی‌ها و جزییات را در ذهن نداشته و یا ممکن است در ثبت آن‌ها دچار خطا شوید.پس بهتر است برای این سبک از گزارشات جلساتی را به صورت همزمان و با حضور تمامی ذی‌نفعان برگزار کنید تا در کنار هم و با سرعت مناسب مستند مورد نظر را آماده کنید.جلسات با موضوع احساسیانسان‌ها در ارتباطات خود، درگیری زیادی با زبان بدن، لحن و حالت چهره‌شان دارند و متاسفانه این احساسات در ارتباطات کتبی به هیچ عنوان منتقل نمی‌شوند. هر چقدر هم که از ایموجی‌ها و گیف‌ها در پیام‌های خود استفاده کنید بازهم جایگزین لحن و حالت شما در انتقال پیام نخواهد بود.برای مکالمات سخت کاری، مثل ارایه انتقادات سازنده، بازخوردهای موثر، بحث در مورد موضوعات حساس مرتبط با منابع انسانی، اخراج و یا قطع همکاری با یکی از اعضای تیم، جلسات را به صورت همزمان و حتما به صورت تصویری برگزار کنید.تاکید به معنای فقط نیستهمه ما باید در مورد نحوه اتفاق افتادن و چگونگی کارها در زمان همه‌گیری یک بحران یا بیماری خاص مثل Covid-19 تجدید نظر کنیم.همانطور که رفتن به میز هم‌تیمی‌مان برای پیگیری یک کار در این شرایط غیرممکن شد، اما افراد درک کردند که در واقع نحوه پیگیری کارهای خود را تغییر دهند. مطالعات نشان داده است که مشاهده ارتباطات موثر اعضای تیم با یکدیگر موجب افزایش شادی و ارزشمندی بیشتری برای آنان شده و بهره‌وری‌شان را نیز افزایش می‌دهد.در عین حال ترک این عادت‌ها بسیار سخت است. ضمن اینکه ترکیبی از جلسات همزمان و ناهمزمان ممکن است لزوما برای تیم شما مفید نباشد و می‌بایست خودتان در مورد چگونگی ترکیب و برگزاری آن‌ها تصمیم بگیرید.برای شروع می‌توانید از انتقال یک جلسه تکراری از همزمان به ناهمزمان شروع کنید و ببینید چطور پیش‌ می‌رود. ارتباط برقرار کنید و هنگامی که فیدبک مناسبی از اعضای تیم دریافت کردید کم‌کم سایر جلسات را نیز تغییر رویه دهید و تجربه خود را هم با من به اشتراک بگذارید.اگر این مطلب رو دوست داشتید می‌تونید اینجا توی خبرنامه من هم عضو بشید تا نوشته‌های بیشتری رو به صورت هفتگی دریافت کنید.</description>
                <category>انتشارات جاواکاپ</category>
                <author>محسن احمدی</author>
                <pubDate>Mon, 03 May 2021 17:00:36 +0430</pubDate>
            </item>
                    <item>
                <title>چگونه معماری نرم‌افزار را بهبود دهیم؟</title>
                <link>https://virgool.io/javacup/%DA%86%DA%AF%D9%88%D9%86%D9%87-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%DB%8C-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-%D8%B1%D8%A7-%D8%A8%D9%87%D8%A8%D9%88%D8%AF-%D8%AF%D9%87%DB%8C%D9%85-paoon6ie466v</link>
                <description>چکیدهکتاب «معماری نرم‌افزار در عمل» نگاه کاربردی و جالبی به معماری دارد. این کتاب به طور خلاصه می‌گوید همه نیازمندی‌های کیفی یک نرم‌افزار مثل نگهداری‌پذیری (Maintainability) و کارایی (Performance) قابل اندازه‌گیری و بهبود است. در نگاه اول کمی دور از ذهن است، مثلا چطور می‌توان نگهداری‌پذیری را اندازه‌گیری کرد؟ کتاب پاسخ می‌دهد: کافی است با دقت به سناریوی این نیازمندی کیفی توجه کنید و با هوشمندی شاخصه‌ی‌ کیفی مورد نظر را شناسایی نمایید. نگاه این کتاب من را به یاد این جمله از لورد کلیون انداخت: «اگر نتوانی اندازه‌گیری‌اش کنی، نمی‌توانی بهبودش دهی». تصویر جمله‌ی لورد کلیوندر ادامه ترجمه‌ی قسمتی از کتاب معرفی‌شده را با هم می‌خوانیم.معماری نرم‌افزاردر چرخه‌ی تولید نرم‌افزار عوامل زیادی، نیازمندی‌های کیفی یک سیستم را تحت تاثیر می‌گذارد. این نیازمندی‌های کیفی، فراتر از نیازمندی‌های کارکردی هستند که حداقل انتظاری است که از یک نرم‌افزار می‌رود. از طرفی نیازمندی‌های کارکردی و کیفی ارتباط تنگاتنگی با هم دارند. هنگام توسعه، معمولا کارکردها در اولویت قرار می‌گیرند اما می‌دانیم این ترجیح، در حقیقت کوته‌نظرانه است. چنان که می‌بینیم سیستم‌ها بازطراحی و بازسازی می‌شوند نه به خاطر نقصان در کارکردهایی که ارائه می‌دهند، چه آن که معمولا از لحاظ کارکرد با سیستم قبلی یکسان هستند، بلکه فقط به خاطر نیازمندی‌های کیفی که به اندازه‌ی کافی ارضا نمی‌شود. برای مثال قابلیت نگهداری و تغییر کافی را ندارند، به اندازه‌ی کافی قابل انتقال (portable) نیستند یا خیلی کند هستند و کارایی کافی را ندارند و یا از امنیت (Security) لازم برخوردار نیستند.به اعتقاد ما معماری اولین جایی است که در توسعه‌ی نرم‌افزار باید نیازمندی‌های کیفی را هدف قرار دهیم. معماری نگاشت نیازمندی‌های کارکردی و کیفی است به ساختارهای نرم‌افزاری لذا تاثیر قطعی در میزان حمایت نرم‌افزار مورد نظر از نیازمندی‌های کیفی مانند کارایی خواهد داشت.حال می‌خواهیم مفهوم شاخصه‌ی کیفی را دقیق‌تر واکاوی کنیم. یک شاخصه‌ی کیفی یک ویژگی قابل اندازه‌گیری و قابل آزمون (Testable) است که نشان می‌دهد نرم‌افزار مورد نظر چقدر پاسخگوی نیازهای ذی‌نفعان است. می‌توان شاخصه‌ی کیفی را شاخصه‌ای در نظر گرفت که نشان‌دهنده‌ی میزان رضایت ذی‌نفعان از نرم‌افزار را در ابعاد گوناگون منافعشان نشان می‌دهد.شاخصه‌ی کیفی (Quality Attribute)یک شاخصه‌ی کیفی باید خوش‌تعریف و قابل آزمون باشد. کتاب «معماری نرم‌افزار در عمل» از یک فرم یکسان برای بیان همه‌ی شاخصه‌های کیفی استفاده می‌کند. مزیت این انتخاب تاکید آن بر ویژگی‌های مشترک همه‌ی شاخصه‌های کیفی است هرچند گاهی ممکن است یک جنبه‌ی کیفی کاملا در فرم مورد استفاده نگنجد و این امر سبب ایجاد اندکی دشواری در بیان آن جنبه شود. این فرم مشترک به شرح ذیل قابل بیان است:یک سناریو برای تعریف یک شاخصه‌ی کیفی۱. محرک (Stimulus)بیانگر رویدادی است که وارد سیستم می‌شود. این محرک می‌تواند در همبافت کارایی یک درخواست باشد، در همبافت کاربردپذیری یک عملکرد کاربر باشد و در همبافت امنیت یک حمله‌ی امنیتی. همچنین است وقتی در همبافت نگهداری‌پذیری صحبت می‌کنیم؛ دقیقا همین لغت برای تعریف یک انگیزه‌ی تغییر در کد به کار می‌بریم. همچنین در تغییرپذیری (Modifiability)؛ درخواستی برای تغییر در سیستم یک محرک محسوب می‌شود. محرک آزمون‌پذیری همچنین، اتمام یک مرحله از توسعه است، که نیاز به آزمون آن را ایجاد می‌کند.۲. منبع تحریک (Source of Stimulus)یک محرک حتما یک منبع تحریک دارد. منبع تحریک در نحوه‌ی برخورد بار محرک تعیین‌کننده است. مثلا وقتی یک کاربر غیرمطمئن درخواستی ارسال می‌کند پاسخ به آن متفاوت است با زمانی که منبع این تحریک یک کاربر احراز هویت شده چنین درخواستی را ارسال نموده است.۳. پاسخ (Response)هر محرکی مستلزم یک پاسخ از طرف سامانه است. پاسخ هنگامی که سخن از سامانه‌ی در حال اجراست، شامل مسئولیت‌هایی است که سیستم در قبال یک محرک بر عهده دارد. هنگامی که سخن از کد در حال توسعه است اما، پاسخ به عملی گفته می‌شود که توسعه‌دهندگان قصد انجام آن را روی آرتیفکت در حال توسعه دارند. برای مثال در آزمون کارایی، با ورود یک درخواست به مثابه اعمال محرک به سیستم، انتظار می‌رود که در زمان مناسبی درخواست پردازش شده و نتیجه‌ی آن به مثابه یک پاسخ ارسال شود.  همچنین است در همبافت تغییرپذیری؛ وقتی نیازی به تغییر در کد به وجود می‌آید، به انجام رسیدن تغییر مورد نیاز در کد برنامه پاسخی است که در خور این محرک است.۴. سنجه‌ی پاسخ (Response Measure) مشخص می‌کند که آیا یک نیازمندی کیفی راضی کننده هست یا خیر. برای مثال برای کارایی اندازه تاخیر و گذرداد می‌تواند به عنوان یک سنجه‌ی پاسخ مورد توجه قرار گیرد.این چهار عنصر، قلب تعریف یک شاخصه‌ی کیفی است. اما دو تعریف مهم دیگر نیز وجود دارند:۵. محیط (Environment)مجموعه‌ای است از شرایطی که سناریو نیازمندی کیفی در آن اتفاق می‌افتد. محیط نیز در پاسخی که به یک محرک داده می‌شود تعیین‌کننده است.۶. سازه (Artifact) قسمتی از سامانه‌ است که نیازمندی مربوط به آن است. ای بسا کل سامانه سازه‌ی مدنظر ما باشد، اما گاه تنها قسمتی از سامانه به عنوان سازه مورد تمرکز قرار می‌گیرد.کتاب در ادامه شاخصه‌های کیفی عمومی را متمایز می‌کند؛ شاخصه‌های کیفی که مستقلا برای سیستمی قابل تعریف هستند در مقابل شاخص‌های کیفی اختصاصی که در یک سناریو خاص برای یک سیستم خاص تعریف می‌شوند.می‌توان شاخصه‌های کیفی را به عنوان مجموعه‌ای از سناریوهای کلی تعریف کرد. البته، برای ترجمه‌ی این سناریوهای کلی به نیازمندی‌های یک سیستم، سناریوی کلی باید خاص منظوره شود.کتاب معماری نرم‌افزار در عملدر نوشته‌های بعدی سعی خواهم کرد با چند مثال واقعی کاربست این روش را با توضیح بیشتر در عمل نشان دهم.</description>
                <category>انتشارات جاواکاپ</category>
                <author>کیارش آذرنیا</author>
                <pubDate>Fri, 30 Apr 2021 12:44:43 +0430</pubDate>
            </item>
                    <item>
                <title>کاربرد Action ها در Github</title>
                <link>https://virgool.io/javacup/%DA%A9%D8%A7%D8%B1%D8%A8%D8%B1%D8%AF-action-%D9%87%D8%A7-github-pel5zw49ufzx</link>
                <description>یه چند وقتی میشه که گیتهاب اکشن هارو معرفی کرده که میشه با استفاده از این اکشن ها یسری فعالیت های تکراری رو، خودکار سازی کرد و توی وقت و انرژی صرفه جویی کرد.حالا مثلا ما چجور کارایی میتونیم بکنیم؟ تقریبا میشه گفت هرکاری رو میشه باهاش کرد. کامپایل کردن پروژه، تست کردن، پابلیش کردن و...من معمولا فایل های خروجی که برای پروژه هام میگیرم بدلیل استفاده از ویژگی SelfContained و ایمیج های ReadyToRun برای اجرای سریعتر، معمولا حجمی حدود 140 مگ داره، حالا وقتی فشردش میکنم حجمش حدود 50 مگ میشه که اگر من بخوام هر دفعه که از برنامه خروجی میگیرم بیام فایل خروجی رو فشرده کنم و اون رو در گیتهاب اپلود بکنم هم فرایندی زمانبر هست هم اینکه تکراری و خسته کننده در نتیجه تصمیم گرفتم که از اکشن گیتهاب برای خودکارسازی این فرایند استفاده کنم. توی این نوشته کوتاه میخوایم یه اکشن بنویسیم که بیاد بر اساس سورس کد موجود روی گیتهاب برنامه رو بیلد کنه، فایل اجرایی رو بصورت فایل فشرده Zip ایجاد کنه و در نهایت این فایل فشرده رو در قسمت Release گیتهاب منتشر کنه/برای شروع کار اول باید در مخزن پروژه در سایت گیتهاب، به قسمت Action بریم.حالا روی قسمت New workflow باید کلیک کنیماینجا شما میتونید از قالب های پیشفرض موجود هر کدوم رو خواستید انتخاب کنید، اما من ترجیح میدم کارمو با یه قالب خالی شروع کنم پس روی set up a workflow yourself کلیک میکنیمکدهای پیشفرضی که وجود داره رو پاک کنید تا مثل عکس زیر یه فایل کاملا تمیز و خالی رو داشته باشیمنکته ای که باید دقت کنید، اسم و مسیر فایل هستش، مسیر فایل رو اصلا نباید تغییر بدید، ولی اسم فایل رو میتونید اصلاح کنید ولی توجه کنید که پسوند فایل باید yml باشه.حالا بریم سراغ نوشتن کدهای اکشن:اول از همه کد زیر رو مینویسیمname: &amp;quotPublish&amp;quotاین خط اسم اکشن مارو مشخص میکنه که قراره توی لیست workflow ها نمایش داده بشهکدی بعدی که باید بنویسیم (در خط بعدی) باید مشخص بکنیم که این اکشن چه زمانی اجرا بشه تریگر های زیر استفاده بیشتری دارند:push = هر زمان که کامیتی رو روی گیتهاب پوش کنید اکشن اجرا میشهpull_request = هر زمان که یه پول رکوئست رو مرج کنید اجرا میشهworkflow_dispatch = برنامه نویس خودش میتونه با کلیک روی دکمه مشخصی در قسمت اکشن ها، اکشن موردنظر رو اجرا کنهلیست کامل تریگر هارو میتونید اینجا مطالعه کنید.ما از push استفاده میکنیم البته یکم تغییرش میدیم زمانی که شامل تگ هم باشه اجرا باشهon:
  push:
    tags:
      - &amp;quotv*&amp;quotنکته ای که هست ما در اخر این دستور از v* استفاده کردیم که داره اشاره میکنه اگر تگ بصورت v1.0.0 بود اجرا بشه اون * میتونه هر عددی باشه. حالا در پایان بهتر متوجه میشید.3 تا متغیر ایجاد میکنیم تا محل فایل پروژه، اجرایی و فشرده رو نگه داره تا فایل اکشنمون زیاد شلوغ نشهenv:
  PROJECT_PATH: src/HandySub/HandySub.csproj
  ZIP_PATH: src/HandySub/bin/Release/net5.0-windows/win-x86/publish/HandySub-x86.zip
  EXE_PATH: src/HandySub/bin/Release/net5.0-windows/win-x86/publish/HandySub.exeحالا باید دستورات خودکار سازی رو بنویسیم همه دستورات باید در قسمت jobs نوشته بشنjobs:
  deploy:
    runs-on: windows-latestبه قسمت runs-on توجه کنید اینجا داریم میگیم که اکشن ما روی سرور ویندوزی و اخرین نسخه از اون اجرا بشه که اگر نیاز داشتید میتونید از linux استفاده کنید.خط بعدی باید قدم به قدم دستورات رو بنویسیم ما برای هر قدم از دستور name استفاده میکنیم که هنگام اجرای اکشن بصورت مرتب و خوانا بتونیم بفهمیم که در چه مرحله از اجرا هستیم. قدم اول اینه که اکشن رو اماده کنیم اکثر دستورات مهم توی این اکشن موجوده    steps:
      - name: Initialize Actions
        uses: actions/checkout@v2قدم بعدی sdk دات نت رو باید روی سرور داشته باشیم تا عملیات بیلد و خروجی رو انجام بدیم پس میگیم که نسخه موردنظر مارو دانلود و نصب بکنه      - name: Initialize .Net
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: 5.0.x      قبل از بیلد کردن پروژه باید کتابخانه ها و بسته های ناگت رو restore کنیم تا بیلد خطا نداشته باشه      - name: Restore Project
        run: dotnet restore ${{ env.PROJECT_PATH }}حالا دستور خروجی گرفتن رو مینویسیم (بدلایلی که نمیدونم چیه حتما باید توی فایل csproj ، runtimeidentifier پروژه مشخص باشه که اینجا ما از win-x86 استفاده کردیم در غیر این صورت خطا میگیرید)      - name: Publish Project
        run: dotnet publish ${{ env.PROJECT_PATH }} -c Release --self-contained -r win-x86 --no-restoreحالا که فایل اجرایی رو ایجاد کردیم باید اون رو بصورت فشرده zip دربیاریم برای این کار از یه اکشن دیگه کمک میگیریم اول به اصطلاح  using میکنیم اون رو بعد ازش استفاده میکنیم. 2 تا ورودی داره files و dest که به ترتیب باید ادرس فایل ها و محل ذخیره زیپ رو بهش بدیم که ما از متغیر هایی که قبلا ایجاد کردیم استفاده میکنیم.      - name: Create Zip File
        uses: papeloto/action-zip@v1
        with:
          files: ${{ env.EXE_PATH }}
          dest: ${{ env.ZIP_PATH }}          در قدم اخر میایم از یه اکشن دیگه برای ساخت Release در قسمت گیتهاب کمک میگیریم، دقت کنید که برای اپلود کردن فایل زیپ داخل این Release، ما باید توکن و id این ریلیز رو ذخیره کنیم که اینجا میریزم داخل متغیر GITHUB_TOKEN و id، حالا این توکن رو از کجا میاریم؟ از قسمت secrets خود گیتهاب که شامل یسری اطلاعات از جمله توکن میشه، همچنین ما اسم تگ رو از طریق github.ref  دریافت میکنیم (همون تگی که پوش کردیم تو گیتهاب)      - name: Initialize Release
        uses: actions/create-release@v1
        id: create_release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: ${{ github.ref }}      حالا نوبته اینه که فایل زیپ رو اپلود کنیم، باز از یه اکشن دیگه کمک میگیریم، توکنی که قبلا ذخیره کردیم رو بهش میدیم همراه با فایل زیپ و در پایان به کمک id که قبلا ذخیره کردیم لینک فایل اپلود شده رو ازش دریافت میکنیم.      - name: Create Release    
        uses: csexton/release-asset-action@v2
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          file: ${{ env.ZIP_PATH }}
          release-url: ${{ steps.create_release.outputs.upload_url }}          کد کامل رو اینجا ببینیددر اخر بر روی دکمه سبز رنگ بالا سمت راست start commit کلیک کنید تا تغییرات ثبت بشه.برگردید به پروژه خودتون ترمینال رو باز کنید و یک تگ جدید ایجاد کنید.git tag v1.0.0حالا تگ ایجاد شده رو پوش کنیدgit push origin tag v1.0.0برید به مخزن گیتهاب تا ببینید که اکشن شما بصورت خودکار اجرا میشه و در پایان یک ریلیز برای شما ایجاد میکنه.در قسمت ریلیز میتونید ببینید که ریلیز توسط ربات گیتهاب ایجاد شده</description>
                <category>انتشارات جاواکاپ</category>
                <author>آمنوتجیکارا</author>
                <pubDate>Wed, 28 Apr 2021 18:44:44 +0430</pubDate>
            </item>
                    <item>
                <title>آشنایی با Multi threading در جاوا</title>
                <link>https://virgool.io/javacup/%D8%A2%D8%B4%D9%86%D8%A7%DB%8C%DB%8C-%D8%A8%D8%A7-multi-threading-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-e7r7fbjcjag7</link>
                <description>در بسیاری از نرم افزارها نیازمند اجرای چند Task به موازات هم هستیم. قابلیت multi tasking در سیستم عاملها مختلف برای این تعبیه شده که چندین وظیفه توسط منابع محدودی مثل cpu به صورت موازی انجام شوند و در واقع زمان منابع موجود بین وظایف مختلف تقسیم میشود. سیستم عامل برای اجرا دو پردازش سنگین،  منابعی مثل Cpu را با فاصله زمانی کوتاهی بین Process ها سوئیج میکند. این عمل به ویژه در پردازشهایی که منابعی دیگر جز CPU را درگیر میکنند کاربردی است تا دیگر پردازشها را معطل نکنند.قبل از هر چیزی باید دو واژه Process و Thread را تعریف کنیم. هر دو این واژه ها با مفهوم Multi tasking گره خورده اند. Multi Tasking یا چند وظیفگی به دوشکل پیاده سازی میشود :1- Multi Processing (چند پردازشی)2- Multi Threading (چند نخی)روش چند پردازشیدر این روش هر پردازش یک فضای آدرس مجزا در حافظه دارد و معمولا در سطح یک برنامه تعریف میشود . مثلا یک برنامه حسابداری یک Process جداگانه داشته و برنامه فوتوشاپ Process مختص خود را دارد.معمولا تخصیص منابع و سوئیچ بین Process ها در سطح سیستم عامل انجام میشود و سوئیچ و ارتباط بین Process ها هزینه بر است. Process ها سنگین وزن هستند و خود میتوانند از چندین Thread تشکل شوند.روش چند نخیدر این روش Thread هایی در یک فضای حافظه مشترک اجرا میشوند و در دل یک Process هستند (داخل یک برنامه هستند) . Thread ها بسیار سبک هستند و ارتباط بین آنها به سادگی ایجاد میشود .همچنین سوئیچ بین Thread ها با سرعت بیشتری انجام میشود.Process Vs Threadچرخه حیات نخ (Thread States)یک Thread دارای چرخه حیاتی است که از زمان تولد تا مرگ وضعیتهای مختلفی را به خود میبیند. وضعیتهای Thread در طول چرخه حیاتش به شرح زیر است :NewRunnableRunningNon-Runnable (Blocked)Terminated1- جدید (New) : زمانی که یک شیء از نوع Thread ساخته میشود در این وضعیت قرار میگیرد2- قابل اجرا (Runnable) : زمانی که Thread آغاز به کار میکند در این وضعیت قرارمیگیرد تا نوبت پردازشش فرا برسد. با فراخوانی متد start این وضعیت برای Thread فعال میشود.3- درحال اجرا (Running) : زمانی که نوبت اجرا به Thread میرسد و Cpu را در اختیار میگیرد در وضعیت درحال اجرا قرار میگیرد.4- متوقف (Block) : زمانی که وقفه ای در اجرا Thread ایجاد شود در این وضعیت قرار میگیرد و پس از پایان وقفه وضعیت به Runnable تغییر میکند تا در نوبت اجرا قرارگیرد. (در این وضعیت Thread خاتمه نیافته اما واجد شرایط اجرا شدن نیست)5- خاتمه یافته (Terminated) : زمانی که عملکرد Thread خاتمه میابد در این وضعیت قرار میگیرد (به عبارتی میمیرد)پیاده سازی Thread در جاوادو روش برای پیاده سازی Thread در جاوا وجود دارد :1- ارث بری از کلاس Thread2- پیاده سازی اینترفیس Runnableنحوه پیاده سازی اولclass Multi extends Thread{     public void run(){          System.out.println(&quot;thread is running...&quot;);     }     public static void main(String args[]){          Multi t1=new Multi();          t1.start();     }}در این مثال با ارث بری از کلاس Thread پیاده سازی انجام شده. بدنه اصلی Thread باید در متد run نوشته شود و برای اجرای Thread هم از متد start استفاده میشود. با اجرای این برنامه یک Thread جدید ساخته شده و محتوای متد run اجرا میشود.نحوه پیاده سازی دومclass Multi3 implements Runnable{     public void run(){          System.out.println(&quot;thread is running...&quot;);     }     public static void main(String args[]){          Multi3 m1=new Multi3();          Thread t1 =new Thread(m1);           t1.start();     }}در این روش اینترفیس Runnable باید پیاده سازی شود و مانند مثال قبل متد run نوشته شود. برای اجرا باید یک شیء از کلاس Thread ساخته شود و شیء Runnable را به متد سازنده آن  داده و با متد start آنرا اجرا کنیم.</description>
                <category>انتشارات جاواکاپ</category>
                <author>امیر رحیمی نژاد</author>
                <pubDate>Fri, 23 Apr 2021 18:34:21 +0430</pubDate>
            </item>
                    <item>
                <title>رهیافتی بر ORM در Hibernate</title>
                <link>https://virgool.io/javacup/%D8%B1%D9%87%DB%8C%D8%A7%D9%81%D8%AA%DB%8C-%D8%A8%D8%B1-orm-%D8%AF%D8%B1-hibernate-o3z2pp3s9b31</link>
                <description>سلام تو این پست قصد دارم در مورد (نگاشت اشیا به مدل رابطه ای با استفاده از Hibernate ) توضیحاتی  خدمتتون بدهم امیدوارم که براتون مفید واقع بشه...یکی از چالش های زبان های برنامه نویسی شی گرا برای کار با پایگاه داده های رابطه ای نگاشت اشیا به داده ها در جداول می باشد این مشکل به دلیل از ساختار متفاوت مدل رابطه ای و شی گرایی حاصل میشه برای درک بهتر مثال زیر رو در نظر میگیریم:فرض کنید کلاسی داریم با نام Student که دارای داده های (نام, نام خانوادگی, سن , شماره دانشجویی) می باشد به راحتی میتوانیم کلاس فوق را به جدولی به صورت زیر نگاشت کنیم:CREATE table student( 
name varchar(20),
last_name varchar(20), 
age Integer, 
id Integer PRIMARY key 
);خب این که کاری نداشت!؟مشکل اصلی وقتی هست که کلاس Student ما به یک سری از کلاس های دیگر وابستگی داشته باشد. مثال زیر را در نظر بگیرید:مدلی رابطه ای طراحی کنید که شامل موجودیت های زیر باشد:1. دانشجو:شامل نام، نام خانوادگی، سن، شناسه، کارت دانشجویی، گروه آموزشی و لیست دروس اخذ شده2. کارت دانشجویی:شامل تاریخ صدور و Serial Number3. گروه آموزشیشامل نام، شناسه، دانشجویان4. درسشامل نام درس، شناسه درس، تعداد واحد و لیست دانشجویان اخذ کننده درسو روابط به صورت زیر باشند:هر دانشجو فقط و فقط یک کارت دانشجویی داردهر کارت دانشجویی فقط و فقط به یک دانشجو تعلق داردهر تعداد دانشجو فقط و فقط در یک گروه عضویت دارندهر گروه شامل چندین دانشجو می باشدهر دانشجو تعدادی از دروس را اخذ کرده استهر درس به وسیله تعدادی دانشجو اخذ شده استهمونطور که می بینید نگاشت این موجودیت ها به سادگی مثال قبل نمی باشند. اینجاست که ما میتوانیم با استفاده از ORM مبتنی بر Hibernate بدون هیچ نیازی از دانش اولیه به مدل رابطه ای، پایگاه داده خودمون رو طراحی کنیم. با استفاده از Hibernate و استاندارد JPA می توانیم مدل خود را به صورت شی گرا طرحی کرده و نگاشت به مدل رابطه ای را به خود Hibernate واگذار کنیم. JPA انوتیشن هایی برای انواع روابط تعریف کرده که به بیان آن ها می پردازیم و سپس آن ها را در هدف خود به کار میبریم: @OneToOneاین انوتیشن برای مواقعی استفاده میشود که رابطه ما از نوع یک به یک باشد مثلا روابط:هر دانشجو فقط و فقط یک کارت دانشجویی دارد هر کارت دانشجویی فقط و فقط به یک دانشجو تعلق داردبا انوتیشن OneToOne مشخص میشوند2. @OneToManyبیانگر رابطه یک به چند می باشد مثال زیر آن را به خوبی بیان میکند:هر گروه شامل چندین دانشجو می باشد3. @ManyToOneرابطه چند به یک:هر تعداد دانشجو فقط و فقط در یک گروه عضویت دارند4. @ManyToManyرابطه چند به چند که مشابه رابطه یک به یک، دوطرفه است. در حقیقت هر کدام از مثال های زیر به تنهایی معنای (یک به چند) میدهند ولی در کنار هم بیانگر چند به چند هستند :هر دانشجو تعدادی از دروس را اخذ کرده استهر درس به وسیله تعدادی دانشجو اخذ شده استپیاده سازیبرای پیاده سازی مدل رابطه ای در مثال اصلی این پست، کافی است آن را به صورت شی گرا طراحی کرده و با استفاده از انوتیشن های ذکر شده روابط بین آن ها را بیان کنیم پس به شکل زیر پیاده سازی داده ها را انجام می دهیم:برای دانشجو@Entity
public class Student {
    @Id
    private int id;

    @Column
    private String name;

    @Column(name = &amp;quotlast_name&amp;quot)
    private String lastName;

    @Column
    private int age;

    @OneToOne
    @JoinColumn(name = &amp;quotstudent_card&amp;quot)
    private StudentCard studentCard;

    @ManyToOne
    @JoinColumn(name = &amp;quotgroup_id&amp;quot)
    private GrouB groub;

    @ManyToMany
    @JoinTable(
            name = &amp;quotstudent_course&amp;quot,
            joinColumns = @JoinColumn(name = &amp;quotstudent_id&amp;quot),
            inverseJoinColumns = @JoinColumn(name = &amp;quotcourse_id&amp;quot)
    )
    private List&lt;Course&gt; courseList;

...
}
کارت دانشجویی@Entity
@Table(name = &amp;quotstdeunt_card&amp;quot)
public class StudentCard {

    @Id
    private int serialNumber;

    @Column
    private Date IssueDate;

    @OneToOne(mappedBy = &amp;quotstudentCard&amp;quot)
    private Student student;

...
}
گروه@Entity
@Table
public class GrouB {

    @Id
    private int id;

    @Column
    private String name;

    @OneToMany(mappedBy = &amp;quotgroub&amp;quot)
    private List&lt;Student&gt; studentList;

...
}فقط برای این کلاس نکته ای که داریم اینه که سعی کنید نام هایی که برای کلاس یا فیلد ها انتخاب میکنید جزو کلمات رزرو شده SQL نباشند!(با خطای Syntax مواجه میشوید)درس@Entity
public class Course {

    @Id
    @Column(name = &amp;quotcourse_id&amp;quot)
    private int courseId;

    @Column(name = &amp;quotcourse_name&amp;quot)
    private String courseName;

    @Column(name = &amp;quotcourse_rating&amp;quot)
    private int courseRating;

    @ManyToMany(mappedBy = &amp;quotcourseList&amp;quot)
    private List&lt;Student&gt; studentList;

...
}استفاده از Entity@ برای هر کلاسی که قصد نگاشت آن را داریم الزامی است.در روابط ManyToMany همانطور که میبینید از JoinTable@ استفاده کرده ایم. این انوتیشن زمانی کاربرد دارد که بخواهیم روابط بین موجودیت ها را در جداول جداگانه توصیف کنیم پس Hibernate جدولی به نام  student_course با ستون های student_id و course_id برای ما ایجاد خواهد کرد.در نهایت Hibernate به شکل زیر اشیا را در پایگاه داده MariaDB نگاشت میکند:البته علاوه بر کلاس های اولیه که قبلا مشاهده کردید باید در فایل hibernate.cfg.xml فیلد hibernate.hbm2ddl.auto را برابر update قرار دهیم جزئیات بیشتر را میتونید در اینجا ببینیدتوجه کنید که Hibernate قابلیت های خیلی بیشتری از این دارد و اینجا صرفا مطالب محدودی از اون گفته شد.</description>
                <category>انتشارات جاواکاپ</category>
                <author>محمد سپهر ملائی</author>
                <pubDate>Wed, 14 Apr 2021 20:47:31 +0430</pubDate>
            </item>
                    <item>
                <title>طراحی اپلیکیشن دسکتاپ با Javafx</title>
                <link>https://virgool.io/javacup/%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C-%D8%A7%D9%BE%D9%84%DB%8C%DA%A9%DB%8C%D8%B4%D9%86-%D8%AF%D8%B3%DA%A9%D8%AA%D8%A7%D9%BE-%D8%A8%D8%A7-javafx-urj0c8snswyk</link>
                <description>سلام، تو این پست قصد دارم یک روال کلی از پروژه ساده دسکتاپ با javafx رو بهتون نشون بدم. برای اینکار میخوام یک Music player اولیه رو با این ابزار پیاده سازی کنم. خواهید دید که اصلا چیز سختی نیست و علاوه جذابیت خاص خودش به راحتی قابل انجام است.من از ابزار های زیر استفاده میکنم:JDK 8IntelliJ IDEA CommunityScene builderدو مورد اولی رو احتمال زیاد باهاشون آشنایی دارید، Scene builder ابزاری هست که به شما کمک میکنه جلوه بصری نرم افزار خودتون رو راحت تر پیاده سازی کنید. خروجی کد fxml میده که بعدا میتونید اون رو تو پروژه جاوا بارگیری کنید. 1. ساخت پروژه اولیهدر intellij از قسمت new project مستقیم javafx رو انتخاب کنید. برای شما پروژه ساده ای ایجاد میشود که در پکیج sample شامل controller.java , main.java, sample.fxml می باشد. میتونید به دلخواه خودتون ساختار پکیج بندی پروژه رو تغییر بدید که فعلا من اینجا برای سادگی از اینکار صرف نظر میکنم. 2. طراحی viewوارد محیط scene builder میشویم میتوانید اونو مستقیم روی سیستمتون نصب کنید یا اینکه از طریق intellij باهاش کار کنید. ترجیح من اینه که از روش اول استفاده کنم(امکانات بیشتری بهتون میده). Scene builderبه راحتی میتونید کامپوننت های مورد نیاز خودتون رو به صورت کشیدن و رها کردن به صفحه بندیتون اضافه کنید من برای کار خودم از موجودیت های زیر استفاده میکنم: AnchorPaneیکی از نگه دارنده ها در javafx هست که به شما کمک میکنه صفحه بندی مورد نظرتون رو بسازید. با استفاده از نگه دارنده ها میتونید کامپوننت ها (نظیر دکمه، تکست فیلد و نوار) رو به شکل خاصی نمایش بدید.2. ToolBarیک منوی خیلی ساده در اختیارتون قرار میده که در ابتدا فقط شامل یک دکمه هست از اون برای انتخاب موسیقی دلخواه استفاده میکنیم3. Sliderبرای نمایش وضعیت پخش موسیقی مورد نظر استفاده میکنیم(اینکه درحال حاضر در کدام قسمت زمانی پخش هستیم) همچنین باید بتوانیم با تغییر وضعیت آن، قسمت دلخواه خودمون رو بشنویم4. Textبرای نمایش ثانیه و دقیقه لحظه ای هنگام پخش استفاده میکنیم 5. Buttonیک دکمه ساده برای play و pauseخب تا اینجا کار اصلیمون رو هنوز شروع نکردیم ولی قبل از اون بیاید یه تغییر کوچیک تو صفحه ایجاد کنیم برای تغییر نوشته یک دکمه به راحتی میتونیم روی اون کلیک کرده و از منوی سمت راست با تغییر Text، متن داخل اون رو شخصی سازی کنیم ولی اگه بخوایم شکل به خصوصی (مثلا دایره ای ) به یکی از دکمه ها بدیم چی؟ یا مثلا رنگش رو چه طور عوض کنیم؟جاوا اف ایکس از نوعی css خاصی پشتیبانی میکنه که به ما این قابلیت رو میده ظاهر کاپوننت های خودمون رو شخصی سازی کنیم. این ویژگی به ما کمک میکنه تا رابط های کاربری با ظاهر چشم نوازی ایجاد کنیم (بر خلاف Swing که کامپوننت های قدیمیش واقعا تو ذوق آدم میزد :)  )در حال حاضر صرفا برای شروع روی دکمه روبروی slider کلیک کرده و از منوی سمت راست قسمت Style، ویژگی خاص fx-background-radius- را به 50% تغییر میدهیم. همچنین میتوانیم از کاراکتر های خاص html که از یونی کد های مختلف شناخته میشن برای دکمه ها استفاده کنیم.3. نوشتن کلاس Controllerاول از همه نیاز داریم به یک سری از کامپوننت های خودمون دسترسی داشته باشیم تا بتونیم تغییراتی رو هنگام اجرا اعمال کنیم پس ویژگی fx:id یکتایی به هر کدوم اختصاص میدیم. همچنین باید یکسری event (رویداد)هایی مشخص کنیم تا هنگام وقوع اونها بتونیم تغییرات را اعمال کنیم مثلا اینکه وقتی کاربر روی دکمه ای کلیک میکنه چه اتفاقی رخ بده یا اینکه موقع تغییر دادن مکان نمای slider بتونیم وضعیت پخش رو تغییر بدهیم. برای این کارها کافیه روی کامپوننت مورد نظر کلیک کرده و از قسمت سمت راست منوی code موارد زیر را تعریف کنیمکامپوننت هایی که برای آن ها شناسه تعیین میکنیم1. اسلایدر2. کلید پخش3. نمایشگر زمانرویداد ها1. Action event برای هر کدام از کلید های file و play2. همچنین یک on mouse dragged برای اسلایدرخب کارمون تقریبا با scene builder تموم شد بعد از اینکه view رو در مسیر پروژه به جای Sample.fxml کپی کردیم (فراموش نکنید ویژگی fx:controller رو در فایل fxml برابر مسیر و نام کلاس کنترلر قرار بدید)حالا باید کلاس controller خودمون رو بنویسیم برای اینکه کارمون یکم راحتتر بشه از محیط Scene builder مسیرView -&gt; Show Sample Controller Skeletonیک نسخه اولیه از کلاس کنترلر میگیریم که شامل کامپوننت ها و رویداد هایی است که تعریف کردیم. همگی را در کلاس Controller کپی میکنیمکامپوننت هایی که شناسه یکتایی بهشون دادیم همگی با انوتیشن FXML@ مشخص می شوند و نیازی به نمونه سازی اولیه ندارند.خب اینجا ما علاوه بر مواردی که در بالا با انوتیشن مشخص شده اند به یک سری کلاس های بیشتری هم نیاز داریم: MediaPlayer  File همچنین یک متغیر boolean برای تمایز بین حالت پخش و سکونpublic class Controller {

    @FXML 
    private Slider slider;

    @FXML 
    private Button playButton;

    @FXML 
    private Text timeLabel;

    private MediaPlayer mediaPlayer;

    private File file;

    private boolean isPlaying = false;
...
}

اگه بخوایم از دید کاربر به مساله نگاه کنیم برای شروع کار نیاز داریم فایل مورد نظرمون رو انتخاب کنیم یک پیاده سازی ابتدایی که میتوانیم ارائه دهیم در متد Action event برای کلید file:@FXML
void openFile&#40;ActionEvent event&#41; {

    FileChooser fileChooser = new FileChooser();
    fileChooser.setTitle(&amp;quotSelect your music&amp;quot);

    file = fileChooser.showOpenDialog(new Stage());

    Media media = new Media(file.toURI().toString());
    mediaPlayer = new MediaPlayer(media);

}هرچه بیشتر درگیر جزئیات شویم میتونیم این قطعه کد رو کاملتر کنیم مثلا در ادامه نیاز داریم که به media player بگیم که هنگام پخش مکان نمای اسلایدر رو در جای مناسب قرار بده پس در همین متد قطعه کد زیر را هم داریمmediaPlayer.setOnPlaying(new Runnable() {
    @Override
    public void run() {
        new Thread(()-&gt;{
            while (isPlaying){
                slider.setValue(mediaPlayer.getCurrentTime().toSeconds() / mediaPlayer.getStopTime().toSeconds() * 100);
                try {
                    Thread.currentThread().sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
});
میبینید که برای کارمون مجبور شدیم یک ترد(Thread) جدید هم ایجاد کنیم و در آخر برای اینکه تردمون همیشه درگیر نباشه یک sleep کوتاه هم براش میگذاریم (این کار باعث میشه تا بتونیم مکان نمای اسلایدر رو تغییر بدیم و گرنه تردمون زورش از ما خیلی بیشتر میشه ).برای Action event کلید play:@FXML
void playClicked(ActionEvent event) {
        if(isPlaying){
            mediaPlayer.pause();
            playButton.setText(&amp;quot⏵&amp;quot);
        }
        else{
            mediaPlayer.play();
            playButton.setText(&amp;quot||&amp;quot);
        }

        isPlaying = !isPlaying;
}
و همچنین برای رویداد کشیدن Slider:@FXML
public void sliderDragged(MouseEvent mouseEvent) {
    mediaPlayer.seek(new Duration(slider.getValue() * mediaPlayer.getStopTime().toSeconds() * 10));
}
توجه کنید که موارد بالا صرفا برای پیاده سازی اولیه میباشند. همونطور که گفتم هر چی بیشتر درگیر جزئیات بشیم کاملترش میکنیمسورس کد در گیتهاب</description>
                <category>انتشارات جاواکاپ</category>
                <author>محمد سپهر ملائی</author>
                <pubDate>Sat, 10 Apr 2021 00:29:24 +0430</pubDate>
            </item>
                    <item>
                <title>آخرش برای برنامه نویسی باید ریاضی بلد باشم یا نه؟</title>
                <link>https://virgool.io/javacup/should-know-math-in-order-to-learn-programming-xfl6r0xmwxvd</link>
                <description>یکی از سوال هایی که بیشتر باهاش مواجه میشم اینهاصن لازمه ریاضی بدونم؟ بعضیا میگن اره؛ بعضیا میگن نه، خب اینجا بحث میکنیم و با چند تا چالش توی زمینه های مختلف آشنا میشیمبرنامه نویسی به زبان ساده یعنی به کامپیتور بفهمونیم کاری رو که ازش میخوایم رو انجام بده. ( ساده بود، نه؟ ? )خب برای انجام دادن این کار، ما برای کامپیوتر روند اجرای اون کار رو تعریف کنیمروند اجرای ی کار میتونه روند درست کردن ی کیک باشه، روند رایت کردن روی یک CD یا حتی روند ضرب دوتا ماتریسhttp://matrixmultiplication.xyz/خیلی واضحه که برای نوشتن اون روند درست کردن کیک، باید آشپزی بلد باشید ( یا از ی آشپز کمک بگیرید ) ، برای رایت کردن روی CD در مورد مفاهیم پایه ایش چیزی بدونید و برای نوشتن روند ضرب 2 ماتریس باید در اون حد ریاضی بلد باشید ?خب با چیزایی که تا حالا گفتم میشه برداشت کرد که اگر کسی ریاضیش قوی تر باشه، لزوما برنامه نویس بهتری نیست ( میتونه باشه ولی فقط توی حوزه برنامه هایی که با ریاضی سر و کله میزنن ).ولی اگر قصد شروع برنامه نویسی رو دارید از یادگیری کمی ریاضی هم نترسید ? چون بعضی موقع ها واقعا لازم میشهیا مثلا برای درست کردن ی موتور شبیه سازی و پردازش تصویر 3 بعدی، اینجا هم به ریاضیات احتیاج داریمشما باید ی شکل 3بعدی رو توی ی مانیتور 2 بعدی به کاربر نشون بدید! سخت نیست؟از کجا بفهمیم این دوتا شکل که ممکنه زاویه ها و مکانشون تغییر کنه به هم برخورد میکنن؟ یک برنامه موتور فیزیک آنلاین که  اومده بعضی پدیده های فیزیک رایج مثل جاذبه و... رو شبیه سازی کردهالبته شما وقتی که مثلا ی بازی درست میکنی، حتما لازم نیست که بری از اول موتور پردازش نور، فیزیک و... خودت رو بنویسی - احتمالا قبلا این برنامه ها نوشته شده و به صورت کتابخونه یا نرم افزار در اختیار شما قرار داده شدهبرنامه نویسی خیلی شاخه داره - و هرشاخه درک و تحلیل مخصوص به خودش رو میطلبه اگر کسی میخواد وارد اون شاخه بشه باید چند هفته یا ماه یا حتی سال روی اون پروژه وقت بزاره یا با موانع و مشکلاتش آشنا بشهیکی سواد و تحصیلات خوبی داره میاد ی نظریه جدید در مورد پردازش موازی ( از اونجایی که cpu های جدید چند هسته ای هستن ما میخوایم از همه توان cpu استفاده کنیم - یکی از روش هاش اینه که یک کار رو به چند قسمت غیر وابسته تقسیم کنیم و تا کامپیوتر همزمان اون ها رو اجرا کنه ) میده، یکی دیگه میاد نرم افزار ویرایش صدا یا فیلم میسازه، یکی توی زمینه توسعه زبان برنامه نویسی فعالیت میکنه و....افراد مختلفی روی پروژه های مختلفی کار میکنن. نمیشه هیچکدوم رو با دیگری مقایسه کردمیبینید؟! ، دنیای برنامه نویسی بزرگه! ?? happy programming ?</description>
                <category>انتشارات جاواکاپ</category>
                <author>Hamid Bluri</author>
                <pubDate>Wed, 07 Apr 2021 11:59:38 +0430</pubDate>
            </item>
                    <item>
                <title>زبان برنامه نویسی Scala</title>
                <link>https://virgool.io/javacup/%D8%B2%D8%A8%D8%A7%D9%86-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-scala-z69kdu3lay5j</link>
                <description>زبان برنامه نویسی Scala توسط Martin Odersky طراحی شده است. این برنامه به طور رسمی برای اوایل سال 2004 برای پلتفرم جاوامنتشر شد و در ژوئن 2004 برای سیستم Net Framework منتشر شد. بعدا، Scala پشتیبانی از .net را در سال 2012 کاهش داد. اسکالا از جاوا، Haskell، لیسپ، Pizza و غیره تاثیر می پذیرد و بر روی F#، Fantom، Red و غیره تاثیر می گذارد. با Scala می توانید هر نوع برنامه ای مانند برنامه های کاربردی وب، برنامه های کاربردی سازمانی، برنامه های موبایل، نرم افزار مبتنی بر دسکتاپ و غیره ایجاد کنید.اسکالا زبانی object-functional است که هم از object-oriented پشتیبانی می کند و هم از functional programming .به چنین زبان هایی multi-paradigm گفته می شود (زبان هایی که چندین روش برنامه نویسی را پشتیبانی می کنند مانند سی شارپ). از زبان برنامه نویسی Scala به عنوان یک زبان اسکریپتی نیز می توان استفاده کرد. و یک زبان همه منظوره است.بسیاری از ویژگی های اسکالا به دلیل انتقادهایی که به جاوا می شد به آن اضافه شدند.این زبان اولین بار توسط Martin Odersky در سال 2001 طراحی شد و در سال 2003 انتشار یافت.واژه scala از دو کلمه Scalable و Language گرفته شده است.اسکالا از زبان های برنامه نوسی مختلفی تاثیر گرفته است و کدهای کوتاهی در مقایسه با بسیاری از زبان های برنامه نویسی موجود دارد.اسکالا بر روی NET. نیز اجرا می شود.آشنایی دلایل محبوبت زبان اسکالابه طور خلاصه، می‌توان گفت که هدف از ایجاد اسکالا طراحی یک جاوای بهینه‌تر بوده و جالب است بدانید که این زبان در JVM (ماشین مجازی جاوا) اجرا می‌شود. به غیر از Scala زبان‌های دیگری همچون Kotlin و Ceylon نیز بوده‌اند که سعی کرده‌اند یک جاوای بهتر باشند اما این در حالی است که در این زبان‌ها سعی شده سینتکس تا حد ممکن نزدیک به زبان جاوا باقی بماند و صرفاً منحنی یادگیری این زبان‌ها نسبت به زبان جاوا کمی بهتر شود اما اسکالا با این ذهنیت طراحی شد که محدودیت‌های زبان جاوا رفع گردیده و توسعه‌دهندگان بتوانند با شکستن ساختارها و پارادایم‌های به کار گرفته شده در زبان جاوا، کدهای کمتر اما در عین حال بهینه‌تری بنویسند و شاید یکی از دلایل سختی یادگیری این زبان هم همین مسألهٔ ساختارشکنی بوده باشد.پلتفرم ها و مجوزهازبان اسکالا بر روی پلتفرم جاوا (ماشین مجازی جاوا) اجرا می شود و با برنامه های جاوا موجود سازگار است.  از آنجا که برنامه های اندروید به طور معمول در جاوا نوشته می شوند و از کد رمزگذاری جاوا به کد رمزگذاری دالویک زمانیکه بسته بندی می شوند منتقل می گردند، سازش پذیری برنامه جاوا در Scala به خوبی با توسعه اندروید تطابق می یابد، البته باید خاطر نشان کرد، بیشتر زمانیکه رویکرد کاربردی ترجیح داده می شود.ویژگی های زبان برنامه نویسی اسکالا :رایگانمتن‌بازتابعیشی‌گراموجز و منعطفبالغ و آماده استفاده (همین حالا)استاتیک و شامل بررسی زمان کامپایل (Type-safe)دارای طیف وسیعی از کتابخانه‌ها (امکان استفاده راحت از کتابخانه‌های جاوا)فریم ورک های زیادی با استفاده از زبان برنامه نویسی scala توسعه داده شده اند و همچنین با استفاده از scala می توان برای اندروید نیز برنامه نوشت.کاربرد زبان Scala :اسکریپت ad hoc در REPLبرنامه‌های کاربردی وبهمزمان سازی نرم‌افزارهاجریان داده با Akkaایجاد برنامه‌های توزیع‌شدهتجزیه داده‌هاکتابخانه‌هاتحلیل داده‌ها با Sparkتفسیر AWS lambdaپردازش موازی دسته‌ایبرای آموزش های بیشتر با ما همراه باشید.</description>
                <category>انتشارات جاواکاپ</category>
                <author>پِرسُنال ادمین</author>
                <pubDate>Tue, 06 Apr 2021 15:13:15 +0430</pubDate>
            </item>
                    <item>
                <title>توضیحی در مورد threadها در زبان جاوا</title>
                <link>https://virgool.io/javacup/java-threads-jdkqpmie0kkj</link>
                <description>توضیح: این متن رو به عنوان توضیح thread چیه به شکل غیررسمی نوشتم، تصمیم گرفتم اینجا هم منتشرش کنم شاید برای کسی مفید بود. برنامه‌نویسی بدون ترد رو انجام دادیم ولی برامون راحته ولی با ترد می‌تونیم به کارایی بالاتر و کدهای منطم‌تری دست پیدا کنیم یا جتی چیزاهایی رو بتونیم انجام بدیم که قبلا نمی تونستیم. در این مطلب اصول اولیه thread رو یاد می‌گیریم.ما بدون آگاهی از thread، برنامه‌هامون یک نخ پردازشی داشت، همه  چیز دنبالِ هم اجرا می‌شد.اول دستورِ اول، بعد دستورِ دوم همینطور تا اخر (طبیعتا توی حلقه‌ها این اتفاق نمی‌افتاد ولی منظورم مشخصه)اما سیستم‌های ما چند تا هسته‌ی پردازشی دارند یعنی در آن واحد می‌تونن چند تا کار رو همزمان انجام بدن. (چرا چند تا هسته دارند؟ چون نمیشه یه هسته‌ی پردازشی رو از یه حدی قوی‌تر کرد، پس میان چند تا هسته پردازشی رو توی یه چیپِ واحد قرار می‌دن و اینطوری توان پردازشی رو زیاد می‌کنن)حالا چطوری می‌شه؟ یک پردازنده داریم.این پردازنده در آنِ واحد  چند تا هسته پردازشی داره (مثلا چندتا سی‌پی‌یو کوچولو در پردازنده اصلی!) یه سری پردازش داریم، مثلا برنامه فایرفاکس، تلگرام و برنامه جاوایی شما که توی jvm داره اجرا میشه.این پردازش‌ها اگر برنامه‌نویسشون مبحث thread رو بلد نباشه، هر کدوم روی یه هسته اجرا می شن، مثلا روی هسته صفر، فایرفاکس اجرا می‌شه. روی هسته ی ۱ تلگرام، بازم روی هسته‌ی ۱ برنامه جاوای شما (برنامه‌ریزی این که کی کجا اجرا بشه به عهده سیستم‌عامله.)حالا نکته‌ای که هست اینه که به ۲ دلیل ما ممکنه نخواهیم برنامه مون در آنِ واحد فقط یک کار رو انجام بده.دلیل ۱: وقتی پردازنده بیشتر از یک هسته پردازشی داره، اینکه برنامه‌ما فقط یک thread داشته باشه و فقط روی یک هسته پردازشی اجرا بشه به لحاظ قدرت پردازشیِ به یک هسته از پردازنده محدود هستیم اما اگر چند تا thread داشته باشیم توان پردازشی بیشتری در اختیارمون قرار می‌گیره. (البته به صورت خطی رشد نمی‌کنه، اگر خیلی زیاد thread داشته باشیم اثر عکس میده)دلیل ۲: برنامه ما، چند تا کار همزمان رو باید انجام بده، مثلا تلگرام همزمان داره تایپ کردنِ من رو هندل می‌کنه و همچنین پیام‌هایی که میاد رو از سرور می‌گیره و رابط ظاهری رو آپدیت می‌کنه.پس ما از ترد‌های مختلف (یا فارسی بگم، نخ پردازشی) استفاده می‌کنیم.همین مثال تلگرام رو بریم جلو، ۲ هسته پردازشی براش فرض کنید.هسته اول که رابط گرافیگی رو هندل می‌کنه و کارای گرافیکی رو انجام می‌ده مثلا هندل کردن رفتن از این صفحه به اون یکی صفحه.هسته دوم هم کارهای پس‌زمینه مثلا ارتباط با سرور رو انجام می‌ده.اگر این ۲ تا هسته نباشن (و فقط یک هسته باشه) برنامه‌نویسی چنین چیزی خیلی سخت می‌شه مثلا من وقتی تایپ می‌کنم نمی‌تونه اطلاعات رو از سرور آپدیت کنه، یا اگر بخواد سرور رو بخونه، نمی‌تونه همزمان به تایپِ من رسیدگی کنه. (البته این سختی برای جاوا و بدون امکانات خاص مثل callback یا java.nio برقراره، ولی event loop در javascript این کار رو خیلی زیبا انجام می‌ده.)اما وقتی که چند تا ترد داشته‌باشیم، این ترد‌ها به شکل «تقریبا مستقل از هم» به کارشون ادامه می‌دن.مستقل بودنشون از این جهته که یکیشون ممکنه کاری برای انجام داشته باشه و انجام بده، اون یکی ممکنه کاری نداشته باشه (مثلا تایپ نکنم) یا اصلا اینترنتم قطع بشه و اون یکی نتونه کار کنه ولی این یکی کار می‌کنه.اما به هم مربوطن و مثل ۲ تا برنامه جدا نیستند. چرا؟چون مثلا وقتی که تایپم تموم بشه و ارسال کنم، دکمه ارسال رو می‌زنم، باید قسمت UI به صفِ کارهای تردِ شبکه این رو اضافه کنه که این پیام رو بفرست و خبرش رو بده بهم که اگر ارسال شد تیک بزنمش.یا اینکه می‌پرسه از تردِ شبکه که آیا پیام جدیدی اومد که من نشونش بدم؟یعنی این‌ تردها به شدت با هم ارتباط دارند و به هم نیازمند هستند.مثال ساده‌ش کار گروهیه. شما در زمان‌های مشخصی برای یه هدف معین همکاری می‌کنید. این همکاری‌تون برای یه نتیجه واحده ولی هر کدوم یه کار متفاوت می‌کنید و از نتیجه اون یکی هم استفاده می‌کنیم یا یکیتون بقیه رو مدیریت می‌کنه و نتایح رو با هم ادغام می‌کنه.راستی یادمون نره که ما ۲ تا مفهوم داریم، یکی هم‌روندی (concurrency) و یکی اجرای موازیه (parallel)در حالت هم‌روند، برنامه چند تا ترد داره و «به نظر می‌رسه» همشون با هم در حال اجرا هستند. حالا ممکنه واقعا این هسته‌ها روی هسته‌های پردازشی مختلفی در حال اجرا باشن یا به نوبت روی یک هسته اجرا بشن. (این نوبت‌دهی رو سیستم‌عامل هندل میکنه همونطور که گفتم)اما مفهوم دوم اجرای همزمانه. (parallel)به این صورت که این ۲ تا ترد «واقعا همزمان روی ۲ تا هسته مختلف» اجرا بشن.ولی همونطور که گفتم این دومی دست سیستم‌عالمه و در زمان اجرا تصمیماتش رو می‌گیره و دست من و شمای برنامه‌نویس نیست. ما فقط می‌تونیم مشخص کنیم حالت اول بشه یعنی چند تا ترد داشته باشیم که در آنِ واحد در وضعیت اجرا باشند. تا اینجا همه چی خوب و خوشحاله، فقط مفهوم ترد رو فهمیدیم اما قسمت سختش اینه که هسته‌ها بخوان با هم حرف بزنن یا ارتباط برقرار کنن یا از یک منبع مشترک استفاده کنند. اینکه بخوان با هم صحبت کنن که مشخصه، مثلا یکیشون به باقی دستور بده که این پردازش رو انجام بده تا من از نتیجه‌ش استفاده کنم.فرض کنید که ۴ تا آرایه داریم و می‌خوایم مجموع هر کدوم رو حساب کنیم و بعد از روی این، جمع کل رو به دست بیاریم.چیکار می‌کنیم؟ ۴ تا ترد می‌سازیم که هر کدوم یه آرایه رو محاسبه کنن.بعد لازمه توی هسته اصلیمون، نتیجه رو بگیریم ازشون (مثلا یه جایی ذخیره کردن) و عملیات نهایی رو انجام بدیم روش.باید یه جوری بگیم آقا یا خانمِ ترد، شما اجرا شو، کارت تموم شد خبر بده بهم.اینجا از start و join استفاده می‌کنیم.مثلا میگیم:// main thread:
t1.start();
t2.start();
t3.start();
t4.start();

// now they wre working concurrently

t1.join(); //wait for t1
t2.join(); //wait for t2
t3.join(); //wait for t3
t4.join(); //wait for t4
long sum = t1.ans + t2.ans + t3.ans + t4.ans;متد join، در واقع یه جور delay برای هسته فعلیمون هست. به این صورت که اینقدر صبر کن تا اون هسته مد نظر کارش تموم شه.خب یعنی اینطوری میشه برنامه که به همه ۴ تا ترد دیگه می‌گه کارشون رو شروع کنن و بعد به اولی میگه من صبر می‌کنم تو کارت تموم شه.حالا اولش کارش تموم شد همین رو به دومی میگه.حالا ممکنه دومی کارش زودتر تموم شده باشه و دیگه این delay نخوره یا ممکنه دومی هم کارش طول بکشه حالا برای دومی صبر می‌کنه.همینطور برای سومی و چهارمی.حالا که هر ۴ تا عملیاتشون تموم شده و نتیجه آماده است  و از ans استفاده می‌کنیم. (فرض کنیم نتیجه جمعشون رو توی یه متغیر توی شی خودشون به نام ans نوشتن.حالا همه این‌ها برای این بود که ۲ تا کد موازی اجرا بشن.اما اگر بخوان که از یه «منبع مشترک» استفاده کنن چی؟مثلا یه متغیر شمارنده (چیزهای پیچیده‌تر هم می‌تونن باشن فقط آرایه یا فایل مشترک)مثلا هر کدوم می‌خوان یه متغیر مثل count رو زیاد کنند.چاره چیه؟ اول بگم مشکلی که پیش میاد چیه؟فرض کنید که ۲ تا ترد دقیقا همزمان بخوان count رو زیاد کنن.هر کدوم نگاهش می‌کنن می‌گن خب صفر هست و من باید ۱ بنویسم توش، بعد توش یک می‌نویسن ولی در واقع باید ۲ نوشته بشه.اینجا ۲ تا پیشنهاد برای رفع مشکل داریم.یکی اینکه عملیات رو atomic تعریف کنیم، یعنی به جای int معمولی، بیایم atomic integer استفاده کنیم.اتمیک یعنی هرکاری با من داری رو توی یه حرکت انجام بده، و تا زمانی که تو داری استفاده می‌کنی کس دیگه‌ای دست نمی‌زنه. یعنی چی؟ یعنی ۲ تا تردی که همزمان می‌خواد به int count دست بزنن، به یکیشون می‌گه دست نگه دار، به دومی می‌گه خب هرکاری داری انجام بده، بعد که کارش تموم شد نوبت دومی میشه. اتمیک بودنش یعنی اینطوری نیست که اول بگه حالا می‌خونم بعد کارم رو انجام می‌دم و می‌نویسم، خوندن و نوشتن رو توی یه مرحله انجام می‌ده و تا زمانی که توی این مرحله هست، ترد دیگه ای حتی اجازه خوندن هم نداره. (مطالعه بیشتر)اما یه چیز دیگه هم داریم به اسم بلوک‌های سنکرون.به این صورته که ما یه سری بلوک سنکرون (یا متد سنکرون) داریم. این بلوک‌های سنکرون اینطوری هستند که برنامه‌نویس می‌گه بلوک‌ها قراره روی یه منابع مشترکی کار کنند که اگر همزمان دست بزنن بهش، خراب می‌شه. پس از جاوا می‌خوایم دسترسی یکیشون رو در آن واحد میسر کنه (به عبارت دقیق تر mutual exclusion).حالا چطوری بگیم این بلوک سنکرون روی چی داره کار می‌کنه که کس دیگه ای روی این شی خاص دست نبره؟به هر بوک سنکرون یه شی می‌دیم، این قفل در واقع یه object یا یه class هست. تا وقتی که یه بلوک سنکرون با شی X در جال اجراست، هیچ بلوک سنکرون دیگه ای نمی‌تونه قفل شی  X رو بگیره و عملا اجرا یشه.می تونه روی شی Y از همون کلاس کار کنه ها، ولی همون شی نه.حالا متد سنکرون هم عملا یه بلوک هست که روی this یا همون آبجکت لاک می‌شه، تا وقتی که این متد در حال اجرا یاشه، هیچ متد سنکرون دیگه‌ای «روی این شی» اجرا نمیشه.سینتکس ساخت ترد هم دو مدله.اولی اینکه یه کلاس داشته باشیم و از Thread ارث‌بری کنه و متد runش رو override کنیم و توش دستوراتمون رو بنویسیم. ساخت این مدل ترد سینتکسش راحت تره ولی سختیش اینه که باید کلاسمون الزاما از Thread ارث‌بری کنه و نه چیز دیگر.دومی هم اینکه کلاسمون اینترفیس Runnable رو implement کنه، باز هم کدهامون رو توی تابع runش می‌نویسیم با این تفاوت که موقع ترد ساختن، یه شی از اون کلاسمون که Runnable رو implement کرده به ترد می‌دیم.هر دو تا حالت، در صورت اجرای متد start روی thread، میاد و تابع ران رو به صورت موازی اجرا می‌کنه.سینتکس ترد را اینجا ببینید.نکته کنکوری: چرا ما تابع run رو نوشتیم ولی باید start رو صدا کنیم؟چون run یه تابع معمولیه و ما نوشتیمش، اگه اون رو صدا کنیم، فقط انگار یه متد معمولی رو صدا زدیم و به صورت sequential اجرا می‌شه! اما متد start یه متد سطح پایین با پیاده‌سازی خاص هست که با سستم‌عامل در ارتباطه و یه ترد جدید می‌سازه و تابع run ما رو توش اجرا می‌کنه.دیگه نکته اضافه اینکه ساخت تردِ معمولی (همین که ما می‌سازیم و به kernel thread هم معروفه)، کار خیلی کندیه، نسبت به اجرای یه تابع معمولی.و هر ترد هم برای خودش منابع می‌گیره و اینکه ما بیایم تردهای زیاد بسازیم اتفاق خوبی نمی‌افته، فقط فشار روی سیستم‌عامل برای مدیریت ترد‌ها بیشتر می‌شه. مثلا ما یه آرایه ۱۰۰۰ در n داریم و می‌خوایم مجموع همش رو حسابی کنیم، خوب نیست که بیایم ۱۰۰۰ تا ترد بسازیم، چون اینطوری کارایی از همون یک ترد هم کم‌تر می‌شه، بلکه ۴-۶ تا ترد  می‌سازیم. توجه: در زبان های دیگه مثل go ترد‌های غیرکرنلی که سبک‌تر باشن هم وجود داره. در مورد go routine می‌تونید بخونید. در مورد ترتیب و مدیریت ترد‌ها: از اون جا که سیستم‌عامل مدیریت منابع و ترد‌ها رو داره، روی ترتیب اجرای تردها هیچ حسابی نمی تونیم بکنیم. ممکنه ۲ تا کد که انتظار داریم همزمان اجرا بشن، اصلا دومی رو اجرا نکنه به مدت یک دقیقه، بعد ۳ دقیقه دومی رو اجرا کنه (اصولا اگه سیتسم‌عامل باشعوری(!) باشه این کارو نمی‌کنه چون همه چی خراب می‌شه ولی امکانش هست). حالا این مثال فرضی بود ولی عملی ترش اینه که اگه ما توی ۲ تا ترد بگیم یکی ۱ تا ۱۰۰ رو چاپ کنه و دومی a تا z رو، هیچ حسابی روی ترتیب چاپشون نمی‌تونیم بکنیم، ممکنه اول ۱ تا ۱۰ چاپ بشه بعد a  تا c و باز همینطوری، ممکنه اول ۱ تا ۱۰۰ چاپ یشه. توی یه سیستم واحد هم با هر بار اجرا ترتیب‌ها عوض میشه!در مورد گرسنگی یا starvation، اینطوریه که وقتی یک ترد روی یه شی قفل کرده و توی بلوک سنکرون داره کلی عملیات انجام می ده (این دیگه دست برنامه نویسه) حالا ترد‌های دیگه که منتظرن اون قفل رو باز کنه و بتونن وارد بلوک سنکرون خودشون بشن، عملا دقیقه‌ها باید منتظر بمونن و باقی کدهاشون اجرا نمیشه و اصطلاحا دچار گرسنگی یا starvation می‌شن چون اجرا نمی شن و اون تسکی که دارن انجام می‌دن رو زمین می‌مونه.حالتِ بدِ دیگه، deadlock هست. بن‌بست!اینطوریه که ترد دوم منتظره ترد اول تموم شه.ترد اول هم منتظره ترم دوم کارش تموم شه، یا منتظره بره توی بلوک سنکرونش (در حالی که اولی هم توی بلوک سنکرونه) اینجا هیچ کدوم نمی تونه پیش‌رفت کنه و تو همین وضعیت باقی می‌مونیم!این حالت‌ها واقعا پیدا کردنش سخته و ممکنه سال‌ها برنامه درست کار کنه ولی یهو به همچین حالتی برسه و دیگه کار نکنه! واقعا پیدا و رفع کردن چنین باگ‌هایی نبوغ و دقت می‌خواد. در مورد ساحتمان داده‌های هم‌روند (یا thread-safe) هم بگم که اینا یه سری ساختمان داده هستند که در مقابل استفاده چند ترد همزمان امن هستند، یعنی چی؟ مثل اون atomic integer که یه متغیر امن بود، این‌ها لیست و مپ و غیره هستند.به طور ساده بخوایم در نظر بگیریم لیست thread-safe  که یه لیست معمولی هست که همه متدهاش سنکرون شده!کاراییش البته معمولا از چیزی که گفتم بهتره چون پیاده سازیش واقعا اینطوری نیست، مثلا عملیات‌های get به صورت همزمان انجام می‌شه ولی عملیات‌های set به صورت یکی یکی و سنکرون.اینا کاراییشون اگر توی یک نخ استفاده بشن از ساختمان داده‌های عادی کم‌تره چون باید اول هر متد اون چک کردن قفل و اینا رو انجام بدن ولی توی استفاده چند تا ترد در مجموع بهترن (کد منبع اینا رو هم بخونید جالبه، کلی چیزای خفنِ ترد می بینید)در نهایت این رو ببینید اگر دوست داشتید:https://www.youtube.com/watch?v=alJuV66KMEM</description>
                <category>انتشارات جاواکاپ</category>
                <author>روزبه شریف‌نسب</author>
                <pubDate>Tue, 06 Apr 2021 12:09:18 +0430</pubDate>
            </item>
                    <item>
                <title>کد تمیز چیست و چرا اهمیت دارد؟</title>
                <link>https://virgool.io/javacup/%DA%A9%D8%AF-%D8%AA%D9%85%DB%8C%D8%B2-%DA%86%DB%8C%D8%B3%D8%AA-%D9%88-%DA%86%D8%B1%D8%A7-%D8%A7%D9%87%D9%85%DB%8C%D8%AA-%D8%AF%D8%A7%D8%B1%D8%AF-l5ztrxta1fbw</link>
                <description>clean the poor codesمقدمهدر این نوشته و نوشته های بعد، می‌خواهیم درباره &quot;کد تمیز&quot; صحبت کنیم.. اما کد تمیز واقعا چی هست؟من می‌تونم ساعت‌ ها در مورد خصوصیات کد های تمیز باهاتون صحبت کنم و از این کار خیلی هم لذت می‌برم، اما خودم رو در جایگاهی نمی‌بینیم که بخواهم تعریف خودم رو از ماهیت کد تمیز ارائه بدم.. دلیلش هم خیلی ساده است; چون اساتیدی وجود دارند که قبلا این کار رو به نحو احسنت انجام دادند. یکی از این اشخاص آقای &quot;رابرت سی مارتین&quot; (Robert C Martin) هست، که چندین کتاب کامل هم در این باره نوشته.. اسم یکی از بهترین کتابهای آقای مارتین &quot;معماری تمیز&quot; هست; که خوندنش رو به همه کسانی که به شکلی با کد سر و کار دارند، پیشنهاد میکنم.Clean Architecture: A Craftsman&#x27;s Guide to Software Structure and Design (Robert C. Martin Series)اگر وقت یا انگیزه لازمه برای خوندن این کتاب رو دارید، که چه بهتر.. اگر هم نه که اشکالی نداره; چون مطالب این نوشته در واقع چکیده ای از مقدمه این کتاب هست. که با هم بررسی می‌کنیممباحثی که مرور خواهیم کرد به شرح زیر است:مهارت چیست؟کد بد یا کثیف چیست؟نشانه های شلختگیطراحی مجددنگرشمسئله اصلیهنر کد تمیزکد تمیز چیست؟ نتیجه ‌گیریمهارت چیست؟برای خوب انجام دادن هر کاری نیاز به مهارت داریم، که برنامه نویسی و کد زدن هم از این قاعده مستثنی نیستند. به دست آوردن مهارت در ۲ بخش خلاصه میشه:دانشتمرینشما باید اصول و شیوه‌های شناخت الگو را مثل یک هنرمند یاد بگیرید.. و این دانش را با انگشتان، چشم‌ها و تمام وجودتان احساس کنید و سخت کار و تمرین کنید.من می‌تونم فیزیک دوچرخه سواری رو به شما یاد بدم. علم فیزیک در این سطح خیلی با ریاضیات کلاسیک در ارتباطه; و ریاضیات کلاسیک هم خیلی سر راسته. در واقع معادلات جاذبه، اصطکاک، تکانه زاویه‌ای و غیره رو میشه در یک برگه کاغذ نوشت.. و با این فرمول‌ها می‌تونم بهتون ثابت کنم، که دوچرخه سواری یک عمل کاملا ممکن هست; حتی میتونم تمام دانشی که برای عملی کردنش نیاز دارید رو بهتون منتقل کنم. اما باز هم اولین بار که سوار دوچرخه بشید، زمین می‌خورید... کد نوشتن هم دقیقا همینه.نوشتن کد های تمیز کار نسبتا مشکلی هست. برای این کار به چیزی بیش از دونستن الگوها و اصول نیاز داریم. باید سخت کار کرد و عرق ریخت. باید تمرین کرد و شکست خورد. باید شکست ها رو دید و تجربه کسب کرد. باید زمین خوردن ها و بلند شدن ها رو تجربه کرد.به سلسله مراتبی که از اینجا به بعد بررسی میکنیم، دقت کنید:کد بد یا کثیف چیست؟برای درک بهتر موضوع که چرا باید تمیز کد نوشت، بگذارید ابتدا از کد کثیف شروع کنیم.همه ما در مقطعی کد هایی نوشتیم که خودمون هم دوست نداشتیم بهشون دست بزنیم. چون Fragile یا شکننده بوده‌اند.. و با کوچک ترین تغییری خیلی از بخش ها تحت شعاع قرار می‌گرفتند.. چنین برنامه ای کاملا در هم تنیده شده (Coupling) و کوچکترین تغییرات در اون زمان و هزینه زیادی میبره. ما در طول یک کد بد به سختی قدم بر می‌داریم. قدم که نه در واقع در باتلاقی از خاربن‌های در هم تنیده و تله‌های مخفی تقلا می‌کنیم. برای یافتن مسیر به دنبال نشونه های تغییرات در حال وقوع می‌گردیم; اما تمام چیزی که می‌بینیم کدهای بی معنی بیشتر و بیشتر هست. در یک جمله میشه گفت: کد بد یعنی شلختگیقطعا با چنین کدی روبرو شدید (یا شاید حتی چنین کدی نوشتید) .. اما واقعا چرا؟آیا می‌خواستید سریع پیش برید؟ آیا عجله داشتید؟ آیا به دِدلاین پروژه نزدیک بودید و باید کار رو جمع می‌کردید؟ آیا وقتی برای ریفکتور و تمیز کاری نداشتید؟ آیا دپارتمان های دیگر وابسته به پیشرفت کار شما بوده‌اند، و مجبور بودید نیازهای اون ها رو بر آورده کنید؟ دلایل بیشماری می‌تونه وجود داشته باشه.همه ما این کارها را انجام دادیم. همه ما به ریخت و پاشی که درست کرده بودیم نگاه کردیم و سپس مرتب کردنش رو به روز دیگری موکول کردیم. همه ما آسودگی ناشی از کار کردن برنامه نامرتب خودمون را حس کردیم و تصمیم گرفتیم که انجام کار شلخته بهتر از انجام هیچ کاری هست. همه ما گفتیم که بعدا بر می‌گردیم و به هم ریختگی رو مرتب و کد ها رو ریفکتور می‌کنیم... پس قطعا با قانون LeBlanc آشنا نبوده ایم. این قانون میگه: بعدا یعنی هیچوقت..نشانه های شلختگیتیم‌های توسعه نرم افزار یکی از اجتماعاتی هستند، که شلختگی کد آثار خودش رو به خوبی در اونها نشون میده.تیم‌هایی که در ابتدای یک پروژه بسیار سریع در حال حرکت بوده‌اند، خودشون رو در حال حرکت با سرعت حلزونی می‌بینند. هر تغییری که در کد ایجاد کنند، چند قسمت دیگه اپلیکیشن رو خراب می کنه. افزودن هرگونه ویژگی یا تغییرات در سیستم مستلزم اینه که: گره خوردگی‌ها، پیچ و تاب‌ها و مشکلات &quot;درک شوند&quot; تا بتونید تعداد بیشتری  گره و پیچ و تاب اضافه کنید. با گذشت زمان شلختگی بسیار بزرگ و عمیق میشه، به گونه ای که دیگه راهی برای مرتب کردنش نیست;با بیشتر شدن شلختگی، بهره‌وری تیم همچنان رو به کاهش میره، و در نهایت به صفر نزدیک میشه. با کاهش بهره وری، مدیریت معقول ترین کار رو انجام میده و به امید افزایش بهره وری، افراد بیشتری رو به پروژه اضافه میکنه..اما آن کارکنان جدید سیستم را نمی‌شناسند. آنها تفاوت بین تغییرات منطبق با طراحی و تغییراتی که باعث نا کارآمدی طراحی می‌شوند را نمی دانند. علاوه بر این، آنها و هر کس دیگری که در تیم حضور دارند، تحت فشارهای هولناکی برای افزایش بهره وری قرار دارند. بنابراین همه آنها بیشتر و بیشتر باعث شلختگی می‌شوند و باعث می‌شوند که بازدهی هر چه بیشتر به سمت صفر برسه.mess-oriented productivity over timeطراحی مجددسرانجام تیم توسعه دهندگان نا امید شده و به مدیریت اطلاع می دهند که نمی توانند به توسعه چنین سورس کدی ادامه دهند. آنها خواستار طراحی مجدد هستند. مدیریت نمی‌خواهد منابع خود را برای طراحی مجدد پروژه جدید صرف کند ، اما وحشتناک بودن بهره‌وری نیز غیر قابل انکار است.. و در نهایت تیم توسعه دهندگان به خواسته شان میرسند و طراحی مجدد با هدف بهبود کیفیت و رفع مشکلات آغاز می‌شود.پس تیم جدیدی تشکیل داده می‌شود; از آنجایی که این یک پروژه سبز (green-field project) است، پس همه می‌خواهند بخشی از آن باشند و از ابتدا چیزی زیبا خلق کنند. اما فقط درخشان ترین اعضا برای این تیم جدید انتخاب می‌شوند; و باقی باید به کار کردن روی سیستم قدیمی ادامه دهند.اکنون دو تیم در یک مسابقه هستند. تیم جدید باید یک سیستم جدید بسازد که همه کارهایی را که سیستم قدیمی انجام می دهد را انجام دهد. نه تنها این ، آنها باید با تغییراتی که به طور مداوم در سیستم قدیمی ایجاد می شوند همگام شوند. مدیریت تا زمانی که سیستم جدید نتواند هر کاری را که سیستم قدیمی انجام می دهد انجام دهد ، سیستم جدید را جایگزین سیستم قدیمی نخواهد کرد.چنین مسابقه ای می‌تواند مدت بسیار زیادی طول بکشد، حتی سالها.. و پس از اتمام این مسابقه اعضای اصلی تیم جدید اکثرا جایگزین شده‌اند و تیم فعلی هم ساختار یک طراحی مجدد دیگر است. اگر حتی یک قسمت کوچک از داستانی که من گفتم را تجربه کرده‌اید ، پس از قبل می دانید که تمیز کردن کدهای خود صرفاً مقرون به صرفه نیست. بلکه در اینجا مسئله بقا در این حرفه مطرح است.نگرشآیا تا به حال درگیر چنین شلختگی شده‌اید، که هفته‌ها طول بکشد تا کاری را که باید ساعتها طول بکشد را انجام دهید؟ آیا دیده‌اید تغییری در صدها ماژول مختلف ایجاد می‌شود در حالی که باید تنها در یک خط ایجاد شود؟ این علائم خیلی شایع هستند. اما چرا این اتفاق برای کد ما می‌افتد؟ چرا کد خوب خیلی زود می‌پوسد و به کد بد تبدیل می شود؟ توضیحات زیادی برای این مورد داریم.ما شکایت داریم که نیازهای پروژه به طریقی تغییر می‌کنند که طرح اصلی را خنثی ‌می‌کنند... ما ناراحتیم که بازه های زمانی فشرده، برای انجام کار صحیح کوتاه است... ما در مورد مدیران و مشتریان عجول و انواع بازاریابی‌های بی فایده صحبت می‌کنیم....مشکل در سرنوشت ما نیست، بلکه در خودمان است. ما غیر حرفه ای هستیم.ممکن است پذیرش این حقیقت بسی تلخ باشد. اما بیایید با آن مواجه شویم.. مدیران و بازاریابان برای دریافت اطلاعات لازم ، به ما نگاه می‌کنند. کاربران برای برطرف کردن نیازمندی‌ها به ما نگاه می‌کنند.. مدیران پروژه از ما انتظار دارند که به پیش برد برنامه کمک کنیم.. و ما عمیقا درگیر برنامه ریزی پروژه هستیم و مسئولیت هرگونه خرابی را به عهده می‌گیریم. به خصوص اگر این خرابی ها مربوط به کد بد باشند.ممکن است بگویید: &quot;اگر آنچه را که مدیر می‌گوید، انجام ندهم، اخراج می‌شوم.&quot; اکثر مدیران حقیقت را می‌خواهند، اکثر مدیران کدهای خوب می‌خواهند، حتی وقتی در مورد برنامه وسواس دارند. آنها ممکن است با شور و شوق از برنامه‌ها و نیازمندی‌ها دفاع کنند؛ چون این کار آنهاست.. و این وظیفه شماست که با اشتیاق برابر، از کد دفاع کنید. &quot;غیر حرفه‌ای ترین&quot; رفتار یک توسعه دهنده این است، که به خواسته مدیرانی که ریسک ایجاد شلختگی‌ها را نمی‌فهمند تن در دهد.مسئله اصلیبرنامه‌نویسان با مجموعه ای از مسائل پایه ای روبرو هستند. مانند محدودیت زمانی و فرا رسیدن ددلاین پروژه. و یکی از دلایل اصلی ایجاد شلختگی نیز همین است. اکثرا توسعه دهندگان تحت فشار و برای رساندن پروژه به ددلاین شروع به ایجاد شلختگی می‌کنند. اما در واقع، شلختگی فورا شما را کند می‌کند و شما را مجبور می‌کند که ددلاین را از دست بدهید. تنها راه برای رسیدن به ددلاین (تنها راه سریع پیشبردن کار) این است که همیشه کد را تا حد ممکن تمیز نگه دارید.به عبارتی دیگر: «تنها راه سریع رفتن، تمیز رفتن است.»هنر کد تمیزفرض کنیم که به این نتیجه رسیده اید که، کد کثیف مانع قابل توجهی است. و پذیرفته اید که تنها راه سریع رفتن، تمیز رفتن است. حال این سوال پیش می‌آید: &quot;چگونه کد تمیز بنویسم؟&quot; اگر ندانیم تمیز بودن کد به چه معناست، تلاشمان برای نوشتن کدهای تمیز بیهوده است...نوشتن کد تمیز بسیار شبیه به نقاشی کشیدن است. اکثر ما تفاوت یک نقاشی هنری خوب و بد را از هم تشخیص می‌دهیم، اما این قدرت تشخیص بدان معنا نیست که ما میدانیم چگونه نقاشی بکشیم.. و همین  ماجرا برای کدهای ما هم صادق است... قدرت تشخیص کد های تمیز از کدهای کثیف، هرگز بدان معنا نیست که ما می‌دانیم &quot;چگونه تمیز کد بنویسیم...&quot;نوشتن کد تمیز مستلزم استفاده منظم از تکنیک های بی شماری است که از طریق حس &quot;تمیزی&quot; با زحمت به دست آمده اند. این حس کردن است که مهم است. برخی از ما با آن متولد می‌شویم و برخی از ما باید برای به دست آوردنش بجنگیم. این حس نه تنها قدرت تشخیص کد خوب و بد را به ما می‌دهد، بلکه همچنین استراتژی و انضباط لازم را، برای تبدیل کد کثیف به کد تمیز را به ما نشان می دهد.یک برنامه نویس بدون &quot;حس تمیزی&quot; می تواند به یک ماژول به هم ریخته نگاه کند و به هم ریختگی را تشخیص دهد اما نمی داند در مورد آن باید چه کاری انجام دهد. و یک برنامه نویس با &quot;حس تمیزی&quot; به یک ماژول بی نظم نگاه می کند و گزینه ها و دگرگونی ها را جهت تمیز کردن آن مشاهده می کند.این &quot;حس&quot; به برنامه نویسان کمک می کند تا بهترین تغییرات را انتخاب کنند و آنها را راهنمایی می‌کند تا توالی رفتار و حفظ تحولات را، برای رفتن از اینجا به آنجا درک و ترسیم کنند. به طور خلاصه ، یک برنامه نویس که کد تمیز می نویسد، هنرمندی است که می تواند یک صفحه خالی را از طریق یک سری تغییرات شکل گرفته به یک سیستم با کد زیبا تبدیل کند.کد تمیز چیست؟احتمالا به تعداد برنامه نویس‌ها تعاریف مختلف برای کد تمیز وجود دارد.. موارد زیر برگزیده ای است از نظرات افراد شناخته شده و عمیقاً با تجربه که نظرات خود را با رابرت مارتین به اشتراک گذاشته اند:خالق سی پلاس پلاس - Bjarne Stroustrupمن دوست دارم کد من زیبا و کارآمد باشد. منطق باید سر راست باشد تا پنهان کردن باگ‌ها دشوار باشد، وابستگی‌های حداقلی برای سهولت در نگهداری، کنترل کامل خطا مطابق با یک استراتژی تکه به تکه و عملکرد نزدیک به بهینه، به گونه‌ای که مردم را وسوسه نکند تا کد را با بهینه‌سازی های غیر اصولی شلخته کنند. کد تمیز یک کار را به خوبی انجام می‌دهد: خواندن کد تمیز لذت بخش است. خواندن آن باید لبخند را به لبان شما بیاورد، همان‌گونه که یک جعبه موسیقی خوش ساخت و یا یک ماشین با طراحی زیبا باعث می‌شود لبخند بزنیدگردی بوچ - Grady Boochکد تمیز ساده و سر راست است. کد تمیز مثل یک نثر خوب نوشته شده است. کد تمیز هرگز هدف طراح را مبهم نمی‌کند بلکه پر از انتزاعات واضح و خطوط کنترل سر راست است.موسس OTI - آقای Dave Thomasکد تمیز میتواند بجز نویسنده اصلی آن، توسط یک توسعه‌دهنده دیگر نیز خوانده شود و بهبود یابد. این کد Unit test و Acceptance test دارد. این کد اسامی معنی دار دارد. کد تمیز به جای اینکه راههای زیادی برای انجام یک کار ارائه کند، یک راه برای انجام یک کار دارد. کد تمیز حداقل وابستگی‌ها، که به طور واضح تعریف شده اند، و یک API واضح و حداقلی را ارائه می‌دهد. کد باید دانا باشد زیرا بسته به زبان، تمام اطلاعات لازم را نمی توان به طور مشخص و به تنهایی با کد بیان کرد.میشل فیدرز - Micheal Feathersمن می‌توانم تمام خصوصیاتی را که در کد تمیز به آن توجه می‌کنم ذکر کنم، اما کیفیت فرا معماری وجود دارد که بر تمام آنان ارجح است. «همیشه به نظر می‌رسد که کد تمیز توسط کسی نوشته شده است که به آن اهمیت داده است.» هیچ چیز واضحی وجود ندارد که بتوانید انجام دهید تا کد بهتر شود. به همه این موارد توسط نویسنده کد فکر شده است و اگر سعی دارید پیشرفت‌ها را تصور کنید، به جایی که هستید برمی‌گردید، جایی که از کد شخصی که برای شما باقی گذاشته تشکر می‌کنید - کدی که توسط کسی که عمیقاً به این مهارت اهمیت می‌دهد به جا گذاشته شده است.نتیجه گیریکتاب های مربوط به هنر قول نمی دهند شما را یک هنرمند کنند. تنها کاری که آنها می توانند انجام دهند این است که برخی از ابزارها ، تکنیک‌ها و فرایندهای فکری را که سایر هنرمندان استفاده کرده اند، را به شما منتقل کنند. بنابراین این نوشته نیز نمی تواند به تنهایی، نوید برنامه نویس شدن خوبی را به شما بدهد. به عبارتی نمی‌تواند آن &quot;حس تمیز&quot; را به شما القا کند. تنها کاری که می تواند انجام دهد این است که روندهای فکری برنامه نویسان خوب و ترفندها ، تکنیک‌ها و ابزارهایی را که آنها استفاده می کنند را به شما نشان دهد.نوشتن کد خوب به تنهایی کافی نیست. کد باید در طول زمان تمیز بماند. همه ما با گذشت زمان شاهد پوسیدگی و تخریب کد هستیم. بنابراین ما باید در جلوگیری از این امر نقش فعالی داشته باشیم..در طول زمان تجربه به من ثابت کرده که تنها راه پیشرفت، ابتدا دانش و سپس تمرین، تمرین و تمرین برای کسب مهارت هست.ویالونیست کنسرتی در راه رسیدن به محل اجرا گم شده بود.. وی پیرمردی را در گوشه ای متوقف کرد و از او پرسید: چگونه می توان به سالن کارنگی (محل اجرا) رسید؟ پیرمرد به ویالونیست و ویالونی که زیر بغلش بود نگاهی کرد و گفت: «تمرین کن پسر. تمرین!»در نوشته های بعد به بررسی بیشتر موضوع می‌پردازیممنابع: کتاب Clean Architectureریپازیتوری فارسی Clean Code (استفاده از ترجمه برای بخش نظرات)</description>
                <category>انتشارات جاواکاپ</category>
                <author>ali.bayat</author>
                <pubDate>Mon, 05 Apr 2021 18:47:39 +0430</pubDate>
            </item>
                    <item>
                <title>توسعه‌ی کارایی‌گرا (Performance Driven Development)</title>
                <link>https://virgool.io/javacup/httpsvirgooliokiarashazarniaperformance-driven-development-rud4tmrofrzl</link>
                <description>مقدمهفرایندهای متنوعی برای توسعه‌ی نرم‌افزار موجود است. بعضی‌ را احتمالا بیشتر شنیده‌ایم مثل توسعه‌ی آزمون‌گرا (Test Driven Development)، بعضی‌ را کمتر مثل توسعه‌ی ویژگی‌گرا (Feature Driven Development). توسعه‌ی کارایی‌گرا نیز یک فرایند برای توسعه‌ی نرم‌افزارهایی است که کارایی (Performance) در آن‌ها اولویت اول است. پس اگر در تیم توسعه‌ی یک پیام‌رسان، یک هسته‌ی بانکی با تراکنش بالا یا هر نرم‌افزار دیگری هستید که کارایی در آن مهم‌ترین گلوگاه موفقیت محصول است، حتما مخاطب این نوشته هستید. برای شناخت این فرایند، ابتدا ترجمه‌ی قسمتی از کتاب آموزنده‌ی هنر آزمون کارایی اپلیکیشن (The Art of Application Performance Testing)، نوشته‌ی یان مالینو را آورده‌ام و سپس نکاتی را که مفید می‌دانستم، افزوده‌ام.شما از نظر بلوغ آزمون کارایی در چه سطحی هستید؟مالینو در فصل اول کتاب از مفهوم «بلوغ آزمون کارایی» و تاثیر آن در کیفیت عملکرد نرم‌افزار سخن به میان می‌آورد. او با استناد به تحقیقی که در سال ۲۰۰۶ توسط فارستر انجام شده است به این مساله می‌پردازد. در این مطالعه از ملاک عددی «درصد مشکلات کارایی که در محیط پروداکشن نمایان می‌شوند نسبت به تعداد کل مشکلات کارایی» برای سنجش کیفیت استفاده شده است. همچنین سه سطح در آزمون کارایی تعریف می‌شود: آتش‌نشانی، صحت‌سنجی کارایی و توسعه کارایی‌گرا.سطوح بلوغ آزمون کاراییسطح اول: آتش‌نشانیآنچنان که می‌بینید سه سطح بلوغ آزمون کارایی تعریف شده است. اولی آتش‌نشانی است؛ وقتی اتفاق می‌افتد که هیچ آزمون کارایی‌ای قبل از استقرار (Deployment) اپلیکیشن انجام نگیرد یا به حد کافی نباشد، بنابراین همه مشکلات کارایی در محیط زنده‌ی پروداکشن نمایان می‌شوند. این رویکرد بدترین گزینه است اما به طرزی شگفت‌آور، همچنان نسبتا رایج است. شرکت‌های این چنین، خود را در معرض ریسک جدی قرار می‌دهند. البته با توجه به هزینه‌ای که آزمون کارایی در ابتدای کار برای تیم به بار می‌آورد، برخی مواقع این انتخاب اقتصادی است؛ مخصوصا اگر در ابتدای راه، کارایی گلوگاه سامانه نیست.سطح دوم: صحت‌سنجی کاراییسطح دوم، صحت‌سنجی کارایی شرکت‌هایی را شامل می‌شود که برای آزمون کارایی وقت کنار می‌گذارند اما نه تا آخرین مراحل چرخه‌ی عمر اپلیکیشن؛ بنابراین، همچنان تعداد قابل توجهی از مشکلات در پروداکشن رخ می‌دهد. این رویکرد در حال حاضر رایج‌ترین رویکرد سازمان‌هاست. اگر در تیم شما هم قبل از یک استقرار مهم که شامل تغییرات زیادی در سیستم می‌شود، محیط پروداکشن را شبیه‌سازی نموده و برای اطمینان از اوضاع یک آزمون کارایی اجرا می‌کنید، در سطح دوم بلوغ آزمون کارایی قرار دارید. خبر خوش آنکه احتمالا از ۷۰٪ مشکلات کارایی قبل از استقرار اطلاع می‌یابید اما همچنان ۳۰٪ مشکلات کارایی شما را در پروداکشن غافل‌گیر خواهد کرد.سطح سوم: کارایی‌گرابالاترین سطح بلوغ آزمون کارایی، توسعه‌ی کارایی‌گراست به این معنا که مسئولیت نیازمندی‌های کارایی در هر مرحله از چرخه‌ی حیات نرم‌افزار به رسمیت شناخته شده باشد. در نتیجه، تنها تعداد اندکی از مشکلات کارایی در محیط استقرار کشف خواهد شد. این رویکردی است که شرکت‌ها باید روش آزمون کارایی خود با آن سازگار نمایند مخصوصا اگر کارایی مهم‌ترین گلوگاه فنی سیستم آن‌هاست. جدول نتایج: مالینو ادعا می‌کند که برای انتشار ویرایش جدید کتابش، شخصا مطالعه مشابهی را در سال ۲۰۰۹ انجام داده است اما نتایج تغییر چندانی نکرده است. توسعه‌ی کارایی‌گراحال که از مرور کتاب فارغ شدیم، قدری با فراغ بال بیشتر ادامه می‌دهیم. البته ادعا نمی‌کنم پیشینه‌ی عبارت توسعه‌ی کارایی‌گرا به همین مقدار محدود می‌شود. به نظر می‌رسد بیشتر ادبیات حول موضوع آزمون کارایی توسط توسعه‌دهندگان و در فضای صنعت رشد یافته است نه توسط محققین دانشگاهی. به هر حال، مالینو سعی کرد با طرح کردن مفهوم بلوغ آزمون کارایی، کارایی‌گرایی را چنین توضیح دهد:باید اهمیت نیازمندی‌های کارایی در هر مرحله از چرخه‌ی حیات نرم‌افزار به رسمیت شناخته شود.با مرور این جمله می‌توانیم بگوییم توسعه‌ی کارایی‌گرا همان توسعه‌ی آزمون‌گرا (TDD) است، فقط این بار اختصاصی‌تر شده و اهمیت «آزمون کارایی» در آن پررنگ‌تر شده است. این نگاه البته خلاقیت من نیست و دیگران نیز راجع به آن صحبت کرده‌اند، برای مثال می‌توانید این نوشته‌ی خواندنی را ببینید.شمای مفهومی مراحل چرخه‌ی توسعه‌ی کارایی‌گرابه عنوان جمع‌بندی اگر چالش‌های کارایی برای نرم‌افزاری که در حال توسعه‌ی آن هستید حیاتی است، یعنی چالش‌هایی از این جنس:آیا سیستم می‌تواند به صد هزار درخواست در ثانیه پاسخ دهد؟ (Throughput)آیا می‌تواند تضمین کند ۹۹٪ درخواست‌ها در کمتر از ۱ ثانیه پاسخ می‌گیرند؟ (Latency)آیا با افزایش کاربران می‌تواند مقیاس یابد؟ (Scalability)و هر سوال دیگری که با کارایی سر و کار دارد.در این صورت شما با یک سیستم با اولویت نیازمندی کارایی روبرو هستید و خوب است به رویکرد توسعه‌ی کارایی‌گرا نگاهی داشته باشید. البته این فرایند بسیار پرچالش است اما قطعا این چالش‌ها برای یک تیم متخصص و با انگیزه، جذاب، هیجان‌انگیز و مملو از یادگیری است. در پایان به تعدادی از چالش‌های این فرایند اشاره می‌کنم تا فرصتی باشد برای جستجوها، مطالعه‌ها و شاید نوشته‌های بعدی.سنجه‌های اصلی کارایی سیستم ما چیست؟ گذردهی برای ما مهم‌تر است یا تاخیر؟چطور این سنجه‌ها را اندازه‌گیری کنیم و از دقت اندازه‌گیری خود مطمئن شویم؟چطور آزمون کارایی را در خط لوله‌ی یک‌پارچه‌سازی (CI Pipeline) خودکار سازی کنیم؟چطور نتایج آزمون را به نحوی ذخیره‌سازی کنیم تا با آزمون‌های قبلی قابل مقایسه باشد؟کدام رویکرد آزمون کارایی مناسب نیاز ماست؟ Load Test یا Stress Test یا رویکردهای دیگر؟پی‌نوشتبرای ترجمه‌ی Performance Driven Development به «توسعه‌ی کارایی‌گرا» گزینه‌های دیگری هم مطرح بود. مثلا در ویکیپدیا از عبارت «توسعه‌ی آزمون‌محور» برای Test Driven Development استفاده شده است که به نظر من مناسب نیست، عبارت «محور» چون «دوران حول یک محور» را تداعی می‌کند اندکی رهزن است؛ در این صورت «کیفیت» و «ارزش» محور است و نه روش. «کارایی‌گرا» را ترجیح دادم؛ کوتاه است و ساده. اما همچنان پذیرای پیشنهادهای بهتر هستم چرا که به نظرم فرایند ترجمه، مستلزم حوصله و دقت است و به مرور بهینه‌ می‌شود؛ مثل صیقل خوردن سنگ‌های رودخانه!</description>
                <category>انتشارات جاواکاپ</category>
                <author>کیارش آذرنیا</author>
                <pubDate>Mon, 05 Apr 2021 13:52:10 +0430</pubDate>
            </item>
                    <item>
                <title>بررسی Sequence pre allocation  در JPA (پیاده‌سازی‌های Hibernate و EclipseLink)</title>
                <link>https://virgool.io/javacup/%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-sequence-pre-allocation-%D8%AF%D8%B1-jpa-%D9%BE%DB%8C%D8%A7%D8%AF%D9%87-%D8%B3%D8%A7%D8%B2%DB%8C-%D9%87%D8%A7%DB%8C-hibernate-%D9%88-eclipselink-uwzux2n11xj2</link>
                <description>در JPA برای تولید مقدار خودکار (GeneratedValue) مورد استفاده در فیلد‌های Identifier استراتژی‌های مختلفی وجود دارد. در اینجا قصد داریم استراتژی Sequence را در JPA (پیاده‌سازی‌های EclipseLink و Hibernate) و با استفاده از دیتابیس Oracle که دارای مکانیزم تولید Sequence می‌باشد بررسی کنیم.فرض کنید قصد داریم نام افراد را در جدول PERSON در دیتابیس Oracle ذخیره کنیم:create table PERSON
(
    ID   NUMBER(19) not null
        primary key,
    NAME VARCHAR2(255 char)
)همانطور که مشاهده می‌شود Primary Key جدول Person فیلد ID از نوع عددی می‌باشد. و قصد داریم فیلد ID را توسط GeneratedValue و با استفاده از Sequence مقداردهی کنیم.همچنین Entity بنام Person که دارای دو فیلد Id و name می‌باشد نیز وجود دارد:@Table
@Entity
public class Person implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = 
     &amp;quotpersonSequenceGenerator&amp;quot)
     @SequenceGenerator(name = &amp;quotpersonSequenceGenerator&amp;quot, sequenceName = 
     &amp;quotSEQ_PERSON&amp;quot, allocationSize = 50)
     private Long id;

   private String name;

// Getters and Setters...
  }در زمان عملیات Insert فیلد Id از  SequenceGenerator بنام personSequenceGenerator مقدار می‌گیرد که personSequenceGenerator نیز خود از SEQ_PERSON که یک Sequence تعریف شده در دیتابیس Oracle می‌باشد استفاده می‌کند:ایجاد Sequence (SEQ_PERSON) در دیتابیس Oracle:create sequence SEQ_PERSON
   start with 50
   increment by 50
   maxvalue 1000000نکته حائز اهمیت این است که در این مثال مقدار allocationSize مربوط به Sequence تعریف شده در Entity برابر 50 (مقدار پیش فرض در JPA) و مقدار افزایش Sequence تولید شده (increment by) نیز برابر allocationSize یعنی 50 می‌باشد.علت این امر نحوه تخصیص Sequence توسط JPA و بهینه سازی آن با استفاده از pre-allocation در زمان Insert رکورد در جدول می‌باشد.در واقع در حالت ساده (بدون استفاده از JPA و یا عدم استفاده از بهینه‌سازی تخصیص Sequence در JPA) برای دسترسی به مقدار Sequence و استفاده از آن نیازمند دریافت مقدار جدید Sequence هستیم. یعنی به ازای هر بار Insert باید مقدار جدید Sequence را دریافت کنیم:select SEQ_PERSON.nextval from dual;اما چنانچه با توجه به تعدد عملیات Insert در لحظه، بخواهیم به حالت بهینه‌ای این کار را انجام دهیم نیازمند مکانیزمی هستیم که علاوه بر عدم اختصاص Sequence تکراری، تعداد مراجعات به دیتابیس را برای دریافت مقدار جدید Sequence کاهش دهد. یعنی به تعبیری باید یک Cache در سمت Application از مقادیر Sequence داشته باشیم تا در زمان نیاز به دریافت Sequence جدید ابتدا به Cache موجود در Application مراجعه کنیم.خوشبختانه این موضوع توسط JPA پوشش داده شده است و پیاده‌سازی‌های مختلف نظیر EclipseLink و Hibernate نیز از آن پشتیبانی می‌کنند.پس بهتر است ببینیم EclipseLink و Hibernate در عمل چطور این بهینه سازی را انجام می‌دهند.فریم‌ورک‌های EclipseLink و Hibernate (در حالت پیش‌فرض)، با استفاده از مکانیزم pre-allocation تعداد مراجعه به دیتابیس را برای دریافت مقدار جدید sequence کاهش می‌دهند. این مقدار در پارامتر allocationSize در تعریف Sequence در ORM قابل تغییر است. (پیش فرض: 50)اگر مستندات مربوط به allocation-size را بررسی کنیم این تعریف را خواهیم دید:allocationSizepublic abstract int allocationSize(Optional) The amount to increment by when allocating sequence numbers from the sequence.Default:50توضیحات فوق شاید کمی گمراه کننده باشد، اما بصورت کلی اتفاقی که می‌افتد این است که ORM ابتدا یک بازه معتبر از مقادیر Sequence مورد نظر را ایجاد و در زمان Insert از این بازه استفاده می‌کند و پس از اتمام مقادیر مجددا بازه جدیدی از Sequence ها را ایجاد و مورد استفاده قرار می‌دهد و بدین ترتیب در مراجعه به دیتابیس برای دریافت Sequence صرفه جویی قابل توجهی انجام می دهد.همانطور که در مثال بالا دیدیم، مقدار allocation-size در Entity و increment by در Sequence یکسان و برابر مقدار 50 می باشد.بدین‌ ترتیب EclipseLink و Hibernate، در زمان insert ابتدا یک بار برای دریافت مقدار جدید Sequence به دیتابیس مراجعه می‌کنند:select SEQ_PERSON.nextval from dualکه این query در بار اول مقدار 50 را برمی‌گرداند.سپس با استفاده از فرمول زیر مقادیر sequence را تعیین می‌کنند (Cache از مقادیر Sequence ایجاد می‌کند):nextval = SEQ.nextval = 50 
First Sequence = nextval - allocation_size + 1 = 50 - 50 + 1 = 1
Last Sequence = nextval = 50بر این ‌اساس مقدار شروع Sequence تخصیصی به فیلد id با محاسبه انجام شده (50-50+1) برابر عدد 1 می‌شود.و برای بهبود کارایی و عدم مراجعه به دیتابیس در insert های بعدی از مقدار شروع (First Sequence) تا مقدار پایانی (Last Sequence)، مقدار Sequence توسط ORM (بدون مراجعه به دیتابیس) یک به یک افزایش و مورد استفاده قرار می‌گیرد.مثلا در EclipseLink: &lt;sequencing preallocation for SEQ_PERSON: objects: 50 , first: 1, last: 50&gt;زمانی که مقدار Sequence به عدد 50 رسید، ORM مجدد به دیتابیس مراجعه می‌کند تا nextvalue را دریافت کند:select SEQ_PERSON.nextval from dualکه این بار این query مقدار 100 را بر می‌گرداند.حال مجدد همین روال تکرار می‌شود:nextval = 100
First Sequence = 100 - 50 + 1 = 51
Last Sequence = 100در واقع ORM در زمان insert، تا زمانی که به مقدار Last Sequence (در این مرحله عدد 100) نرسیده باشد به دیتابیس مراجعه نخواهد کرد.یعنی به ازای هر 50 عملیات insert تنها یک مراجعه به دیتابیس برای دریافت nextvalue از sequence مورد نظر می‌شود که بهبود قابل توجهی در کارایی خواهد بود!و نکته دیگر اینکه چنانچه Application، در حین insert نمودن رکوردها و پیش از رسیدن به مقدار Last Sequence به هر علتی Restart شود، به دلیل از بین رفتن مقدار Last Sequence، مجددا First Sequence و Last Sequence را محاسبه و استفاده می‌کند.که این امر طبیعتا فاصله ای را در مقادیر sequence مورد استفاده ایجاد می‌کند:Application Starts Running:
select SEQ_PERSON.nextval from dual
nextval = 50
First Sequence = 50 - 50 + 1 = 1
Last Sequence= nextval = 50
--------------------------------------------------------
insert into person (id, name) values (1, &amp;quotAli&amp;quot)
...
...
...
...
insert into person (id, name) values (23, &amp;quotRamin&amp;quot)
(Next Value for id: 24)
--------------------------------------------------------
Application Restarts:
select SEQ_PERSON.nextval from dual
nextval = 100
First Sequence = 100 - 50 + 1 = 51
Last Sequence = nextval  = 100
insert into person (id, name) values (51, &amp;quotReza&amp;quot)
....در آخر باید این نکته را هم ذکر کنیم که JPA بصورت کلی مکانیزم بهینه‌سازی تخصیص Sequence را تعریف کرده و نحوه اجرای آن را به پیاده‌سازی‌ها واگذار کرده که ما در اینجا روش پیش فرض مورد استفاده در پیاده‌سازی‌های EclipseLink و Hibernate را بررسی کردیم. در Hibernate به این روش Pooled Optimizer گفته می‌شود. برای اطلاعات بیشتر و سایر روش های مورد استفاده در Hibernate می توانید مقالات زیر را مطالعه کنید:Hibernate Pooled and Pooled-Lo OptimizerHibernate Hi/Lo Algorithm</description>
                <category>انتشارات جاواکاپ</category>
                <author>Ramin Mehraninejad (raminpix)</author>
                <pubDate>Tue, 09 Feb 2021 15:15:58 +0330</pubDate>
            </item>
                    <item>
                <title>توسعه با طعم شی‌ گرایی (0) - شی گرایی یا رویه ای (1)</title>
                <link>https://virgool.io/javacup/%D8%AA%D9%88%D8%B3%D8%B9%D9%87-%D8%A8%D8%A7-%D8%B7%D8%B9%D9%85-%D8%B4%DB%8C-%DA%AF%D8%B1%D8%A7%DB%8C%DB%8C-0-%D8%B4%DB%8C-%DA%AF%D8%B1%D8%A7%DB%8C%DB%8C-%DB%8C%D8%A7-%D8%B1%D9%88%DB%8C%D9%87-%D8%A7%DB%8C-1-ei8ijwgg3jqs</link>
                <description>سلام دوستان. ببخشید دیر شد، خودم سعی دارم یک روز درمیان مقالات را آماده کنم، اما نمیدونم چرا انقدر زمان سریع میگذره و زود دیر میشه!.... خب بریم سراغ ادامه مقدمه و شروع بحث.در حال حاضر تقریبا همه زبان های برنامه نویسی محبوب از شی گرایی پشتیبانی میکنند ، اما قطعا این تنها راه توسعه نرم‌افزار نیست. معمولا در اولین مراحل توسعه پروژه‌های سیستم های نرم افزاری و وقتی نوبت به انتخاب تکنولوژی مناسب برای نوشتن کد می رسد ، رنگ و بوی بحث ها وجه فلسفی بخود میگیره و همیشه یکی از اولین مباحث این است که کدام پارادایم برنامه نویسی را باید دنبال کرد. پس باید نگاه دقیق تری به آنها داشته باشیم.متون زیر ترجمه ویرایش شده از مقاله Differences between Procedural and Object Oriented Programming است. البته برنامه نویسی رویه ای تقریبا در پروژه ای حرفه ای و لارج اسکیل انجام نمیشه اما مرور و مقایسه اش خارج از لطف نیست.برنامه نویسی رویه ای Procedural  برنامه نویسی رویه ای را می توان به عنوان یک مدل برنامه نویسی تعریف کرد که برگرفته از مفهوم فراخوانی رویه ای است که در آن عملیات یکی پس از دیگری و به ترتیب اجرا می شوند .رویه هایی که به عنوان روال ، زیرروال یا عملکرد ( routines- subroutines – functions) نیز شناخته می شوند، شامل یک سری مراحل محاسباتی هستند. در حین اجرای یک برنامه ، هر رویه خاص برحسب نیاز ممکن است در هر نقطه فراخوانی شود، این فراخوانی میتواند از سمت خودش باشد یا رویه های دیگر. از زبان های مطرح رویه ای میتوان به سی، فورترن، کوبول، بیسیک و پاسگال اشاره کرد.برنامه نویسی رویه ای Procedural   برنامه نویسی شی گرا  Object Oriented برنامه نویسی شی گرا را می توان به عنوان یک مدل برنامه نویسی تعریف کرد که مبتنی بر مفهوم اشیا است. اشیا حاوی مشخصات / داده ها به صورت ویژگی و کد/ رفتارها به صورت متد هستند. در واقع در این پارادیم، نرم‌افزار ها با استفاده از مفهوم اشیایی که با دنیای واقعی تعامل دارند طراحی می شوند. زبان های برنامه نویسی شی گرا کلاس پایه هستند ، به این معنی که اشیا نمونه هایی از کلاس ها هستند. زبان های جاوا، سی پلاس پلاس ، سی شارپ ، رابی، پایتون، پرل، آبجکیتیو-سی، سوییفت، دارت و... زبانهای مطرح شی گرا هستند.برنامه نویسی شی گرا  Object Oriented  تفاوت بین برنامه نویسی رویه ای و برنامه نویسیآبجکت-اورینتد یا همون شی گرادر برنامه نویسی شی گرا ، برنامه به قسمتهای کوچکی تقسیم می شود که اشیا نامیده می شوند .برنامه نویسی شی گرا از رویکرد پایین به بالا پیروی می کند . bottom up approachبرنامه نویسی شی گرا دارای مشخص کننده های دسترسی مانند خصوصی ، عمومی ، محافظت شده و غیره است.(private, public, protected)افزودن داده و عملکرد جدید آسان است.برنامه نویسی شی گرا مخفی کردن داده ها را فراهم می کند بنابراین امنیت بیشتری دارد .در برنامه نویسی شی گرا Overloading امکان پذیر است.در برنامه نویسی شی گرا ، داده از اهمیت بیشتری برخوردار است..برنامه نویسی شی گرا بر اساس دنیای واقعی است .پروسیجر اورینتد یا رویه ایدر برنامه نویسی رویه ای ، برنامه به قسمتهای کوچکی تقسیم می شود که توابع نامیده می شوندبرنامه نویسی رویه ای از رویکرد بالا به پایین پیروی می کند .(top down approach)در برنامه نویسی رویه ای مشخص کننده دسترسی وجود ندارد.افزودن داده و عملکرد جدید آسان نیستبرنامه نویسی رویه ای روش مناسبی برای پنهان کردن داده ها ندارد بنابراین از امنیت کمتری برخوردار است در برنامه نویسی رویه ای ،Overloading  امکان پذیر نیست..در برنامه نویسی رویه ای ، عملکرد مهمتر از داده است..برنامه نویسی رویه ای مبتنی بر دنیای غیر واقعی استدر ادامه به مثال هایی در این رابطه و مقایسه شی گرایی با برنامه نویسی فانکشنال خواهیم پرداخت. </description>
                <category>انتشارات جاواکاپ</category>
                <author>سید عباس ظهیری</author>
                <pubDate>Fri, 05 Feb 2021 18:13:49 +0330</pubDate>
            </item>
            </channel>
</rss>