<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های محمد صادق شیخ زاهدی</title>
        <link>https://virgool.io/feed/@m.s.sheikhzahedi</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-07-06 12:36:47</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/133901/avatar/GMGEXZ.jpg?height=120&amp;width=120</url>
            <title>محمد صادق شیخ زاهدی</title>
            <link>https://virgool.io/@m.s.sheikhzahedi</link>
        </image>

                    <item>
                <title>نگاهی به Maven، چیست و چه بخش هایی دارد</title>
                <link>https://virgool.io/@m.s.sheikhzahedi/%D9%86%DA%AF%D8%A7%D9%87%DB%8C-%D8%A8%D9%87-maven-%DA%86%DB%8C%D8%B3%D8%AA-%D9%88-%DA%86%D9%87-%D8%A8%D8%AE%D8%B4-%D9%87%D8%A7%DB%8C%DB%8C-%D8%AF%D8%A7%D8%B1%D8%AF-rdznpeqebky4</link>
                <description>سلام :) Maven یک ابزار مدیریت پروژه قدرتمند است که بر اساس POM (project object model) ساخته شده است. برای ساخت پروژه(build)، مدیریت dependencyها و مستندسازی(documentation) استفاده می شود. به طور خلاصه می توان گفت maven ابزاری است که می تواند برای ساخت و مدیریت هر پروژه مبتنی بر جاوا استفاده شود.در این مقاله به برسی اجمالی هر بخش می پردازیم هرچند بحث گسترده تر است اما دراینجا بحث های کلی را مطرح میکنم.امکانات Maven:فایل‌ POM: فایل‌های Project Object Model (POM) فایل‌های XML هستند که حاوی اطلاعات مربوط به پروژه و اطلاعات پیکربندی مانند وابستگی‌ها(dependencies)(به زبان ساده تر کتابخانه ها)، source directory، پلاگین ها، پروفایل ها و غیره است که توسط Maven برای build پروژه استفاده می‌شود. Maven فایل pom.xml را برای انجام تنظیمات و عملیات آن نیاز دارد.دپندنسی ها(Dependencies): کتابخانه های خارجی جاوا هستند که برای پروژه مورد نیاز هستند. به عنوان مثال شما میخواهید در Spring با دیتابیس ارتباط برقرار کنید برای اینکار نیاز دارید تا از Spring Data Jpa در پروژه خود استفاده نمایید برای اینکار نیاز هست تا dependency مربوط به آن را که spring-boot-starter-data-jpa است در فایل pom پروژه اضافه نمایید تا بتوانید از کلاس ها، اینترفیس ها و انوتیشن های موجود در آن استفاده کنید.برای مثال:&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
&lt;/dependency&gt;با اضافه کردن این دپندنسی شما به انوتیشن های jpa که شامل Entity, Id, GeneratedValue, Table, Query و ... ،همچنین اینترفیس های JpaRepository, JpaSpecificationExecutor و ... و قابلیت های ORM هایبرنیت دسترسی پیدا میکنیدمخازن(Repositories): دایرکتوری هایی که شامل مجموع فایل های JAR که همان کتابخانه ها یا بهتر بگیم dependencyها هستند، مخازن محل نگهداری dependency ها هستن.مخزن محلی یک دایرکتوری در هارد دیسک دستگاه شما است که معمولا در مسیر C:\Users\your_username\.m2\repository قرار دارد و دپندنسی ها در آنجا کش و نگهداری می شوند. اگر dependency مورد نظر در مخزن محلی Maven یافت نشد، Maven آنها را از یک مخزن مرکزی Maven دانلود کرده و در مخزن محلی شما قرار می دهد یکی ازین مخازن https://mvnrepository.com می باشد.چرخه های حیات (Build Life Cycles): که بر اساس Maven architecture می باشد به چندین فاز تقسیم میشود و اگر هریک از فاز هارا به صورت اختصاصی مشخص نکنیم , Maven بر اساس پیش فرض خود عمل میکند.فاز های پیش فرض Life cycle را میتوان به این صورت بیان کرد :الف) Validate : بررسی میکند که پروژه به درستی ایجاد شده و تمام نیازمندی های آن در دسترس میباشدب) Compile : سورس پروژه را Compile میکندپ) Test : پروژه کامپایل شده را با Framework های Unit Test و متناسب با سورس پروژه تست میکند.ت) Package : سورس کامپایل شده را به فرمت مورد نظر و مشخص شده در Artifact میسازد.ث) Verify : تست های لازم بر روی خروجی کار را انجام میدهد و مشخص میکند که کیفیت با چیزی که مد نظر است, برابری میکند یا خیرج) Install : پروژه را درون Local Repository قرار میدهدچ) Deploy : پروژه را درون Remote Repository قرار میدهد.وقتی که یکی از فاز ها را به صورت اختصاصی میخواهیم اجرا کنیم, فاز های قبلی آن به صورت اتومات اجرا میشوند. برای مثال وقتی که میخواهید فاز Test پروژه را اجرا کنید فاز قبل تر از آن یعنی Validate و Compile نیز اجرا میشوند و یا اگر میخواهید پروژه را  Package کنید, فاز های قبل آن یعنی Validate و Compile و  Test نیز انجام میشوند.جهت اجرای این فاز ها باید به پوشه ای که فایل POM وجود دارد برویم و دستور آن را در کنسول اجرا نمایید مثلا برای اجرای فاز Compile دستور زیر را اجرا میکنیمmvn compileپروفایل ها (Build Profiles): پروفایل مجموعه ای از مقادیر پیکربندی است که به شما این امکان را می دهد پروژه خود را با استفاده از تنظیمات مختلف build کنید. برای مثال نیاز داریم پروژه را روی سیستم local با یکسری تنظیمات مخصوص build بگیریم جهت توسعه و تست اما برای انتشار نسخه ی product با استفاده از تنظیمات متفاوت پروژه build شود این تنظیمات می تواند شامل تنظیمات دیتابیس و ... باشدبرای فعال کردن buildهای مختلف، می‌توانید پروفایل‌های build مختلفی را به فایل‌های POM خود اضافه کنید.به مثال زیر توجه کنید:&lt;profiles&gt;
    &lt;profile&gt;
       &lt;id&gt;dev&lt;/id&gt;
       &lt;activation&gt;
          &lt;!-- this profile is active by default --&gt;
          &lt;activeByDefault&gt;true&lt;/activeByDefault&gt;
          &lt;!-- activate if system properties &#039;env=dev&#039; --&gt;
          &lt;property&gt;
             &lt;name&gt;env&lt;/name&gt;
             &lt;value&gt;dev&lt;/value&gt;
          &lt;/property&gt;
       &lt;/activation&gt;
       &lt;properties&gt;
          &lt;db.driverClassName&gt;com.mysql.jdbc.Driver&lt;/db.driverClassName&gt;
          &lt;db.url&gt;jdbc:mysql://localhost:3306/dev&lt;/db.url&gt;
          &lt;db.username&gt;mkyong&lt;/db.username&gt;
          &lt;db.password&gt;8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92&lt;/db.password&gt;
       &lt;/properties&gt;
    &lt;/profile&gt;

    &lt;profile&gt;
       &lt;id&gt;prod&lt;/id&gt;
       &lt;activation&gt;
          &lt;!-- activate if system properties &#039;env=prod&#039; --&gt;
          &lt;property&gt;
             &lt;name&gt;env&lt;/name&gt;
             &lt;value&gt;prod&lt;/value&gt;
          &lt;/property&gt;
       &lt;/activation&gt;
       &lt;properties&gt;
          &lt;db.driverClassName&gt;com.mysql.jdbc.Driver&lt;/db.driverClassName&gt;
          &lt;db.url&gt;jdbc:mysql://live01:3306/prod&lt;/db.url&gt;
          &lt;db.username&gt;mkyong&lt;/db.username&gt;
          &lt;db.password&gt;8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92&lt;/db.password&gt;
       &lt;/properties&gt;
    &lt;/profile&gt;

&lt;/profiles&gt;به عنوان مثال ما در اینجا دو پروفایل داریم یکی dev که پروفایل پیشفرض است و دیگری prod که دو تنظیمات متفاوت برای دیتابیس را ارائه میکنند.دستور زیر را برای اجرای فاز Compile روی پروفایل prod اجرا میکنیمmvn compile -P prodپلاگین ها (Build Plugins):پلاگین بخش اجرایی maven است، پلاگین ها برای ایجاد فایل های jar، ایجاد فایل های war، کامپایل کد، unit test، ایجاد مستندات پروژه(documentation)، و غیره استفاده می شوند. تقریباً هر عملی که فکر می‌کنید روی یک پروژه انجام دهید، به عنوان یک پلاگین Maven پیاده‌سازی می‌شود. مثلا maven-jar-plugin برای تولید jar فایل پروژه یا پلاگین protobuf-maven-plugin برای تبدیل فایل های proto که برای grpc هستن به کلاس جاوا.برای مثال در پروژه های SpringBoot ما به پلاگین spring-boot-maven-plugin جهت اجرای فاز های مختلف نیاز داریم که در مثال زیر پلاگین ما از lombok نیز پشتیبانی میکند.&lt;build&gt;
    &lt;plugins&gt;
       &lt;plugin&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
          &lt;configuration&gt;
             &lt;excludes&gt;
                &lt;exclude&gt;
                   &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
                   &lt;artifactId&gt;lombok&lt;/artifactId&gt;
                &lt;/exclude&gt;
             &lt;/excludes&gt;
          &lt;/configuration&gt;
       &lt;/plugin&gt;
    &lt;/plugins&gt;
&lt;/build&gt;بررسی فایل POM:دراینجا شما یک نمونه از فایل pom.xml را مشاهده می کنید&lt;project xmlns=&amp;quothttp://maven.apache.org/POM/4.0.0&amp;quot
        xmlns:xsi=&amp;quothttp://www.w3.org/2001/XMLSchema-instance&amp;quot
        xsi:schemaLocation=&amp;quothttp://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd&amp;quot&gt;

    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
    &lt;groupId&gt; com.project.loggerapi &lt;/groupId&gt;
    &lt;artifactId&gt;LoggerApi&lt;/artifactId&gt;
    &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;

    &lt;profiles&gt;
       &lt;profile&gt;
          &lt;!-- ... --&gt;
       &lt;/profile&gt;
    &lt;/profiles&gt;
    
    &lt;!-- Add typical dependencies for a web application --&gt;
    &lt;dependencies&gt;
       &lt;dependency&gt;
          &lt;groupId&gt;org.apache.logging.log4j&lt;/groupId&gt;
          &lt;artifactId&gt;log4j-api&lt;/artifactId&gt;
          &lt;version&gt;2.11.0&lt;/version&gt;
       &lt;/dependency&gt;
       &lt;!-- ... --&gt;
    &lt;/dependencies&gt;

    &lt;build&gt;
       &lt;plugins&gt;
          &lt;!-- ... --&gt;
       &lt;/plugins&gt;
    &lt;/build&gt;

&lt;/project&gt;یک) project: این element اصلی فایل pom.xml است.دو) modelVersion: به این معنی است که از چه نسخه ای از مدل POM استفاده می کنید. از نسخه 4.0.0 برای maven 2 و maven 3 استفاده کنید.سه) groupId: یک شناسه یونیک است که معمولا مشابه پکیج پروژه قرار میگیرد و معکوس دامنه شرکت یا سازنده به همراه نام پروژه را قرار می دهند به عنوان مثال com.project.loggerapiچهار) artifactId: برای نامگذاری پروژه ای که می سازید استفاده می شود. در مثال ما نام پروژه ما LoggerApi است.پنج) version: شماره نسخه پروژه است.شش) profiles: جهت ایجاد پروفایل های مختلف همانطور که قبلا گفتیم.هفت) build: مکان قرار دادن پلاگین های مختلف Maven است</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Wed, 22 May 2024 18:44:03 +0330</pubDate>
            </item>
                    <item>
                <title>دسترسی به پایگاه داده در جاوا: JPA، Hibernate، JDBC و Spring Data</title>
                <link>https://virgool.io/@m.s.sheikhzahedi/%D8%AF%D8%B3%D8%AA%D8%B1%D8%B3%DB%8C-%D8%A8%D9%87-%D9%BE%D8%A7%DB%8C%DA%AF%D8%A7%D9%87-%D8%AF%D8%A7%D8%AF%D9%87-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-jpa-hibernate-jdbc-%D9%88-spring-data-xflowfb3bg2y</link>
                <description>اتصال برنامه‌های جاوا به پایگاه‌ داده ها میتواند گیج کننده باشد، به خصوص زمانی که تلاش می‌کنید تا تعامل بین JDBC، JPA، Hibernate و Spring Data را درک کنید. بیایید به این فناوری‌ها بپردازیم و بر نحوه اتصال برنامه‌نویسان به پایگاه‌ داده ها تمرکز کنیم.الف) (Java Database Connectivity) JDBC به عنوان یک پل حیاتی بین دنیای جاوا و دنیای پایگاه داده عمل می کند و امکان ارتباط مستقیم بین برنامه جاوا و پایگاه داده را فراهم می کند. با استفاده از JDBC، توسعه دهندگان می توانند با پایگاه داده اتصال برقرار کنند، پرس و جوهای SQL را اجرا و نتایج را مدیریت کنند. با این حال، JDBC نیاز به کدنویسی دستی دارد و فاقد انتزاع سطح بالاتر است امکان بروز اشتباه و خطا بالا است.ب) JPA (Jakarta Persistence API) برای رفع محدودیت های موجود در JDBC راه حل هایی را ارائه میدهد. JPA یک interface استاندارد برای برنامه های جاوا جهت تعامل با پایگاه های داده رابطه ای است که دسترسی به پایگاه داده را با ارائه مجموعه ای از annotation ها و نگاشت اشیاء جاوا به جداول پایگاه داده ساده می کند.جهت پیاده سازی JPA، به یک چارچوب ORM مانند Hibernate، TopLink ، iBatis یا ... نیاز دارید. JPA را به عنوان یک رابط و Hibernate را به عنوان یک پیاده سازی در نظر بگیرید. بدون Hibernate (یا ابزاری مشابه)، JPA به تنهایی کاربرد محدودی دارد.سه حوزه را در بر می گیرد:خود API که در پکیج jakarta.persistence تعریف شده است (javax.persistence برای Jakarta EE 8 و پایین تر) شامل Entity، EntityManager، Query و ...زبان پرس و جوی JPQL (Jakarta Persistence Query Language) Object/relational metadata (ORM)پ) Hibernate یک چارچوب قدرتمند و پرکاربرد Object-Relational Mapping (ORM) است. این یک پیاده سازی JPA است، به این معنی که به قوانین تعیین شده توسط JPA پایبند است. Hibernate علاوه بر پیاده سازی JPA ویژگی ها و بهینه سازی های اضافی را ارائه می دهد. ت) Spring Data: به عنوان بخشی جدایی ناپذیر از Spring Framework که به طور گسترده مورد استفاده قرار می گیرد، Spring Data اجرای لایه دسترسی به داده را برای پایگاه داده های مختلف ساده می کند و انتزاع سطح بالاتری را برای دسترسی به داده فراهم می کند. spring data از منابع داده های مختلف، از جمله پایگاه داده های رابطه ای، پایگاه های داده NoSQL و غیره پشتیبانی می کند.که شامل ماژول های متفاوتی است از جمله Spring Data Commons و Spring Data JDBC و Spring Data JPA و Spring Data KeyValue و Spring Data MongoDB و Spring Data Redis و ...ث)  Spring Data JPA، یک ماژول در Spring Data که به طور یکپارچه با JPA و Hibernate ادغام می شود.هنگام استفاده از Spring Boot با Spring Data JPA، تنظیمات لازم برای اتصال برنامه جاوا به پایگاه داده به راحتی در دسترس هستند. فقط میزبان پایگاه داده، نام کاربری، رمز عبور را ارائه دهید، و Spring Boot بقیه کارها را انجام می دهد.</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Sun, 19 May 2024 10:52:23 +0330</pubDate>
            </item>
                    <item>
                <title>زمان بندی اجرای وظایف SpringBoot</title>
                <link>https://virgool.io/@m.s.sheikhzahedi/%D8%B2%D9%85%D8%A7%D9%86-%D8%A8%D9%86%D8%AF%DB%8C-%D8%A7%D8%AC%D8%B1%D8%A7%DB%8C-%D9%88%D8%B8%D8%A7%DB%8C%D9%81-springboot-ycfpiou2ex4c</link>
                <description>سلام :)گاهی نیاز هست که ما یک سری کار ها و تسک ها را در دوره زمانی مشخص یا بصورت زمان بندی شده اجرا کنیم، Spring Boot این امکان را برای ما فراهم می کند که وظایف را برای اجرا در یک دوره زمانی معین با کمک انوتیشن Scheduled@ زمان بندی کنیم.ابتدا باید زمانبندی(scheduling) را در پروژه SpringBoot فعال کنیم برای اینکار نیاز هست که در بالای کلاس اصلی اسپرینگ که شامل متد main پروژه هست انوتیشن @EnableScheduling اضافه کنیم، در کنار انوتیشن @SpringBootApplication. به عنوان مثال:// Annotation
@SpringBootApplication
@EnableScheduling
// Class
public class SchedulerApplication {
    // Main driver method
    public static void main(String[] args)
    {
        SpringApplication.run(SchedulerApplication.class,args);
    }
}خب حال برای نوشتن کدهای زمان بندی شده ما نیاز داریم به ایجاد یک @Component کلاس که اسم اون رو Scheduler می گذاریم و درون آن متد scheduleTask() را برای زمان بندی یک کار با استفاده از انوتیشن Scheduled@ تعریف می کند.متد ()schedulerTask در کلاس Scheduler به سادگی تاریخ و زمانی را که task در آن اجرا می شود چاپ می کند.// Annotation
@Component
// Class
public class Scheduler {

    // Method
    // To trigger the scheduler every one minute
    // between 19:00 PM to 19:59 PM
    @Scheduled(cron = &amp;quot0 * 19 * * ?&amp;quot)
    public void scheduleTask()
    {
        SimpleDateFormat dateFormat = new SimpleDateFormat(
                &amp;quotdd-MM-yyyy HH:mm:ss.SSS&amp;quot);

        String strDate = dateFormat.format(new Date());

        System.out.println(
                &amp;quotCron job Scheduler: Job running at - &amp;quot
                        + strDate);
    }
}عنصر cron مشخصشده در انوتیشن Scheduled@ اجازه میدهد تا عبارات cron را برای دربرداشتن تریگرها در ثانیه، دقیقه، ساعت، روز ماه، ماه، و روز هفته تعریف کنیم. عبارت مشخص شده در اینجا در عنصر cron زمانبندی را هر یک دقیقه بین ساعت 19:00 تا 19:59.00 راه اندازی کند.یعنی هر یک دقیقه بین ساعت 19:00 تا 19:59.00 تابع scheduleTask صدا زده می شود و ما خروجی آن را در کنسول مشاهده می کنیم. *برای اجرای یک متد در زمان مشخص، باید از انوتیشن Scheduled@ در بالاسر متد مربوطه استفاده نمایید، که به صورت کلی 4 نوع ورودی fixedDelay،fixedRate،initialDelay و cronرا دارد. که ما در مثال بالا از cron استفاده کردیم حال بیایید این چهار نوع را بررسی کنیم1- fixedDelayدر این حالت، مدت زمان بین پایان آخرین اجرا و شروع اجرای بعدی ثابت است. کار همیشه منتظر می ماند تا کار قبلی تمام شود.این گزینه باید زمانی استفاده شود که اجرای قبلی قبل از اجرای مجدد اجباری باشد که یک عدد ثابت به میلی ثانیه دریافت می کند.@Scheduled(fixedDelay = 1000)
public void scheduleFixedDelayTask() {
    System.out.println(
            &amp;quotFixed delay task - &amp;quot + System.currentTimeMillis() / 1000);
}2- fixedRateاین گزینه باید زمانی استفاده شود که هر اجرای وظیفه مستقل باشد که یک عدد ثابت به میلی ثانیه دریافت می کند.توجه داشته باشید که کارهای برنامه ریزی شده به طور پیش فرض به صورت موازی اجرا نمی شوند. بنابراین حتی اگر از fixedRate استفاده کنیم، تا زمانی که کار قبلی انجام نشود، کار بعدی فراخوانی نخواهد شد.@Scheduled(fixedRate = 1000)
public void scheduleFixedRateTask() {
    System.out.println(
            &amp;quotFixed rate task - &amp;quot + System.currentTimeMillis() / 1000);
}اگر میخواهیم از رفتار موازی در کارهای زمانبندیشده پشتیبانی کنیم، باید انوتیشن @Async را اضافه کنیم:@EnableAsync
public class ScheduledFixedRateExample {
    @Async
    @Scheduled(fixedRate = 1000)
    public void scheduleFixedRateTaskAsync() throws InterruptedException {
        System.out.println(
                &amp;quotFixed rate task async - &amp;quot + System.currentTimeMillis() / 1000);
        Thread.sleep(2000);
    }
}3- initialDelayبرای زمانی است که بخواهیم اجرای اول را در زمان متفاوتی انجام دهیم و بعد با fixed rate/fixed Delay تکرار های بعدی را مشخص کنیم.اولین اجرا با تاخیر 1 ثانیه ای انجام می شود، سپس سایر اجرا ها هر 2 ثانیه.@Scheduled(fixedDelay = 1000, initialDelay = 2000)
public void scheduleFixedRateWithInitialDelayTask() {

    long now = System.currentTimeMillis() / 1000;
    System.out.println(
            &amp;quotFixed rate task with one second initial delay - &amp;quot + now);
}توجه داشته باشید که چگونه در این مثال از fixedDelay و همچنین initialDelay استفاده می کنیم. این کار برای اولین بار بعد از مقدار initialDelay اجرا می شود و مطابق با fixedDelay به اجرای آن ادامه می دهد.4- cronگاهی اوقات تاخیرها و نرخ ها کافی نیستند و ما به انعطاف پذیری یک عبارت cron برای کنترل وظایف خود نیاز داریم. ممکن است شرایطی پیش بیاید که اجرای متد به فواصل زمانی خاصی نیاز داشته باشد. مثلا هر هفته یا آخر هر ماه یا بین یک بازه زمانی مشخص و یا ...ترتیب قرار گیری مقادیر به صورت زیر است.مقدار سال اجباری نمی باشد ولی سایر فیلد ها باید پر شود.&lt;second&gt; &lt;minute&gt; &lt;hour&gt; &lt;day-of-month&gt; &lt;month&gt; &lt;day-of-week&gt; &lt;year&gt;میتوانید از سایت زیر یک عبارت cron تولید یا تست نماییدhttps://crontab.cronhub.io/برای مثال:@Scheduled(cron = &amp;quot0 15 10 15 * ?&amp;quot)
public void scheduleTaskUsingCron) {

    long now = System.currentTimeMillis() / 1000;
    System.out.println(
            &amp;quotschedule tasks using cron jobs - &amp;quot + now);
}توجه داشته باشید که در این مثال، ما یک کار را برنامه ریزی می کنیم که در ساعت 10:15 صبح پانزدهمین روز هر ماه اجرا شود.* به طور پیش فرض، Spring از منطقه زمانی محلی سرور برای عبارت cron استفاده می کند. با این حال، ما می توانیم از ویژگی zone برای تغییر این منطقه زمانی استفاده کنیم:@Scheduled(cron = &amp;quot0 15 10 15 * ?&amp;quot, zone = &amp;quotEurope/Paris&amp;quot)استفاده از تنظیمات application.propertiesهاردکد کردن این زمانبندیها ساده است، اما معمولاً نیاز داریم که بتوانیم برنامه را بدون کامپایل مجدد و استقرار مجدد کل برنامه کنترل کنیم.برای اینکار می توانیم از Spring Expressions و فایل application.properties استفاده کنیم برای اینکار به شکل زیر عمل می کنیمبرای وظایف fixedDelay@Scheduled(fixedDelayString = &amp;quot${fixedDelay.in.milliseconds}&amp;quot)و قرار دادن fixedDelay.in.milliseconds=1000 در application.propertiesبرای وظایف fixedRate@Scheduled(fixedRateString = &amp;quot${fixedRate.in.milliseconds}&amp;quot)و قرار دادن fixedRate.in.milliseconds=1000 در application.propertiesبرای وظایف cron@Scheduled(cron = &amp;quot${cron.expression}&amp;quot)و قرار دادن مقدار cron.expression در application.propertiescron.expression=&amp;quot0 15 10 15 * ?&amp;quot</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Thu, 16 May 2024 15:08:28 +0330</pubDate>
            </item>
                    <item>
                <title>اینترفیس Externalizable در جاوا</title>
                <link>https://virgool.io/@m.s.sheikhzahedi/%D8%A7%DB%8C%D9%86%D8%AA%D8%B1%D9%81%DB%8C%D8%B3-externalizable-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-bxb6kceegw5c</link>
                <description>هدف اصلی این اینترفیس تسهیل سریال سازی و سریال سازی سفارشی است که با استفاده از آن می توان کنترل بیشتری بر سریالیزه سازی اشیا داشت به عنوان مثال می توان تعیین کرد کدام فیلد ها باید سریالیزه شوند یا نشوند، چک کردن validation یا پیاده سازی بیزینس های خود. اینترفیس Externalizable در پکیج java.io.Externalizable است که از java.io.Serializable ارث بری میکند و باید تو تابع writeExternal()و readExternal() راباید override کرد.public interface Externalizable extends java.io.Serializable {
    void writeExternal(ObjectOutput out) throws IOException;
    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}خب بیایید یک مثال بزنیم :)public class Country implements Externalizable {
    private String name;
    private int code;
    private int total;

    // getters, setters

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeUTF(name);
        out.writeInt(code);
    }

    @Override
    public void readExternal(ObjectInput in)
            throws IOException, ClassNotFoundException {
        this.name = in.readUTF();
        this.code = in.readInt();
    }
}در اینجا، ما یک کلاس Country تعریف کرده ایم که رابط Externalizable را پیاده سازی می کند و دو متد ذکر شده در بالا را پیاده سازی می کند.در متد ()writeExternal برای serialized شی، ما ویژگی های شی را به جریان ObjectOutput اضافه می کنیم. که دارای متدهای استانداردی مانند writeUTF() برای String و writeInt() برای مقادیر int است.در مرحله بعد در متد ()readExternal، برای deserialized شی، از جریان ObjectInput با استفاده از متدهای readUTF()، readInt() می خوانیم تا مقادیر را به همان ترتیبی که نوشته شده اند بخوانیم.در مثال بالا ما فیلد total را در عملیات serialized و deserialized شرکت نداده ایم و فقط مقادیر name و code در این عملیات تبدیل و انتقال داده می شوند. ما میتوانیم درون متدهای writeExternal  و readExternal به راحتی و با کنترل کامل بیزینس های خود را پیاده سازی کنیم. برای مثال میتوانیم ولیدیشن های خود را بنویسیم@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    System.out.println(&amp;quotCustom externalizable serialization logic invoked.&amp;quot);
    
    this.name = in.readUTF();
    this.code = in.readInt();

    if (this.code == 840) {
        throw new IllegalArgumentException(&amp;quotNot a valid country!&amp;quot);
    }
    if (this.name.length()&gt;150) {
       throw new IllegalArgumentException(&amp;quotCountry name must be less than 150 characters!&amp;quot);
    }
}در مثال بالا ما برای کشور با کد 840  و همچنین اسم کشور را به 150 کارکتر محدودیت ایجاد کردیم که در عملیات deserialized خطا ایجاد می کنیم.بیایید یک فیلد جدید به کلاس Country برای یک سری اطلاعات امنیتی اضافه میکنیم...
private String superSecretInformation;
...حال در فرایند serialized و deserialized ما این فیلد را اینکد و دیکد می کنیم @Override
public void writeExternal(ObjectOutput out) throws IOException {
    out.writeUTF(name);
    out.writeInt(code);
    out.writeUTF(Base64.getEncoder().encodeToString(superSecretInformation.getBytes()));
}

@Override
public void readExternal(ObjectInput in)
        throws IOException, ClassNotFoundException {
    this.name = in.readUTF();
    this.code = in.readInt();
    this.superSecretInformation = new String(Base64.getDecoder().decode(in.readUTF()));
}</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Wed, 15 May 2024 10:37:54 +0330</pubDate>
            </item>
                    <item>
                <title>Datastructures در جاوا(پارت 1)</title>
                <link>https://virgool.io/@m.s.sheikhzahedi/datastructures-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7%D9%BE%D8%A7%D8%B1%D8%AA-1-ebdonrq6ukuc</link>
                <description>ساختار داده(Data Structure) چیست:ساختار داده، به معنای نحوه ذخیره و سازماندهی دادهها در حافظه و ارائه روشهای مدیریت آنها است که روشی است برای مرتب کردن داده ها در رایانه به گونه ای که بتوان به طور موثر به آنها دسترسی پیدا کرد و به روز کرد.ساختار داده فقط برای سازماندهی داده ها استفاده نمی شود. همچنین برای پردازش، بازیابی و ذخیره داده ها استفاده می شود. انواع مختلفی از ساختارهای داده پایه و پیشرفته وجود دارد که تقریباً در هر برنامه یا سیستم نرم افزاری توسعه یافته استفاده می شود. بنابراین ما باید دانش خوبی در مورد ساختار داده داشته باشیم.طبقه بندی ساختار داده ها:ساختار داده خطی(Linear): ساختار داده ای که در آن عناصر داده به صورت متوالی یا خطی مرتب می شوند، جایی که هر عنصر به عناصر مجاور قبلی و بعدی خود متصل می شود، ساختار داده خطی نامیده می شود. نمونه هایی از ساختارهای داده خطی عبارتند از: آرایه، پشته، صف، لیست پیوندی و غیره.ساختار داده ایستا(Static): ساختار داده استاتیک دارای اندازه حافظه ثابت است. دسترسی به عناصر در یک ساختار داده ایستا آسان تر است. نمونه ای از این ساختار داده یک آرایه است.ساختار داده پویا(Dynamic): در ساختار داده پویا، اندازه ثابت نیست. اندازه آن می تواند بطور تصادفی در طول زمان اجرا به روز شود که ممکن است در مورد پیچیدگی حافظه (فضا) کد موثر در نظر گرفته شود. نمونه هایی از این ساختار داده عبارتند از: صف، پشته و غیره.ساختار داده غیر خطی(Non-linear): ساختارهای داده ای که عناصر داده به صورت متوالی یا خطی قرار نمی گیرند، ساختار داده غیرخطی نامیده می شوند. در یک ساختار داده غیر خطی، ما نمیتوانیم همه عناصر را تنها در یک اجرا طی کنیم. نمونههایی از ساختارهای داده غیرخطی درختان و نمودارها هستند.به عنوان مثال، میتوانیم فهرستی از آیتمها را با نوع داده مشابه با استفاده از ساختار دادههای آرایه ذخیره کنیم.در این مقاله فقط به آشنایی اولیه پرداختیم در مقالات بعد توضیحات تکمیلی و آموزش هرکدام از ساختار داده های موجود می پردازیم</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Tue, 14 May 2024 10:33:23 +0330</pubDate>
            </item>
                    <item>
                <title>record در جاوا</title>
                <link>https://virgool.io/@m.s.sheikhzahedi/record-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-fqtjgfz67upm</link>
                <description>در زبان جاوا، رکورد (Record) یک ساختار داده است که به شما اجازه می دهد تا یک مجموعه ای از فیلدها را در یک شیء گروه بندی کنید. اولین بار در جاوا 14 به عنوان preview feature و در جاوا 15 ارائه شد. رکوردها به صورت غیرقابل تغییر (Immutable) هستند، به این معنی که پس از ساخته شدن نمی توانید مقادیر فیلدهایشان را تغییر دهید و معمولا به عنوان DTO یا data transfer object استفاده می شوند جهت انتقال داده ها بین فرآیندها.برای رکورد ها به صورت اتوماتیک متدهای equals،hashCode و toString ساخته می شود علاوه بر این سازنده و متد های getter مربوط به هر فیلد جنریت می شود و نیاز به نوشتن کدهای روتین که داخل کلاس می نویسیم نیست. از آن جایی که رکورد ها Immutable هستند یعنی غیرقابل تغییر بنابراین هیچ متد setter وجود نخواهد داشت.برای تعریف یک رکورد در جاوا، شما باید از کلیدواژه record استفاده کنید و فیلدهای مورد نظرتان را تعریف کنید. به عنوان مثال، فرض کنید شما می خواهید یک رکورد برای نمایش اطلاعات یک شخص ایجاد کنید:public record Person(String name, int age) {
 // constructor, getters, and other methods are generated automatically 
}در این مثال، رکورد Person دو فیلد name و age را دارد. همچنین، برای این رکورد، سازنده (constructor)، متدهای getter و سایر متدهای مورد نیاز به طور خودکار تولید می شوند.برای ایجاد یک نمونه از رکورد Person، می توانید به صورت زیر عمل کنید:Person person = new Person(&amp;quotJohn Doe&amp;quot, 25);با داشتن نمونه از رکورد Person، شما می توانید به فیلدهای آن دسترسی پیدا کنید. به عنوان مثال:String name = person.name();
int age = person.age();در واقع، با استفاده از رکوردها، شما می توانید به سادگی و بدون نیاز به نوشتن کدهای تکراری و مکرر، ساختار داده های ساده تری را تعریف کنید که فقط برای حفظ داده ها استفاده می شوند.نکاتی در رابطه با رکورد ها در جاوارکورد یک کلاس فاینال است. در نتیجه قابل ارث بری نیست.داده های رکورد، ایممیوتبل (غیرقابل تغییر) اند. در نتیجه برای داده های رکورد متد های ستر نداریم.رکورد میتواند دارای چند کنستراکتور(سازنده) باشدpublic record Person(String name, String email, int age) {

  public Person(String name,int age){

    this(name,null,age);

  }

}برای رکورد میتوان یک کنستراکتور فشرده (compact constructor) ایجاد کرد. در واقع این نوع کنستراکتور ها هیچ ورودی نمیگیرند و هنگام ایجاد شدن صدا زده خواهند شد:public record Person(String name,String email, int age) {
    public Person{
        System.out.println(&amp;quotCompact Constructor&amp;quot);
    }
}</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Mon, 13 May 2024 20:18:16 +0330</pubDate>
            </item>
                    <item>
                <title>آنالیز کدهای SpringBoot با استفاده از Sonarqube</title>
                <link>https://virgool.io/@m.s.sheikhzahedi/%D8%A2%D9%86%D8%A7%D9%84%DB%8C%D8%B2-%DA%A9%D8%AF%D9%87%D8%A7%DB%8C-springboot-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-sonarqube-ufbfrdg0tb5b</link>
                <description>سلام :)خب توی مقاله قبل به بررسی Sonarqube پرداختیم و امکانات آن را بررسی کردم، میتوانید از لینک زیر آن را مشاهده نمایید https://virgool.io/@m.s.sheikhzahedi/%D8%A8%D8%B1%D8%B3%DB%8C-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-sonarqube-%D8%AA%D8%AC%D8%B2%DB%8C%D9%87-%D9%88-%D8%AA%D8%AD%D9%84%DB%8C%D9%84-%DA%A9%D8%AF%D9%87%D8%A7-%D9%88-%D9%BE%D8%B1%D9%88%DA%98%D9%87-nyhomnltrhzh اگر بخواهیم به صورت خلاصه بگیم:نرم افزار سونار کیوب یا نرم افزار  Sonarqube یک ابزار کنترل کننده کیفیت کد است. این برنامه کد نوشته شده را دریافت و تجزیه و تحلیل می‌کند و گزارش‌هایی را برای کیفیت کدی که برای برنامه‌تان نوشته‌اید، ارائه می‌دهد. نحوه عملکرد این نرم افزار به این صورت است که ابزارهای تجزیه و تحلیل استاتیک و پویا را ترکیب می‌کند و کیفیت را به طور مداوم در طول زمان اندازه گیری می‌نماید.برای استفاده از Sonarqube ابتدا نیاز به راه اندازی سرور آن داریم که برای اینکار دو راه داریم دانلود فایل zip و اجرا کردن آن و راه ساده تر استفاده از داکرراه اندازی Sonarqube در داکربرای اینکار کافی است دستور زیر را اجرا کنیمdocker run -d --name sonarqube -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true -p 9000:9000 sonarqube:latestجهت فرار از تح*ریم میتوانید بجای است ایمیج از docker.arvancloud.ir/sonarqube:latest استفاده کنید.بعد از اجرا دستور بالا سرور sonarqube روی آدرس http://localhost:9000 قابل مشاهده است و با یوزر admin و پسورد admin میتوانید لاگین کنید.تولید Tokenبرای اینکه بتوانید از این اسکنر در پروژه خود استفاده کنید، باید یک access token از رابط SonarQube ایجاد کنید. بعد از لاگین در تب Projects بر روی Create Project کلیک کنید، یک منو باز می شود میتوان پروژه local یا پروژه از github  و gitlab ایجاد کنید. در این بخش من local را انتخاب میکنم و اطلاعات پروژه را وارد میکنمبعد از ایجاد پروژه در پنل پروژه بخش Overview بخش &quot;How do you want to analyze your repository?&quot; من Locally را انتخاب میکنمدر این بخش می توانیم token را ایجاد کنیم، زمان Expire شده توکن و یک نام برای آن انتخاب می کنیمتوکن جنریت شده را کپی می کنیم افزودن SonarQube به SpringBootبرای اینکار نیاز هست که یک plugin به pom.xml پروژه اضافه کنیم&lt;build&gt;
    &lt;pluginManagement&gt;
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.sonarsource.scanner.maven&lt;/groupId&gt;
                &lt;artifactId&gt;sonar-maven-plugin&lt;/artifactId&gt;
                &lt;version&gt;3.11.0.3922&lt;/version&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/pluginManagement&gt;
&lt;/build&gt;آخرین ورژن این پلاگین میتوانید از این لینک مشاهده کنید.حال می توانیم با استفاده از دستور زیر اسکل پروژه را شروع کنیم:./mvnw clean verify sonar:sonar -Dsonar.projectKey=PROJECT_KEY
    -Dsonar.projectName=&#039;PROJECT_NAME&#039;
    -Dsonar.host.url=http://localhost:9000
    -Dsonar.token=THE_GENERATED_TOKEN* نیاز هست که اطلاعات خود را بجای project_key, project_name , the-generated-token قرار دهید.جهت افزودن تنظیمات Sonarqube نیاز است یک فایل به نام sonar-project.properties در root پروژه ایجاد کنیم و تنظیمات داخل آن قرار می دهیمsonar.projectKey=my-spring-project
sonar.projectName=My Spring Project
sonar.host.url=http://localhost:9000
sonar.token=THE_GENERATED_TOKENحال فقط نیاز به اجرای دستور زیر است./mvnw clean verify sonar:sonarبعد از اجرای دستور میتوان نتایج اسکن و آنالیز پروژه را در داشبورد پروژه ها در آدرس http://localhost:9000 مشاهده کردمشکلات کشف شده می تواند Bug, Vulnerability, Code Smell, Coverage یا Duplication باشد. هر دسته دارای تعداد متناظر یا مقدار درصدی است.با کلیک بر روی نام پروژه ما را به داشبورد اختصاصی می‌برد که در آن می‌توانیم مسائل خاص پروژه را با جزئیات بیشتر بررسی کنیم.برگه Issues در داشبورد پروژه، مسائلی را که مختص پروژه مورد نظر است نمایش می دهد:</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Sun, 12 May 2024 14:16:02 +0330</pubDate>
            </item>
                    <item>
                <title>برسی نرم افزار Sonarqube ، تجزیه و تحلیل کدها و پروژه</title>
                <link>https://virgool.io/@m.s.sheikhzahedi/%D8%A8%D8%B1%D8%B3%DB%8C-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-sonarqube-%D8%AA%D8%AC%D8%B2%DB%8C%D9%87-%D9%88-%D8%AA%D8%AD%D9%84%DB%8C%D9%84-%DA%A9%D8%AF%D9%87%D8%A7-%D9%88-%D9%BE%D8%B1%D9%88%DA%98%D9%87-nyhomnltrhzh</link>
                <description>نرم افزار سونار کیوب یا نرم افزار  Sonarqube یک ابزار کنترل کننده کیفیت کد است. این برنامه کد نوشته شده را دریافت و تجزیه و تحلیل می‌کند و گزارش‌هایی را برای کیفیت کدی که برای برنامه‌تان نوشته‌اید، ارائه می‌دهد. نحوه عملکرد این نرم افزار به این صورت است که ابزارهای تجزیه و تحلیل استاتیک و پویا را ترکیب می‌کند و کیفیت را به طور مداوم در طول زمان اندازه گیری می‌نماید. در این نرم افزار، همه چیز از جمله خطاهای طراحی بررسی و ارزیابی می‌شود. این به کاربران کمک می‌کند که مشکلات کد خود را پیدا کنند و قابلیت جستجوی این مشکل‌ها نیز در برنامه وجود دارد. از این برنامه می‌توان کمک گرفت تا فهمید تجزیه و تحلیل کند چه علتی دارد و کد در کجا به هم می‌ریزد. این برنامه تعیین می‌کند که آیا این مشکل در استایل، شکست کد، تکرار کد، عدم پوشش آزمایشی یا کد بیش از حد پیچیده است یا مشکل دیگری وجود دارد.تجزیه و تحلیل دینامیک کد در سونار کیوبتشخیص خطای حافظهبررسی این که آیا نشت حافظه یا خطا رخ می‌دهد یا خیر. پیدا کردن محل خطا در کد نوشته شده: مکان یابی کد مشکل دار در برنامه نوشته شده.استنتاج متغیرمقادیری را که برنامه محاسبه می‌‌کند، مشاهده می‌نماید و سپس آن‌ها را بررسی می‌کند. ویژگی‌هایی که در یک یا چند مقدار عددی در برنامه وجود داشت را برای بقیه مقادیر نیز چک می‌کند تا ببیند برنامه به شکل صحیح کار می‌نماید یا خیر.تجزیه و تحلیل امنیتیشناسایی مشکلات امنیتی در کد نوشته شدهخطاهای همزمانیتحلیل دینامیک از تشخیص خطای زمان اجرا برای پیدا کردن نقص‌هایی مانند اشتباهات اجرای برنامه، نقص‌های حافظه و مشکلات امنیتی استفاده می‌نماید. Slicing کد یا خلاصه کردن برنامه: شامل کاهش خطوط برنامه به حداقل شکلی است که همچنان عملکرد لازم را داشته باشد. یعنی برنامه توسط نرم افزار سونار کیوب طوری خلاصه شود که عملکرد کافی را داشته باشد ولی ساده و مختصر نیز باشد‌.تجزیه و تحلیل عملکرد کدردیابی پویا یا دینامیک، از ابزار‌های نرم افزاری در زمان اجرای کد استفاده می‌کند. با جمع آوری داده‌هایی که می‌تواند برای تجزیه و تحلیل و شناسایی دلایل عملکرد ضعیف برنامه استفاده شود، عمل می‌کتد و عملکرد کد را بررسی می‌نماید‌.تجزیه و تحلیل استاتیک کد در سونار کیوبتجزیه و تحلیل کد استاتیک بدون اجرای هیچ کدی انجام می‌شود یعنی نیازی نیست که برنامه در حال اجرا باشد تا توسط سونار کیوب ارزیابی گردد. تجزیه و تحلیل استاتیک، مجموعه‌ای از الگوریتم‌ها و تکنیک‌ها است که برای تجزیه و تحلیل کد منبع به منظور یافتن خطاهای احتمالی است. در تحلیل استاتیک، کدگذاری ضعیف نیز تشخیص داده می‌شود. تجزیه و تحلیل کد به شکل استاتیک  راهی برای بررسی کد به شکل خودکار است.</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Sun, 12 May 2024 10:38:42 +0330</pubDate>
            </item>
                    <item>
                <title>چندریختی(Polymorphism) در جاوا</title>
                <link>https://virgool.io/@m.s.sheikhzahedi/%DA%86%D9%86%D8%AF%D8%B1%DB%8C%D8%AE%D8%AA%DB%8Cpolymorphism-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-cblobnbtf9sm</link>
                <description>سلام :)کلمه پلی مورفیسم(Polymorphism) به معنای داشتن اشکال متعدد است. چندریختی(Polymorphism) در جاوا مفهومی است که به وسیله آن می توانیم یک عمل واحد را به روش های مختلف انجام دهیم.دو نوع چندریختی در جاوا وجود دارد: چندریختی زمان کامپایل یا استاتیک و چندریختی زمان اجرا یا داینامیک. ما می توانیم پلی مورفیسم را در جاوا با روش overloading و روش overriding انجام دهیم.1 چندریختی زمان اجرا:خب Runtime polymorphism یا Dynamic Method Dispatch فرآیندی است که در آن فراخوانی یک متد override شده در زمان اجرا به جای زمان کامپایل مشخص می شود.این نوع پلی مورفیسم با روش Overriding به دست می آید. از طرف دیگر، overriding زمانی اتفاق می افتد که یک کلاس مشتق شده(کلاس فرزند) برای یکی از توابع عضو، کلاس پایه(کلاس پدر) تعریف داشته باشد. گفته می شود که تابع پایه نادیده گرفته شده است.اگر بخواهیم به زبا ساده تر بگوییم دو تابع با امضا یکسان در دو کلاس متفاوت که بین آن ها یک رابطه ارث بری وجود دارد یعنی اگر کلاس فرزند متدی را پیاده سازی کند که در کلاس پدر وجود داشته است، overriding در جاوا انجام داده ایم و در زمان فراخوانی تابع بجای تابع موجود در کلاس پدر، تابع override شده در کلاس فرزند صدا زده می شود و این عمل تا زمان اجرا قابل تشخیص نمی باشد. شروط overriding به ترتیب زیر است:نام متدها یکسان باشدورودی و خروجی متدها یکسان باشدمتدهای override شده حتما باید در دو کلاس متفاوت باشند و بین کلاس ها رابطه ارث بری وجود دارد.مثال overriding در جاوا:دو کلاس به نام Human و Boy داریم. کلاس Boy از کلاس Human ارث بری میکند. حال برای اینکه overriding را در جاوا انجام دهیم برای دو کلاس متدی به نام eat مینویسیم.کد آن به صورت زیر است:public class Human {
     public void eat() {
          System.out.println(&amp;quotHuman is Eating....&amp;quot);
     }
}

public class Boy extends Human {
     @Override
     public void eat() {
          System.out.println(&amp;quotBoy is eating&amp;quot);
     }
}

public class Girl extends Human {
      @Override
      public void eat() { 
          System.out.println(&amp;quotGirl is eating&amp;quot);     
 } 
}

public static void main(String[] args) {
          Human h;

          h = new Boy();
          h.eat();

         h = new Girl();
         h.eat();
 }

output:
Boy is eating
Girl is eatingدر مثال بالا کلاس boy و girl از کلاس human ارث بری می کند و تابع eat موجود در کلاس human را بازنویسی کرده است زمانی که در تابع main برای اولین بار متد eat را فراخوانی می کنیم بجای تابع eat موجود در کلاس boy اجرا می شود و برای بار دوم متد eat باز نویسی شده در کلاس girl اما اگر بازنویسی انجام نمی شد کلاس موجود در کلاس پدر فراخوانی می شد و برای اینکه مشخص شود کدام یک از توابع باید اجرا شود باید تا زمان اجرای پروژه صبر کرد. 2 چندریختی زمان کامپایل:این نوع پلی مورفیسم که Compile-Time Polymorphism یا Static Polymorphism گفته میشود با overloading تابع یا overloading عملگر به دست می آید، و در زمان کامپایل مشخص می شود.* هرچند overloading عملگر درجاوا پشتیبانی نمی شود به جز عملگر &quot;+&quot; که میتوان برای جمع کردن دو عدد یا الحاق دو رشته به یکدیگر استفاده شود.overloading تابع:در توابع overloading به این معناست که توابع هم نام در یک کلاس اما با تعداد یا نوع پارامتر های ورودی متفاوت به عنوان مثال:class Helper {
    // Method with 2 integer parameters
    static int Multiply(int a, int b)
    {
        // Returns product of integer numbers
        return a * b;
    }

     // Method 2
    // With same name but with 2 double parameters
    static double Multiply(double a, double b)
    {
        // Returns product of double numbers
        return a * b;
    }
} همانطور که مشاهده میکنید در کلاس Helper ما دو تابع هم نام(Multiply) داریم که نوع پارامترهای ورودی آن ها متفاوت هستند در عمل ما تابع Multiply را overload کردیم، در زمان استفاده بر اساس نوع ورودی یکی از دو تابع فراخوانی می شود.class Main{
    public static void main(String[] args)
    {
        System.out.println(Helper.Multiply(2, 4));          //-- Output 8
        System.out.println(Helper.Multiply(5.5, 6.3));   //-- Output 34.65
    }
}یا در مثال دیگر:class Helper {
    // Method 1
    // Multiplication of 2 numbers
    static int Multiply(int a, int b)
    {
        // Return product
        return a * b;
    } 
    // Method 2
    // // Multiplication of 3 numbers
    static int Multiply(int a, int b, int c)
    {
        // Return product
        return a * b * c;
    }
}مانند مثال قبل در کلاس Helper ما دو تابع هم نام(Multiply) داریم با این تفاوت که تعداد پارامترهای ورودی آن ها متفاوت است یکی از توابع 2 ورودی و دیگری 3 ورودی دارد و در زمان فراخوانی براساس تعداد ورودی ها یکی از توابع فراخوانی می شود* نوع خروجی در overloading موردنظر نیست و فقط نوع یا تعداد پارامترهای ورودیچریک کدرز</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Tue, 07 May 2024 19:38:07 +0330</pubDate>
            </item>
                    <item>
                <title>معرفی DTO, Java Bean و POJO در جاوا</title>
                <link>https://virgool.io/CherikCoders/%D9%85%D8%B9%D8%B1%D9%81%DB%8C-dto-java-bean-%D9%88-pojo-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-cunxyslgamdt</link>
                <description>سلام :)خب اجازه بدید از DTO شروع کنیم، DTO یا Data Transfer Object در جاوا یک شی جهت انتقال داده ها بین زیرسیستم ها یا بخش های متفاوت پروژه و یک الگوی طراحی سازمانی(aggregate) برای جمع آوری داده ها است.DTO, Java Bean, POJO
قبل اینکه بیشتر ادامه بدیم چنتا مفهوم رو باید روشن کنیم، POJO و Java Beanیک Plain Old Java Object (POJO) یک شیء معمولی جاوا است. که می تواند هر کلاسی باشد و هیچ محدودیت خاصی غیر از مواردی که توسط زبان جاوا تجویز شده است، محدود نمی شود و برای قابلیت استفاده مجدد و افزایش خوانایی ایجاد شده اند. public class CoffeePOJO {
   public String name;
   private List&lt;String&gt; ingredients;
   public CoffeePOJO(String name, List&lt;String&gt; ingredients) { 
            this.name = name;
       this.ingredients = ingredients;
   }

   void addIngredient(String ingredient) {
       ingredients.add(ingredient);
   }
}همانطور که در مثال بالا مشاهده میکنید ما یک کلاس معمولی جاوا داریم :) اما یکسری نکات وجود داره که کلاس بالا یک POJO هست اما یک Java Bean نیست چرا که Java Beanها از یک سری استانداردها تحت عنوان JavaBean standard پیروی میکنند و هرکلاس POJO که این استاندارد ها را داشته باشد یک Java Bean هستش.بر اساس این استاندارد، تمام ویژگی ها(properties) خصوصی هستند(private) و با متدهای getter و setter قابل دسترسی خواهند بود. علاوه بر این، یک سازنده بدون آرگ وجود داشته باشد. به همراه چند مورد دیگر.بنابر این یک Java Bean حتما یک POJO هستش، اما هر POJO نمیتواند Java Bean باشد :)public class CoffeeBEAN implements Serializable {
   private String name;
   private List&lt;String&gt; ingredients;
   public CoffeeBEAN() {
   }
   public String getName() {
       return name;
   }
   public void setName(String name) {
       this.name = name;
   }
   public List&lt;String&gt; getIngredients() {
       return ingredients;
   }
   public void setIngredients(List&lt;String&gt; ingredients) {
       this.ingredients = ingredients;
   }
}پیاده سازی یک DTO: یک DTO را می توان به عنوان یک POJO یا یک جاوا Bean پیاده سازی کرد. مهمترین وظیفه DTO رفع نگرانی بین لایه presentation و domain model هستشبیایید یک سرویس rest کوچک برای توضیح این موضوع بنویسیم. مثال ما یک کافی شاپ با موجودیت های قهوه و مشتری داریم. هر دوی این ها موجودیت های جداگانه ای در سیستم هستند. اگر بخواهم قهوه مورد علاقه مشتری را بدانم، یک API ایجاد می کنم که داده های محاسبه شده را در FavoriteCoffeDTO را ارائه می دهد.کد مربوطه:@Entity
@Getter
@Setter
public class Coffee {
   private Long id;
   private String name;
   private List&lt;String&gt; ingredients;
   private String preparation;
}
@Entity 
@Getter 
@Setter
public class Customer {
   private Long id;
   private String firstName;
   private String lastName;
   private List&lt;Coffee&gt; coffees;
}
@Getter  
@Setter
public class FavoriteCoffeeDTO {
   private String name;
   private List&lt;String&gt; coffees;
}من لایه دامنه را از لایه ارائه در پیاده سازی بالا جدا کردم.در این مثال، من فیلدها را خصوصی کردم، به این معنی که برای دسترسی به فیلدها باید متدهای getter و setter ایجاد کنم. که ما از انوتیشن @Gettrو @Setter استفاده کردیم.کاربران اغلب انتخاب می کنند که استاندارد JavaBean را به طور کامل یا جزئی برای DTO دنبال کنند. البته این اجباری نیست، شما مختارید هر روشی را انتخاب کنید که با نیازهایتان مطابقت دارد. گزینه‌های دیگر عبارتند از عمومی کردن همه فیلدها و دسترسی مستقیم به آنها (مانند مثال زیر)، یا غیرقابل تغییر کردن شی با سازنده همه آرگ‌ها و برخی روش‌های دریافت‌کننده.public class FavoriteCoffeeDTO {
   public String name;
   public List&lt;String&gt; coffees;
}

String name = favCoffeeDTO.name;در ورژن های جدید جاوا می توانیم از record ها برای ایجاد DTOها استفاده کنیم که در یک مقاله به اون پرداختیم https://cherikcoders.ir/record-%d8%af%d8%b1-%d8%ac%d8%a7%d9%88%d8%a7/ مثال DTO با استفاده از Record:public record FavoriteCoffeeDTO(String name, List&lt;String&gt; coffees) {}

String name = favoriteCoffeeDTO.name();منبع: چریک کدرز</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Tue, 07 May 2024 10:16:46 +0330</pubDate>
            </item>
                    <item>
                <title>پروتکل TUS، آپلود Resumable فایل‌ها</title>
                <link>https://virgool.io/CherikCoders/%D9%BE%D8%B1%D9%88%D8%AA%DA%A9%D9%84-tus-%D8%A2%D9%BE%D9%84%D9%88%D8%AF-resumable-%D9%81%D8%A7%DB%8C%D9%84-%D9%87%D8%A7-vbzo8mpovqqm</link>
                <description>سلام :) توی این مقاله یک توضیح مختصر به همراه مثال براتون آماده کردم و در مقالات بعد اطلاعات کامل و سورس کدها را خدمتتان قرار می دمپروتکل tusخب بریم سراغ پروتکل tus, یک پروتکل متن باز برای انتقال فایل ها در بستر اینترنت طراحی شده است که قابلیت انتقال بخش به بخش داده ها یا همون chunk کردن فایل را فراهم میکند پس کل فایل به صورت یکجا ارسال نمی شود و به صورت قطعات کوچیک تر به سمت سرور ارسال می شوند که خب قابلیت های فراوانی را برای ما به ارمغان می آورد :) مثل قابلیت توقف و ادامه آپلود، از سر گیری آپلود بعد از قطع شدن ارتباط کلاینت و سرور، ارسال فایل های حجیم بدون نگرانی در اختلال اینترنت.پروتکل tus یک پروتکل استاندارد برای ارسال فایل بین کلاینت و سرور است که بر پایه ی HTTPS/HTTP است و برای پلتفرم‌های مختلف مانند مرورگرها و اپلیکیشن‌های دسکتاپ و موبایل طراحی و توسعه داده شده است.روند کلی کار tus به شکل زیر است:ایجاد یک آپلود جدید: کلاینت باید یک درخواست POST به آدرس سرور Tus بفرستد تا یک آپلود جدید را آغاز کند. سرور یک شناسه یکتا مثلا یک uuid تولید و به عنوان محل ذخیره سازی فایل در هدری به نام Location قرار میدهد و  پاسخ با کد وضعیت 201 Created به کلاینت ارسال میکند.ارسال قطعات فایل: کلاینت باید قطعات فایل را به سرور ارسال کند. این ارسال قطعه به قطعه انجام می شود و از متد PATCH برای انتقال قطعه استفاده می شود. هر قطعه باید با شناسه آپلود و موقعیت قطعه مشخص شده در هدر Upload-Offset فرستاده شود. سرور باید قطعه را در مکان مناسب ذخیره کند و اندازه و موقعیت قطعه(Upload-Offset) را در پاسخ به کلاینت برگرداند.تکمیل آپلود: هنگامی که کلاینت تمام قطعات فایل را ارسال کرد، باید یک درخواست PATCH اضافی را با موقعیت Upload-Offset برابر با اندازه کل فایل ارسال کند. سرور باید آپلود را تکمیل کند و فایل را در مکان نهایی ذخیره کند.در نهایت، باید توجه داشته باشید که هر نوع آپلود در پروتکل Tus یک شناسه منحصر به فرد دارد. این شناسه برای ادامه آپلود، متوقف کردن آپلود یا بازیابی وضعیت آپلود استفاده می شود. هرچند در این بین فرایند ها و موارد بیشتر از چیزی که در این مقاله مطرح شد وجود دارد که در مقالات بعد بیستر به آن ها خواهیم پرداخت.با استفاده از این مراحل، می توانید با موفقیت فایل ها را با استفاده از پروتکل Tus آپلود کنید.</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Mon, 04 Dec 2023 20:51:23 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش مقدمات AOP در Spring</title>
                <link>https://virgool.io/CherikCoders/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D9%85%D9%82%D8%AF%D9%85%D8%A7%D8%AA-aop-%D8%AF%D8%B1-spring-vp3k0chmui2z</link>
                <description>AOP در Springبرنامه نویسی جنبه گرا (AOP) ،AOP مخفف عبارت &quot;Aspect Oriented Programming&quot; است که به شیوه ای از برنامه نویسی اشاره دارد که در آن برنامه نویسی به صورت کلی تر و ابسترکت تر انجام می شود و به محصول نهایی قابل توجیه است.در AOP، به جای تکرار کد برای قابلیت هایی مانند لاگ کردن، پیدا کردن خطا و تراکنشات، از بلوک هایی که به عنوان &quot;مشاهده کننده ها&quot; (aspects) شناخته می شوند، استفاده می شود. این aspects مستقل از کد اصلی برنامه هستند و وظیفه آنها مدیریت قابلیت های مشترک در برنامه است.به عنوان مثال، فرض کنید که در برنامه شما برای انجام تراکنشات باید هر بار کدی را تکرار کنید که برای شروع و پایان یک تراکنش مورد استفاده قرار می گیرد. با استفاده از AOP، شما می توانید این کد را در یک aspect ذخیره کنید و هربار که برای تراکنشات نیاز دارید، از آن استفاده کنید.برای استفاده از AOP در Spring، می توانید از ابزارهایی مانند AspectJ و Spring AOP استفاده کنید. با استفاده از این ابزارها، می توانید کد خود را برای اجرای عملیات هایی logging، error checking، caching و… استفاده کنید.به طور خلاصه، AOP یک روش برنامه نویسی است که به شما این امکان را می دهد که از بلوک هایی که قابلیت های مشترک را برای کد شما فراهم می آورند، استفاده کنید و در نتیجه کدتان را بهبود بخشید.در Spring برای تعریف Aspect می توانید از انوتیشن های Spring استفاده کنید.فرض کنید که ما یک سیستم ساده احراز هویت کاربران داریم. به طور خاص، ما یک سرویس ورود (LoginService) داریم که دو متد دارد: login و logout. حال ما می خواهیم قبل و بعد از اجرای هر دو متد، لاگ هایی را بنویسیم تا بفهمیم چه کاری در هنگام ورود و خروج از سیستم انجام شده است. این می تواند با استفاده از AOP انجام شود.برای شروع، ما باید یک Aspect تعریف کنیم. Aspect ها در واقع قوانینی هستند که به منظور توصیف رفتاری که قرار است در قالب Advice (نظیر قرار دادن لاگ ها) در نقاط مختلف برنامه اجرا شود، تعریف می شوند.در اینجا ما یک Aspect ساده با نام LoggingAspect ایجاد می کنیم:@Aspe
@Componen
public class LoggingAspect {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Before(&amp;quotexecution(* com.example.demo.service.LoginService.*(..))&amp;quot)
    public void logBefore() {
        logger.info(&amp;quotBefore method execution&amp;quot);
    }

    @After(&amp;quotexecution(* com.example.demo.service.LoginService.*(..))&amp;quot)
    public void logAfter() {
        logger.info(&amp;quotAfter method execution&amp;quot);
    }
}در اینجا، ما یک Aspect به نام LoggingAspect تعریف کرده ایم که دارای دو Advice است: logBefore و logAfter. Advice ها در واقع رفتارهایی هستند که در نقاط مختلف برنامه قابل اجرا هستند. در اینجا، Advice های ما قبل و بعد از اجرای متد های login و logout سرویس ورود را شامل می شوند.همانطور که می بینید، ما از انوتیشن هایی مانند @Aspect و @Before و @After برای تعریف Aspect و Advice استفاده کرده ایم.همچنین با استفاده از عبارتexecution(* com.example.demo.service.LoginService.*(..))به Spring می گوییم که می خواهیم این Aspect و Advice ها را برای همه متهای LoginService اجرا شونددر این کلاس از @Aspect استفاده شده است که نشان می دهد که این کلاس یک Aspect است. همچنین از @Component نیز برای تشخیص این که این کلاس یک کامپوننت Spring استفاده شده است.همچنین در این کلاس، متدهای logBefore() و logAfter() به عنوان Advice های قبل از اجرای یک متد (Before advice) و بعد از اجرای یک متد (After advice) تعریف شده اند.توی این مطلب یک توضیح مختصر و یک مثال ساده زدیم در مطالب بعد بیشتر به این موضوع می پردازیم :)</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Sat, 25 Feb 2023 12:08:38 +0330</pubDate>
            </item>
                    <item>
                <title>ساخت docker-compose برای پروژه SpringBoot و MongoDB</title>
                <link>https://virgool.io/CherikCoders/%D8%B3%D8%A7%D8%AE%D8%AA-docker-compose-%D8%A8%D8%B1%D8%A7%DB%8C-%D9%BE%D8%B1%D9%88%DA%98%D9%87-springboot-%D9%88-mongodb-csdvdmzxhrb7</link>
                <description>خب برای شروع یک فایل به اسم docker-compose.yml در فولدر پروژه ایجاد میکنیمversion: &amp;quot3.8
	services:
	  mongo:
	    image: mongo:4.4
	    container_name: mongo
	    hostname: mongo&amp;quotیک سرویس ایجاد کردیم به نام mongo که از ایمیج mongo:4.4 استفاده میکنه میتونیم از ایمیج با هر تگ دیگه ای استفاده کنیم از لینک زیر سایر تگ های mongodb را ببینید https://hub.docker.com/_/mongo/tags بعد از مشخص کردن ایمیج یک اسم برای کانتینرمون انتخاب میکنیم و هاست نیم ست کردیمversion: &amp;quot3.8&amp;quot
	services:
	  mongo:
	    image: mongo:4.4
	    container_name: mongo
	    hostname: mongo
	    ports:
	      - &amp;quot27017:27017&amp;quot
	    environment:
	      - MONGO_INITDB_ROOT_USERNAME=root
	      - MONGO_INITDB_ROOT_PASSWORD=root
	      - MONGO_INITDB_DATABASE=mydb
        networks:
	      - mongo-network

networks
	  mongo-network:
	      name: mongo-networkدر ادامه پورت mongo رو به یکی از پرت های سیستم مپ کردیم و ورودی های خودمون که environment ها هستن مشخص کردیمهمچنین یک شبکه جدید ایجاد کردیم به اسم mongo-network :)برای ذخیزه ی دیتاهامون نیاز هستش که volumes را ست کنیم:version: &amp;quot3.8&amp;quot
	services:
	  mongo:
	    image: mongo:4.4
	    container_name: mongo
	    hostname: mongo
	    ports:
	      - &amp;quot27017:27017&amp;quot
	    environment:
	      - MONGO_INITDB_ROOT_USERNAME=root
	      - MONGO_INITDB_ROOT_PASSWORD=root
	      - MONGO_INITDB_DATABASE=mydb
        volumes:
	      - ./mongo/data/db/:/data/db/
	      - ./mongo/log/mongodb/:/var/log/mongodb/
	      - ./mongo/initdb.d/:/initdb.d/
        networks:
	      - mongo-network

networks
	  mongo-network:
	      name: mongo-networkسه فولدر در مسیر جاری پروژه ایجاد میکنیم به شکل زیرmkdir ./mongo/data
mkdir ./mongo/log
mkdir ./mongo/initdb.dخب کارمون تقریبا با mongo تموم شد فقط یک بخش باقی مونده که یک یوزر بسازیم تا از اون در SpringBoot استفاده کنیمبرای اینکار نیازه هست یک shell اسکریپت مینویسیم به اسم create-user.sh و در فولدر initdb.d قرار میدهیم تا در زمان ساخت کانتینر اجرا شود#!/bin/bash
mongo -u &amp;quotroot&amp;quot -p &amp;quotroot&amp;quot --authenticationDatabase &amp;quotadmin&amp;quot &amp;quotmydb&amp;quot --eval &amp;quotdb.createUser({ user: &#039;user1&#039;, pwd: &#039;user1&#039;, roles: [{ role: &#039;dbOwner&#039;, db: &#039;mydb&#039; }] })&amp;quotاسکریپت بالا یک کاربر با نام کاربری و رمز user1 که دسترسی کامل به بانک اطلاعاتی mydb دارد ایجاد میکنددیگ بریم سراغ اسپرینگ :)قبل هرچیز نیازه یک داکر فایل برای پروژه ایجاد کنیم،برای اینکار یک فایل به نام Dockerfile ایجاد میکنیم نمونه زیر ساده ترین حالت ممکن هستشFROM openjdk:17.0.1-jdk-slim

COPY target/*.jar  app.jar
EXPOSE 8080
ENTRYPOINT [&amp;quotjava&amp;quot,&amp;quot-jar&amp;quot,&amp;quotapp.jar&amp;quot]توی این مثال چون ورژن جاوا من 17 بود از ایمیج openjdk:17.0.1-jdk-slim استفاده کردماین داکر فایل jar فایل موجود در فولدر target را داخل کانتینر ما کپی میکند و بعد اونو اجرا میکنهاما مشکلی که داره اینه که نیازه که پروژه از قبل build شده باشدمیتونیم داکر فایلمونو به شکل زیر تغییر بدیم تا خودش package برامون بسازهFROM maven:3.8.3-openjdk-17 AS builder
ADD . /app
WORKDIR /app
RUN mvn -f /app/pom.xml clean package
FROM openjdk:17.0.1-jdk-slim
	
COPY --from=builder /app/target/*.jar  app.jar	
EXPOSE 8080	
ENTRYPOINT [&amp;quotjava&amp;quot,&amp;quot-jar&amp;quot,&amp;quotapp.jar&amp;quot]حال فایل docker-compose.yml ویرایش میکنیم و یک سرویس جدید بهش اضافه میکینمversion: &amp;quot3.8&amp;quot
services:
  mongo:
    image: mongo:4.4
    ...

  web:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: app
    restart: always
    depends_on:
      - mongo
    ports:
      - &amp;quot8080:8080&amp;quot
    environment:
      - SERVER_PORT=8080
      - SPRING_PROFILES_ACTIVE=prod
      - SPRING_APPLICATION_NAME=myapp
      - SPRING_DATA_MONGODB_AUTHENTICATION_DATABASE=admin
      - SPRING_DATA_MONGODB_AUTO_INDEX_CREATION=true
      - SPRING_DATA_MONGODB_HOST=mongo
      - SPRING_DATA_MONGODB_PORT=27017
      - SPRING_DATA_MONGODB_USERNAME=user1
      - SPRING_DATA_MONGODB_PASSWORD=user1
      - SPRING_DATA_MONGODB_DATABASE=mydb
    networks:
      - mongo-network

networks:
  mongo-network:
      name: mongo-networkنیازه که environmentهارو بر اساس پروژه خودمون تنظیم کنیم :) https://gist.github.com/sheikhoo/dbaaf0342fe121ea5f0b1d45515e9fd5 کارمون دیگ تمومه کافیه دستور زیر رو اجرا کنیم تا پروژه و mongo روی داکر راه اندازی بشنdocker-compose upهمین :)</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Sat, 25 Feb 2023 07:54:00 +0330</pubDate>
            </item>
                    <item>
                <title>ست کردن ip دلخواه بر روی کانتینرهای داکر</title>
                <link>https://virgool.io/@m.s.sheikhzahedi/%D8%B3%D8%AA-%DA%A9%D8%B1%D8%AF%D9%86-ip-%D8%AF%D9%84%D8%AE%D9%88%D8%A7%D9%87-%D8%A8%D8%B1-%D8%B1%D9%88%DB%8C-%DA%A9%D8%A7%D9%86%D8%AA%DB%8C%D9%86%D8%B1%D9%87%D8%A7%DB%8C-%D8%AF%D8%A7%DA%A9%D8%B1-uu9fun5fpedq</link>
                <description> ابتدا نیازه یک شبکه در Docker ایجاد کنیم برای اینکار:docker network create --subnet=192.168.0.0/16 mynetworkبا استفاده از دستور docker network create میتوانیم یک شبکه جدید در docker بسازیمما با استفاده از دستور بالا یک شبکه با subnet موردنظرمان ساختیمحال میتوانیم کانتینرمونو روی این شبکه بسازیمdocker run --network mynetwork -d nginxبرای کانتینرمون می توانیم ip هم ست کنیم برای اینکار از --ip استفاده میکنیمdocker run --network mynetwork --ip 192.168.5.10 -d nginxالبته میتوانیم برای شبکه ای که ساختیم gateway و ip-range را هم تنظیم کنیمdocker network create \
  --driver=bridge \
  --subnet=192.168.0.0/16 \
  --ip-range=192.168.5.0/24 \
  --gateway=192.168.5.1 \
  mynetworkهمین :)</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Sat, 25 Feb 2023 07:43:03 +0330</pubDate>
            </item>
                    <item>
                <title>آپلود فایل در سرور با Oracle Apex</title>
                <link>https://virgool.io/@m.s.sheikhzahedi/%D8%A2%D9%BE%D9%84%D9%88%D8%AF-%D9%81%D8%A7%DB%8C%D9%84-%D8%AF%D8%B1-%D8%B3%D8%B1%D9%88%D8%B1-%D8%A8%D8%A7-oracle-apex-rcl9gi6xm64p</link>
                <description>سلام :) توی این آموزش میخواهیم فایل ها با استفاده از Oracle Apex درون یک فولدر در سرور آپلود کنیمقبل از هرچیز نیازه یک دایرکتوری جهت آپلود فایل هامون ایجاد کنیم.mkdir /u02/uploadFileخب فولدرو ایجاد کردیم، حال باید یک directory در بانک اطلاعاتیمون ایجاد کنیمsqlplus
create directory upload_image_dir as &#039;/u02/uploadFile&#039;;و به این directory مجوز های لازم رو میدیمgrant read on directory upload_image_dir  to anonymous;
grant read on directory upload_image_dir  to admin;اوکی بریم سراغ apex، یک صفحه ی جدید ایجاد کنیدخب حالا یک Static Content داخل صفحه قرار میدیم و داخل اون یک آیتم از نوع File Browse که اسم اون رو من P6666-FILE قرار دادمبه بخش Processing برید و یک process جدید ایجاد کنیم جهت آپلود فایل در directory مانند تصویر زیرکدهای زیر را داخل بخش PL/SQL Code قرار دهیدDECLARE
    V_IMAGE APEX_APPLICATION_TEMP_FILES.BLOB_CONTENT%TYPE;
    V_FILENAME APEX_APPLICATION_TEMP_FILES.FILENAME%TYPE;
BEGIN
    BEGIN
        SELECT BLOB_CONTENT,FILENAME INTO V_IMAGE,V_FILENAME
            FROM APEX_APPLICATION_TEMP_FILES
            WHERE UPPER(NAME)=UPPER(:P6666_FILE);
        EXCEPTION WHEN NO_DATA_FOUND THEN
            V_IMAGE:=NULL;
            V_FILENAME:=NULL;
        WHEN OTHERS THEN
            V_IMAGE:=NULL;
            V_FILENAME:=NULL;
    END;
    IF V_IMAGE IS NOT NULL AND V_FILENAME IS NOT NULL THEN
        SAVEFILE&#40;V_IMAGE,&#039;UPLOAD_IMAGE_DIR&#039;,V_FILENAME&#41;;
    ELSE
        APEX_ERROR.ADD_ERROR (
        p_message  =&gt; &#039;Image Not Upload&#039;,
        p_display_location =&gt; apex_error.c_inline_in_notification );
    END IF;
END;همانطور که مشاهده میکنید در کد بالا یک پروسیجر صدا زدیم به اسم SaveFile که سه تا ورودی دارهفایل ما از نوع BLOBدایرکتوری که فایل باید داخل اون آپلود بشه VARCHAR2 (که قبلا اونو به اسم UPLOAD_IMAGE_DIR تعریف کردیم)اسم فایل VARCHAR2  حال بریم پروسیجر SaveFile درون پایگاه داد جهت ذخیره ی فایل ها درون فولدر ایجاد کنیم.create or replace PROCEDURE SaveFile&#40;
     FileContent IN OUT NOCOPY BLOB
   , FolderName IN VARCHAR2
   , FileName IN VARCHAR2&#41;
IS
    BUFFER RAW(1024);
    OFFSET PLS_INTEGER := 1;
    FileLength PLS_INTEGER;
    amount PLS_INTEGER := 1024;
    fhandle UTL_FILE.FILE_TYPE;
BEGIN
    FileLength := DBMS_LOB.GETLENGTH(FileContent);
    fhandle := UTL_FILE.FOPEN&#40;FolderName, FileName, &#039;wb&#039;&#41;;         
    LOOP
        EXIT WHEN OFFSET &gt; FileLength;
        DBMS_LOB.READ(FileContent, amount, OFFSET, BUFFER);
        UTL_FILE.PUT_RAW(fhandle, BUFFER, TRUE);
        OFFSET := OFFSET + amount;
    END LOOP;
    UTL_FILE.FCLOSE (fhandle);
EXCEPTION
    WHEN OTHERS THEN
        IF UTL_FILE.IS_OPEN(fhandle) THEN
            UTL_FILE.FCLOSE(fhandle);
        END IF;
    RAISE;
END SaveFile;فقط یک نکته کوچیک باقی مونده اونم اینه یک دکمه از نوع Submit قرار بدیم و تمام :)</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Tue, 03 Jan 2023 11:00:19 +0330</pubDate>
            </item>
                    <item>
                <title>RabbitMQ چیست؟ استفاده از RabbitMQ در Spring Boot</title>
                <link>https://virgool.io/CherikCoders/rabbitmq-%DA%86%DB%8C%D8%B3%D8%AA-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-rabbitmq-%D8%AF%D8%B1-spring-boot-oeba0v1jpkry</link>
                <description>قبل هرچیز یک نگاه به RabbitMQ بندازیم :)خب RabbitMQ یک نرم افزار رایج انتقال پیام(messaging broker) بین برنامه ها و سیستم هاست که به آن ها اجازه می دهد به یکدیگر متصل شوند و ارتباط برقرار کنند. این یک روش رایج برای سرویس ها در سیستم های مبتنی بر میکروسرویس(microservices-based systems) است که به‌صورت نامتقارن از طریق ارسال پیام و عملیات صف بندی ارتباط برقرار کنند.برای اینکه بیشتر درمورد RabbitMQ بدونید و نحوه ی کار اون آشنا بشید یه سر به این مقاله برنید https://virgool.io/@mabdi/rabbitmq-%DA%86%DB%8C%D8%B3%D8%AA-%D9%88-%DA%86%D9%87-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%DB%8C-%D8%AF%D8%A7%D8%B1%D8%AF-lkdktial4v3g یه توضیح کوچیک در باره نحوه ی کار RabbitMQ اینجا بهتون میدم، بعد میریم سراغ Spring Bootپیام رسانی در RabbitMQ شامل موارد زیر است:producer یک برنامه کاربری است که پیام ها را به RabbitMQ ارسال می کند. پیام ها مستقیماً به یک صف(queue) ارسال نمی شوند.در اینجا، producer پیام را به یک exchange ارسال می کند. exchange مسئولیت مسیریابی پیام به صف های(queues) مختلف را بر عهده دارندبه زبان ساده producer برنامه ای است که پیام های اولیه را تولید میکنه و به RabbitMQ ارسال می کند پیام ها ابتدا در exchange مشخص میشود که وارد کدام صف شوندصف(queue) یک بافر است که در داخل RabbitMQ قرار دارد تا پیام هایی را که تولیدکننده می فرستد و گیرنده دریافت می کند ذخیره کند.consumer یک برنامه کاربردی کاربر است که پیام ها را از RabbitMQ دریافت می کند و سپس آنها را پردازش می کند.در تصویر زیر این فرایند را مشاهده می کنیدنصب RabbitMQحالا که با RabbitMQ آشنا شدیم وقتشه تا اونو نصب کنیم، البته من برای نصب و استفاده از داکر استفاده میکنم پیشنهاد می کنم شماهم بجای نصب خود نرم افزار از کانتینرهای داکر استفاده کنید.کار سختی نیست کافیه داکر روی سیستم نصب داشته باشید و دستور زیر را در cmd یا terminal اجرا کنیدdocker run -d --name my-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3.9-managementحالا اگر داخل مرورگر http://localhost:15672 بزنید محیط مدیریت RabbitMQ براتون باز میشه و میتونید با یوزر guest و پسورد guest وارد شوید. هرچند ما با این محیط فعلا کاری نداریم اما میتونید مفاهیمی که بالا گفتیم اینجا مشاهده کنید.سورس پروژهپروژه ای که در ادامه قراره توضیح بدیمو میتونید از لینک زیر دریافت کنید :)  https://github.com/sheikhoo/RabbitMQ-SpringBoot-Example آماده سازیایجاد پروژه و Dependenciesوقتشه بریم سراغ SpringBoot یک پروژه جدید ایجاد کنید، برای استفاده از RabbitMQ نیاز هستش تا کتابخانه spring-boot-starter-amqp را به پروژه خودمون اضافه کنیم. برای اینکار کد زیر را در فایل pom.xml قرار دهید&lt;dependency&gt;
      &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
      &lt;artifactId&gt;spring-boot-starter-amqp&lt;/artifactId&gt;
&lt;/dependency&gt;ایجاد Modelیک کلاس POJO که میخواهیم اشیاء آن را به عنوان پیام مبادله (ارسال/دریافت) کنیم ایجاد میکنیم. در اینجا من اسم کلاسمو Message میزارم شما میتونید هر مدلی که دوست دارید بسازید مثلا User، Student، Log یا هرچیز دیگه ایpackage ir.sheikhoo.rabbitmqspringboot.model;
public class Message {
    private String title;
    private String text;
    private String sender;
    // ... getter و setter هارو اینجا قرار بدید
}application.propertiesفایل پیکربندی(application.properties) باید به شکل زیر باشد:server.port= 8080
spring.rabbitmq.host= localhost
spring.rabbitmq.port= 5672
spring.rabbitmq.username= guest
spring.rabbitmq.password= guest
queue.name= example_queue
fanout.exchange= example_exchangeخط اول port که قراره برنامه ما روی اون اجرا بشه رو مشخص کردیم، 4 خط بعد هم اطلاعات RabbitMQ را برای اتصال به اونو به برناممون دادیم.خط 5 یک اسم برای صف یا همون queue انتخاب کردیم که ما در اینجا اسمشو example_queue گذاشتیم و خط 6 هم یک اسم برای exchange انتخاب کردیم که اینجا ما اونو example_exchange گذاشتیم.تنظیمات RabbitMQیک کلاس جاوا جدید برای RabbitMQ configuration به نام RabbitConfiguration.java ایجاد می کنیمنکته: انوتیشن @Configuration در بالا کلاس فراموش نکنیدpackage ir.sheikhoo.rabbitmqspringboot.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitConfiguration {
    @Value(&amp;quot${fanout.exchange}&amp;quot)
    private String fanoutExchange;

    @Value(&amp;quot${queue.name}&amp;quot)
    private String queueName;

    @Bean
    Queue queue() {
        return new Queue(queueName, true);
    }

    @Bean
    FanoutExchange fanoutExchange() {
        return new FanoutExchange(fanoutExchange);
    }

    @Bean
    Binding binding(Queue queue, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(queue).to(fanoutExchange);
    }
}بیایید نگاهی دقیق به این کلاس پیکربندی بیندازیم:انوتیشن @Value حاوی نام queue و exchange است که از application.properties می خواند.تابع queue() جهت ایجاد یک صف جدید برای ذخیره Messageهای ما بکار میرود.تابع fanoutExchange() جهت ایجاد یک exchange جدید از نوع FanoutExchange استفاده می شود. FanoutExchange فقط تمام پیام هایی را که دریافت می کند به تمام صف هایی که می شناسد پخش می کند.تابع binding() صف و exchange را به هم متصل می کند.ساخت Producerخب Producer که یادتون هست بالا درموردش صحبت کردیم، حال میخواهیم یک Producer  برای ارسال پیام های از جنس Message به صف RabbitMQ ایجاد کنیم اسم این کلاس را QueueProducer قرار می دهیمما از درون producer و consumer استفاده میکنیم که ارائه شده توسط چارچوب Spring Boot است.package ir.sheikhoo.rabbitmqspringboot.config;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import ir.sheikhoo.rabbitmqspringboot.model.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class QueueProducer {
    @Value(&amp;quot${fanout.exchange}&amp;quot)
    private String fanoutExchange;

    private final RabbitTemplate rabbitTemplate;
    @Autowired
    public QueueProducer(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }
    public void produce(Message message) throws JsonProcessingException {
        rabbitTemplate.setExchange(fanoutExchange);
        rabbitTemplate.convertAndSend(new ObjectMapper().writeValueAsString(message));
    }
}تابع convertAndSend() با استفاده از ObjectMapper مدل ما را به JSON تبدیل میکند تا بتوان درون صف آن را ذخیره نماییم.ساخت Consumerبرای دریافت پیام ها() از صف به Consumer نیاز داریم اسم این کلاس QueueConsumer میزاریمpackage ir.sheikhoo.rabbitmqspringboot.config;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import ir.sheikhoo.rabbitmqspringboot.model.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class QueueConsumer {
    private final RabbitTemplate rabbitTemplate;

    @Value(&amp;quot${queue.name}&amp;quot)
    private String queueName;

    @Autowired
    public QueueConsumer(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }
    private String receiveMessage() {
        String message = (String) rabbitTemplate.receiveAndConvert(queueName);
        return message;
    }

    public Message processMessage() throws JsonProcessingException {
        String message = receiveMessage();
        return new ObjectMapper().readValue(message, Message.class);
    }
}ساخت کنترلربا ساخت یک controller و قرار دادن همه بخش های کنار هم میتوانیم از برنامه که نوشتیم استفاده کنیمpackage ir.sheikhoo.rabbitmqspringboot.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import ir.sheikhoo.rabbitmqspringboot.config.QueueConsumer;
import ir.sheikhoo.rabbitmqspringboot.config.QueueProducer;
import ir.sheikhoo.rabbitmqspringboot.model.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping(&amp;quot/&amp;quot)
public class LogsController {

    @Autowired
    private QueueProducer queueProducer;
    @Autowired
    private QueueConsumer queueConsumer;

    @GetMapping(&amp;quotgetMessage&amp;quot)
    public ResponseEntity&lt;?&gt; getMessage() throws JsonProcessingException {
        Message message = queueConsumer.processMessage();
        return new ResponseEntity&lt;Message&gt;(message, HttpStatus.OK);
    }

    @PostMapping(&amp;quotsendMessage&amp;quot)
    public ResponseEntity&lt;?&gt; sendMessage(@RequestBody Message message) throws
JsonProcessingException {
        queueProducer.produce(message);
        return new ResponseEntity&lt;Message&gt;(HttpStatus.CREATED);
    }
}بعد از اجرا پروژه با استفاده از postman میتوانید درخواست POST و GET پیام ها را به صف ارسال نمایید یا از صف استخراج کنیدارسال و قرار دادن پیام به صف:[POST] http://localhost:8080/sendMessageBody:{ 
     &amp;quottitle&amp;quot:&amp;quotHello,RabbitMQ&amp;quot, 
     &amp;quottext&amp;quot:&amp;quotThis is my message&amp;quot,
     &amp;quotsender&amp;quot:&amp;quotadmin&amp;quot 
} دریافت پیام از صف:[GET] http://localhost:8080/getMessage</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Mon, 02 Jan 2023 22:30:17 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش ابزار Frama-c برای آزمون نرم افزار</title>
                <link>https://virgool.io/coderlife/frama-c-zz667tj2j1ju</link>
                <description>ابزار Frama-C مخفف (Framework for Modular Analysis of C programs) یا (چارچوب برای تجزیه و تحلیل مدولار برنامه های C) که جهت تحلیل کدهای برنامه به زبان c مورد استفاده می باشد.ابزار Frama-C مجموعه ای از آنالایزرهای برنامه قابل تعامل برای برنامه های C است.به عنوان آنالایزر استاتیک، برنامه ها را بدون اجرای آنها بازرسی می کند.این ابزار برای سیستم عامل های Mac و لینوکس ارائه شده و از طریق ماشین های مجازی همچون VM،Cygwin و یا WIndows Subsystem for Linux در ویندوز نیز قابل استفاده می باشد.من از سیستم عامل Ubuntu 18.04 LTS که بر روی VMware نصب کردم استفاده می کنم و آموزش بر اساس این سیستم عامل تهیه کردمسیستم عامل ubuntu نصب شده بر روی VMطریقه نصب Frama-cجهت نصب Frama-c در ubuntu ابتدا terminal را باز میکینم و با استفاده از دستور زیر نصب انجام می شودsudo apt-get update -y
sudo apt-get install -y frama-cو تمام، frama-c بر روی سیستم عامل شما نصب شد. اکنون می توانیم به دو صورت از این ابزار استفاده نمایید یکی با استفاده از خط دستور terminal و دیگری محیط گرافیکی ابزار است.جهت مشاهده ی محیط گرافیکی درون terminal دستور زیر را وارد می نماییمframa-c-guiکه محیط آن به شکل زیر می باشدمحیط ابزار frama-cدر صورتی که در زمان اجرای frama-c-gui با خطای زیر مواجه شدیدGtk-Message: Failed to load module &quot;canberra-gtk-module&quot; خطای با استفاده از این دستور مشکل برطرف می شودsudo apt-get install libcanberra-gtk*شروع کارما در این بخش به بررسی call graph, inout, users, metrics, pdg, post dominators, slicing, WP بر روی سورس کد زبان C که در ادامه آن را قرار می دهم میپردازیم، هرچند برای تست نرم افزار آیتم های متنوعی وجود دارد اما ما فقط مواردی که گفتیم می پردازیمسورس برنامهسورس کدی که ما انتخاب کردیم، مرتب سازی انتخابی (Selection Sort ) می باشد که شامل دو تابع یکی جهت مرتب سازی و دیگر چاپ نتیجه در خروجی است.#include &lt;stdio.h&gt;
void selection_sort(int a[],int n);
void show_sort_output(int a[],int n);
void main()
{
    int a[30], n;
    int i;
    printf(&amp;quot\nEnter size of an array: &amp;quot);
    scanf(&amp;quot%d&amp;quot, &amp;n);
    printf(&amp;quot\nEnter elements of an array:\n&amp;quot);
    for(i=0; i&lt;n; i++)
        scanf(&amp;quot%d&amp;quot, &amp;a[i]);
    selection_sort(a,n);
    printf(&amp;quot\n\nAfter sorting:\n&amp;quot);
    show_sort_output(a,n);
}
void selection_sort(int a[],int n)
{
    int i, j, min, temp;
    for (i=0; i&lt;n; i++)
    {
        min = i;
        for (j=i+1; j&lt;n; j++)
        {
            if (a[j] &lt; a[min]
                min = j;
        }
        temp = a[i];
        a[i] = a[min];
        a[min] = temp;
    }
}
void show_sort_output(int a[],int n)
{
    int i;
    for(i=0; i&lt;n; i++)
        printf(&amp;quot\n%d&amp;quot, a[i]);
}برای ورود کد مورد نظر به ابزار در منو Projects گزینه New Project را انتخاب و فایل برنامه مورد نظر را انتخاب می کنیمایجاد پروژه جدید در Frama-cنمودار Call graph:یک نمودار جریان کنترل است، که بیانگر روابط فراخوان بین زیر خطوط در یک برنامه کامپیوتری است. به طور کلی فراخوانی متدها(پروسیجرها، توابع و ...) برنامه را نمایش می دهد.با استفاده از محیط گرافیکی:جهت مشاهده call graph سورس کد خودمان از منوی Analyses گزینه show callgraph را انتخاب می کنیم call graph در frama-cنتیجه به شکل زیر می باشدcall graphبا استفاده از terminal:همچنین می توان با استفاده از دستور زیر درون terminal نتیجه را به صورت متنی ذخیره کردframa-c-gui -cg call_graph.txt main.cکه call_graph.txt فایل خروجی می باشد و main.c سورس کد برنامهتست ورودی و خروجی inout:جهت به دست آوردن ورودی ها و خروجی از هر یک از توابع برنامه مورد استفاده قرار می گیردبا استفاده از محیط گرافیکی:برای تهیه inout برنامه ابتدا به منو Analyses رفته سپس بر روی Analyses کلیک کرده و از منوی سمت چپ inout را کلیک کرده و مقادیر out, input, inout را انتخاب کرده و نتیجه در کنسول به نمایش در خواهد آمد.به عنوان مثال بخشی از نتیجه تولید شده در console برای تابع selection_sort به شکل زیر می باشد، که در آن ورودی ها و خروجی های این تابع را بررسی کرده است[inout] Out (internal) for function selection_sort:
          a[0..29]; i; j; min; temp
[inout] Inputs for function selection_sort:
          a[0..29]
[inout] InOut (internal) for function selection_sort:
        Operational inputs:
          a[0..29]; a; n
        Operational inputs on termination:
          a[0..29]; a; n
        Sure outputs:
          iبا استفاده از terminal: می توانیم با استفاده از دستور زیر درون terminal نتیجه را به صورت متنی ذخیره کنیمframa-c -inout main.c &gt; inout.txtبا اجرای دستور بالا همان نتایج تولید شده درون consol در بخش گرافیک ابزار درون فایل inout.txt ذخیره می شوندآزمون کاربران users:این آزمون توابع فراخوانی شده، printf ها و scanf های یک تابع را نشان میدهد.با استفاده از محیط گرافیکی:برای استفاده از این آزمون در منو Analyses گزینه Analyses را انتخاب کرده و در پنجره باز شده گزینه users را انتخاب میکنیم سپس مقدار user- را انتخاب کرده و بر روی execute کلیک می کنیم تا در کنسول نتیجه تولید شود.frama-c users نتیجه ی این آزمون بر روی سورس کد ما به شکل زیر می باشدshow_sort_output: printf_va_4
main: selection_sort show_sort_output printf_va_1 scanf_va_1 printf_va_2
scanf_va_2 printf_va_3 printf_va_4از این خروجی متوجه می شویم که هر یک از توابع ما چه توابعی صدا زدن، چه دستورات ورودی و خرجی داشتن(printf و scanf)، برای مثال تابع main توابع selection_sortو show_sort_output را صدا زده است و همچنین دارای دو printf و یک scanf هست.با استفاده از terminal: می توانیم با استفاده از دستور زیر درون terminal نتیجه را به صورت متنی ذخیره کنیمframa-c -users main.c &gt; user.txtآنالیز metric:در Metrics اطلاعاتی نظیر تعداد توابع، entry point، حلقه های تکرار، شرط ها و ... را به دست بیاورید.جهت بدست آوردن metric از دستور زیر استفاده می کنیمframa-c main.c -metricsکه main.c نام سورس کد ما هستش، جهت ذخیره خروجی درون فایل txt از دستور زیر استفاده می کنیمframa-c main.c -metrics &gt; metric.txtخروجی به شکل زیر می باشد:         Defined functions (3)
          =====================           
         main (0 call); selection_sort (1 call); show_sort_output (1 call); 

          Undefined functions (6)
          =======================
           printf_va_1 (1 call); printf_va_2 (1 call); printf_va_3 (1 call);
           printf_va_4 (1 call); scanf_va_1 (1 call); scanf_va_2 (1 call); 
          
          &#039;Extern&#039; global variables (0)
          =============================

          Potential entry points (1)
          ==========================
           main; 
          
          Global metrics
          ============== 
          Sloc = 39
          Decision point = 5
          Global variables = 0
          If = 5
          Loop = 4
          Goto = 0
          Assignment = 13
          Exit point = 3
          Function = 9
          Function call = 8
          Pointer dereferencing = 7
          Cyclomatic complexity = 8همانطور که مشاهده می نمایید ما سه تابع داریم، نقطه ی ورود ما تابع main است، 5 شرط، 4 حلقه، 3 نقطه ی خرج و .... داریمآنالیز metricآنالیز PDG:گراف PDG گراف وابستگی برنامه یا Program Dependence Graph، یک گراف تولید شده از وابستگی های داده ای و وابستگی اجرایی دستورات نسبت به هم تهیه می شوند.برای استخراج PDG ابتدا سورس کد را به قالب فایل dot تبدیل کرده و سپس آن به pdf تبدیل می کنیم، برای اینکار به شکل زیر عمل میکنیم:با استفاده از دستور زیر فایل .dot را تولید کردهframa-c -pdg -pdg-dot graph -pdg-print main.c &gt; pdg.dotسپس با دستور زیر آن را به pdf  تبدیل می کنیمdot -Tpdg graph.main.dot &gt; pdg.pdfخروجی pdgآنالیز Postdominators:در Post Dominator دستوراتی که بر روی دستورات دیگر تاثیر میگذارد را مشخص می کنیم و به شکل یک گراف به نمایش داده می شود. این آنالیز با scanf و printf مشکل دارد و باعث ایجاد خطا می شود برای استفاده از این آنالیز، من ورودی را دستی وارد کردم و حذف scanf ها، همچنین کامنت کردن دستورات  printf که سورس کد به شکل زیر تغییر کرد:#include &lt;stdio.h&gt;
void selection_sort(int a[],int n);
void show_sort_output(int a[],int n);
void main()
{
int a[30], n;
int i;
//printf(&amp;quot\nEnter size of an array: &amp;quot);
//scanf(&amp;quot%d&amp;quot, &amp;n);
n=5;
//printf(&amp;quot\nEnter elements of an array:\n&amp;quot);
for(i=0; i&lt;n; i++)
a[i]=i;
selection_sort(a,n);
//printf(&amp;quot\n\nAfter sorting:\n&amp;quot);
show_sort_output(a,n);
}
void selection_sort(int a[],int n)
{
int i, j, min, temp;
for (i=0; i&lt;n; i++)
{
min = i;
for (j=i+1; j&lt;n; j++)
{
if (a[j] &lt; a[min])
min = j;
}
temp = a[i];
a[i] = a[min];
a[min] = temp;
}
}
void show_sort_output(int a[],int n)
{
int i;
//for(i=0; i&lt;n; i++)
//printf(&amp;quot\n%d&amp;quot, a[i]);
}با استفاده از دستور زیر گراف تولید می نماییمframa-c main.c -dot-postdom mainو با استفاده از دستور زیر آن را به pdf تبدیل می کنیمdot -Tpdf main.main.dot &gt; postdom.pdfخروجی:Postdominatorsبرش بندی یا Slicingیک برش از برنامه حاوی دستوراتی از آن است که ویژگیهای مشخصی از برنامه را به نمایش میگذارد.. برشبندی برای اولین بار برای یافتن عامل بروز خرابی برنامهها ارائه شد؛ اما بعد از آن، کاربردهای مختلفی پیدا کرد. برای مثال، برای یافتن دو برنامه که از نظر معنایی به یکدیگر شباهت دارند میتوان از برشبندی استفاده نمود. به همینترتیب، برای یافتن میزان چسبندگی یک برنامه از برشبندی استفاده میکنند.در Slicing بر اساس تعیین یک متغیر میتوان دستوراتی که بر روی آن متغیر تاثیر مستقیم و یا غیر مستقیم دارند را شناسایی کنیم.برش بندی را می توان به دو صورت wr و rd انجام دهیم که در ادامه تفاوت این دو را مشاهده می نماییدبا استفاده از دستور زیر بر روی متغیر a ، slicing انجام میدهیم و عبارت wr به این معنی میباشد که در متغیر مورد نظر نوشته شده است.frama-c -slice-wr a main.c -slice-print &gt; slice_a_wr.txtیا با دستور زیر بر روی متغیر a و عبارت rd به این معنی می باشد که از متغیر مورد نظر خوانده شده است(استفاده شده است)frama-c -slice-rd a main.c -slice-print &gt; slice_a_rd.txtهمانطور که در تصویر مشخص است در فایل سمت چب بر اساس rd متغیر a تولید شده است تابع show_sort_output نیز آورده شده است ولی در برش wr وجود ندارد.آنالیز WP:خواص را به صورت قیاسی تأیید می کند، بر پارامتر کردن با توجه به مدل حافظه تمرکز دارد. WP طوری طراحی شده است که برنامه C را مستقیماً به زبان Why وارد می کند ، با سایر افزونه های Frama-C مانند افزونه تجزیه و تحلیل ارزش همکاری می کند. WP می تواند به صورت اختیاری از پلت فرم Why3 برای استناد به بسیاری از پیش بینی های خودکار و تعاملی دیگر استفاده کند.برای تهیه WP باید از طریق ترمینال دستور زیر را اعمال نماییم.frama-c -wp -wp-rte main.c &gt; wp.txtخروجی تولید شده:[kernel] Parsing FRAMAC_SHARE/libc/__fc_builtin_for_normalization.i (no preprocessing)
[kernel] Parsing main.c (with preprocessing)
[wp] Running WP plugin...
[rte] annotating function main
[rte] annotating function selection_sort
[rte] annotating function show_sort_output
main.c:12:[wp] warning: Allocation, initialization and danglingness not yet implemented
              (\initialized(param0))
main.c:11:[wp] warning: Missing assigns clause (assigns &#039;everything&#039; instead)
main.c:9:[wp] warning: Allocation, initialization and danglingness not yet implemented
              (\initialized(param0))
main.c:23:[wp] warning: Missing assigns clause (assigns &#039;everything&#039; instead)
main.c:20:[wp] warning: Missing assigns clause (assigns &#039;everything&#039; instead)
main.c:36:[wp] warning: Missing assigns clause (assigns &#039;everything&#039; instead)
[wp] 20 goals scheduled
[wp] [Qed] Goal typed_main_call_scanf_va_1_pre : Valid
[wp] [Alt-Ergo] Goal typed_main_assert_rte_signed_overflow : Valid
[wp] [Alt-Ergo] Goal typed_main_call_scanf_va_1_pre_2 : Timeout (Qed:4ms) (10s)
[wp] [Alt-Ergo] Goal typed_main_call_printf_va_1_pre : Timeout (Qed:2ms) (10s)
[wp] [Alt-Ergo] Goal typed_main_call_printf_va_2_pre : Timeout (Qed:18ms) (10s) (Stronger)
[wp] [Alt-Ergo] Goal typed_selection_sort_assert_rte_signed_overflow : Valid
[wp] [Alt-Ergo] Goal typed_selection_sort_assert_rte_mem_access : Unknown (Qed:5ms) (204ms)
[wp] [Alt-Ergo] Goal typed_main_call_scanf_va_2_pre : Timeout (Qed:9ms) (10s) (Stronger)
[wp] [Alt-Ergo] Goal typed_selection_sort_assert_rte_signed_overflow_2 : Valid
[wp] [Alt-Ergo] Goal typed_selection_sort_assert_rte_mem_access_2 : Unknown (Qed:5ms) (153ms)
[wp] [Alt-Ergo] Goal typed_selection_sort_assert_rte_mem_access_4 : Unknown (Qed:5ms) (205ms)
[wp] [Alt-Ergo] Goal typed_selection_sort_assert_rte_mem_access_3 : Unknown (Qed:5ms) (204ms)
[wp] [Alt-Ergo] Goal typed_selection_sort_assert_rte_mem_access_6 : Valid
[wp] [Alt-Ergo] Goal typed_selection_sort_assert_rte_mem_access_5 : Unknown (Qed:5ms) (255ms)
[wp] [Alt-Ergo] Goal typed_selection_sort_assert_rte_signed_overflow_3 : Unknown (Qed:7ms) (182ms)
[wp] [Alt-Ergo] Goal typed_show_sort_output_assert_rte_mem_access : Unknown (Qed:7ms) (154ms)
[wp] [Alt-Ergo] Goal typed_show_sort_output_assert_rte_signed_overflow : Valid
[wp] [Alt-Ergo] Goal typed_main_call_printf_va_3_pre : Timeout (Qed:8ms) (10s) (Stronger)
[wp] [Alt-Ergo] Goal typed_main_call_scanf_va_2_pre_2 : Timeout (Qed:8ms) (10s) (Stronger)
[wp] [Alt-Ergo] Goal typed_show_sort_output_call_printf_va_4_pre : Timeout (Qed:6ms) (10s)
[wp] Proved goals:    6 / 20
     Qed:             1  (0.47ms-5ms-10ms)
     Alt-Ergo:        5  (8ms-19ms) (47) (interrupted: 7) (unknown: 7)</description>
                <category>محمد صادق شیخ زاهدی</category>
                <author>محمد صادق شیخ زاهدی</author>
                <pubDate>Sat, 15 Feb 2020 08:45:26 +0330</pubDate>
            </item>
            </channel>
</rss>