رفتن به مطلب
جامعه‌ی برنامه‌نویسان مُدرن ایران

پرچمداران

  1. کامبیز اسدزاده

    کامبیز اسدزاده

    بنیـــان گذار


    • امتیاز

      5

    • تعداد ارسال ها

      250


  2. سید معین حسینی

    سید معین حسینی

    میانجی گر‌ها


    • امتیاز

      1

    • تعداد ارسال ها

      18


  3. فرهاد شیری

    فرهاد شیری

    مدیران مرجع


    • امتیاز

      1

    • تعداد ارسال ها

      58


  4. mohamad

    mohamad

    کاربـــر عـــــادی


    • امتیاز

      1

    • تعداد ارسال ها

      6



مطالب محبوب

در حال نمایش مطالب دارای بیشترین امتیاز از زمان چهارشنبه, 19 دی 1397 در همه بخش ها

  1. 1 امتیاز
    استارتاپ چیست و چگونه راه اندازی می‌شود استارتاپ یا استارت‌آپ یک سرمایه‌گذاری به شکل کارآفرینی است که طی آن یک شرکت نوپا ایده‌ی جدیدی برای کسب‌و‌کار ارائه می‌دهد. طبق تعریف استیو بلنک، پروفسور دانشگاه استنفورد، استارتاپ یک سازمان است که برای پیدا کردن یک مدل کسب‌و‌کار تکرارپذیر و مقیاس‌پذیرراه‌اندازی می‌شود. البته اختلاف ‌بر سر تعریف استارتاپ زیاد است؛ اما نکته‌ی مشترک در همه‌ی آن‌ها این است که بر اساس یک ایده‌ی خلاقانه و جدید فعالیت آن‌ها آغاز می‌شود. این ایده‌ها بازار نیازمندی‌ها را هدف قرار می‌دهند و با ارائه‌ی یک محصول یا خدمات جدید و استفاده از تکنولوژی، خیلی سریع رشد پیدا می‌کنند. از آنجایی که هدف از راه‌اندازی یک استارتاپ پیدا کردن مدل کسب‌و‌کار است؛ عمر آن نمی‌تواند طولانی باشد و معمولا بعد از گذشت چند سال به موفقیت می‌رسد یا بودجه‌ی آن تمام می‌شود و شکست می‌خورد. استارتاپ‌ها برای شروع فعالیت خود لزوما نیازی به ثبت شدن شرکت ندارند و از هرجا و با هر تعداد بنیان‌گذار می‌توانند فعالیت خودشان را آغاز کنند. بودجه‌ی راه‌اندازی استارتاپ‌های معمولا کم است؛ اما اگر ایده‌ی خوبی داشته باشند خیلی زود می‌توانند مورد حمایت سرمایه‌گذاران قرار بگیرند. اصطلاحات رایج در استارتاپ افرادی که با استارتاپ‌ها درگیر هستند معمولا از اصطلاحات خاصی برای بیان مقاصد خود استفاده می‌کنند. در ادامه به معرفی چند نمونه از این اصطلاحات می‌پردازیم. Lean Startup متودولوژی لین استارتاپ (Lean Startup) یا نوپای ناب به شما یاد می‌دهد که چگونه یک استارتاپ را هدایت کنید، چه موقع آن را تغییر دهید و از چه راه‌هایی برای رشد آن استفاده کنید. لین استارتاپ یک رویکرد علمی برای ساختن و مدیریت کردن استارتاپ‌ به شما می‌دهد و کمک می‌کند که محصول خودتان را سریع‌تر به دست مشتری برسانید. بسیاری از استارتاپ‌ها با ایده‌ی ساختن محصول مورد نیاز مردم راه‌اندازی می‌شوند. آن‌ها ماه‌ها و حتی سال‌ها زمان صرف می‌کنند که محصول خود را به بهترین نحو شکل دهند بدون اینکه آن را به مشتری نشان بدهند. همین موضوع باعث شکست خوردن بسیاری از آن‌ها می‌شود. زیرا آن‌ها با مشتری‌ها صحبت نمی‌کنند و در مورد محصولات خود از آن‌ها بازخورد نمی‌گیرند. زمانی که مشتری‌ها نتوانند با یک استارتاپ ارتباط برقرار کنند، به ایده‌ی آن اهمیتی نمی‌دهند و درنتیجه استارتاپ شکست می‌خورد. Unicorn Startup استارتاپ تک شاخ یا یونیکورن استارتاپ (Unicorn Startup) به استارتاپ‌هایی گفته می‌شود که رشد سریعی دارند و به ارزش بیش از ۱ میلیارد دلار می‌رسند. این لغت اولین بار در سال ۲۰۱۳ توسط سرمایه‌گذاری به نام آیلین لی ارائه شد و او از میان حیوانات افسانه‌ای، تک شاخ را به‌عنوان نماد این مدل استارتاپ‌ انتخاب کرد. ازجمله بزرگ‌ترین استارتاپ‌هایی که در این دسته جا می‌گیرند می‌توان به Uber ،Xiaomi ،Airbnb ،Dropbox و Pinterest اشاره کرد. بنیان‌گذار استارتاپ (Founder) به شخصی که استارتاپ را راه‌اندازی می‌کند بنیان‌گذار گفته می‌شود. این اشخاص معمولا علاقه‌ای به کار کردن برای دیگران ندارند و باور دارند که می‌توانند با تلاش‌های بی‌وقفه‌ی خود دنیا را تغییر دهند. این افراد می‌توانند با تعدادی از دوستان خود در این راه شریک شوند و وظایف سنگین را بین خودشان تقسیم کنند. راه‌اندازی یک استارتاپ به هیچ عنوان کار راحتی نیست و در طی آن، به بنیان‌گذاران آن فشار زیادی وارد خواهد شد. اما اگر فعالیته‌های آن‌ها موفقیت‌آمیز باشد، نتیجه‌ی آن هم از نظر احساسی و هم از نظر مالی بسیار خوب خواهد بود. شتاب‌دهنده‌ی استارتاپ (Startup Accelerators) شتاب‌دهنده‌ها شرکت‌هایی هستند که روی استارتاپ‌هایی با ایده‌های جالب و البته کاربردی سرمایه‌گذاری می‌کنند. این شرکت‌ها درصدی از مالکیت استارتاپ را می‌گیرند؛ اما در عوض خدماتی مانند آموزش توسط مربی‌ها و آشنا کردن آن‌ها با سرمایه‌گذاران و متخصصان آن رشته را برایشان فراهم می‌کنند. درواقع این شرکت‌ها شانس موفقیت استارتاپ‌ها و پیدا کردن سرمایه‌ی بالقوه برای فعالیت‌هایشان را بالا می‌برند. استارتاپ ویکند (Startup Weekend) استارتاپ ویکند یک رویداد آموزشی-تجربی ۵۴ ساعته است که معمولا در آخر هفته برگزار می‌شود. در این رویداد افراد مختلفی مانند علاقه‌مندان به استارتاپ، توسعه‌دهندگان، برنامه‌نویسان، مدیران کسب‌و‌کارها، بازاریاب‌ها و طراحان گرافیک حضور دارند. ایده‌ها در این رویداد مطرح می‌شوند و افراد گروه تشکیل می‌دهند تا طرح اولیه یا دموی ایده‌ی خود را پیاده‌سازی کنند. استارتاپ گرایند (Startup Grind) استارتاپ گرایند یک برنامه‌ی جهانی است که در آن از کارآفرینان موفق دعوت می‌شود تا داستان موفقیت‌ و چالش‌های استارتاپ خود را با دیگران به اشتراک بگذارند. افراد می‌توانند در این برنامه با پروژه‌های یکدیگر آشنا شوند و از تجربیات هم استفاده کنند. تجارت B2B این اصطلاح کوتاه شده‌ی عبارت Business to Business است و به کسب‌و‌کاری گفته می‌شود که محصولات و خدمات خود را به یک کسب‌و‌کار دیگر ارائه می‌دهد. این نوع تجارت در مقابل تجارت بی تو سی (B2C) قرار دارد. تجارت B2C تجارت B2C مخفف عبارت Business to customers است و به کسب‌و‌کارهایی گفته می‌شود که محصولات و خدمات خود را به مشتری‌های عرضه می‌کنند. تجارت C2C نوعی از سرویس است که کاربران با استفاده از آن، خدمات و کالاهای خود را به دیگر کاربران عرضه می‌کنند. وب‌سایت‌ها و سرویس‌های خرید و فروش اجناس دست دوم، از نمونه‌های تجارت Customer to Customer هستند. سرمایه‌ی بذری (Seed Funding) همان‌طور که یک گیاه از یک بذر شروع به رشد می‌کند، یک استارتاپ نیز از یک سرمایه‌ی اولیه شروع می‌شود. به سرمایه‌ای که در مرحله‌ی اولیه راه‌اندازی استارتاپ در اختیارش قرار می‌گیرد، سرمایه‌ی بذری گفته می‌شود. واگذاری (Vesting) به نوعی تخصیص سهامی گفته می‌شود که طی آن بعد از گذشت مدت زمانی، مقدار سهم تعیین‌شده به کارمندان داده می‌شود. به‌عنوان مثال اگر به یک کارمند ۲۰۰ سهام طی ۱۰ سال داده شود، یعنی بعد از گذشت هر سال ۲۰ سهم به او اختصاص پیدا می‌کند. این کار به کارمندان انگیزه می‌دهد که عملکرد خوبی داشته باشند و برای مدت زمان زیادی در شرکت کار کنند. بنچمارک (Benchmark) به فرآیندی گفته می‌شود که یک استارتاپ برای اندازه‌گیری موفقیت فعلی خود از آن استفاده می‌کند. سرمایه‌گذاران میزان موفقت استارتاپ‌ها را بر اساس بنچمارک‌ها می‌سنجند. به‌عنوان مثال وقتی می‌گوییم شرکت A به بنچمارک درآمد X در طی ۲ سال رسیده است یعنی این استارتاپ توانسته است طی ۲ سال میزان فروش خود را به X برساند. بوت‌استرپ (Bootstrapped) زمانی که گفته می‌شود یک شرکت بوت‌استرپ است، یعنی بودجه‌ی آن توسط خود کارآفرین یا بودجه‌ی خود شرکت تأمین شده است. وام موقت (Bridge loan) این نوع وام به Swing loan نیز معروف است و به مساعده‌هایی گفته می‌شود که بر اساس میزان درآمد به یک شخص داده می‌شود و فاصله‌ی بین درآمدهای عمده‌ را پر می‌کند. فروش (Buyout) یک استراتژی معمول برای خروج است که طی آن سهام شرکت به فروش می‌رسد و به خریداران آن اجازه‌ی کنترل شرکت داده می‌شود. سرمایه (Capital) به دارایی‌های مالی گفته می‌شود که در حال حاضر برای استفاده در دسترس هستند. کارآفرینان از سرمایه برای آغاز استارتاپ استفاده می‌کنند و مقدار آن را افزایش می‌دهند تا به رشد استارتاپ کمک کنند. دو دلیجنس (Due diligence) به ارزیابی و تحلیل سرمایه‌گذاران از وضعیت و پتانسیل‌های سرمایه‌گذاری گفته می‌شود. این ارزیابی می‌تواند شامل بررسی سوابق مالی و اندازه‌گیری ROI باشد. بازده سرمایه‌گذاری یا بازگشت سرمایه (ROI) همان‌طور که از نامش پیدا است، برگشت سرمایه را مورد بررسی قرار می‌دهد. درواقع به پولی گفته می‌شود که به یک سرمایه‌گذار به‌عنوان درصدی از سرمایه‌‌گذاری خود در استارتاپ برگشت داده می‌شود. به‌عنوان مثال اگر یک سرمایه‌گذار مبلغ ۲ میلیون دلار برای خرید ۲۰ درصد سهام یک شرکت خرج کند و شرکت با مبلغ ۴۰ میلیون دلار به فروش برسد، این یعنی آن سرمایه‌گذار مبلغ ۸ میلیون دلار از فروش شرکت دریافت خواهد کرد. خروج (Exit) برخی بنیان‌گذاران و سرمایه‌گذاران استارتاپ این‌گونه پولدار می‌شوند؛ Exit به متدی گفته می‌شود که یک سرمایه‌گذار و یک کارآفرین سرمایه‌ی خودشان را از شرکت خارج می‌کنند. خروج معمولا در زمان IPO و M&A اتفاق می‌افتد. آی‌پی‌او (IPO) زمانی است که یک استارتاپ سهام خودش را در یک فراخوان بورس برای فروش به مردم پیشنهاد می‌دهد. در این حالت یک شرکت خصوصی تبدیل به سهامی عام می‌شود و دیگر یک استارتاپ نیست. مالکیت و ادغام (Merge & Acquisition) زمانی است که استارتاپ توسط یک شرکت بزرگ‌تر خریداری یا با آن ادغام می‌شود. این اتفاق به صورت دوستانه (همراه با توافقنامه) یا خصمانه (بدون توافقنامه) صورت می‌گیرد. توافقنامه عدم ‌افشاگری (NDA) NDA مخفف عبارت Non-disclosure agreement است و به توافقنامه‌ای گفته می‌شود که طی آن هر ۲ طرف از اطلاعات حساس و محرمانه مانند اسرار تجارت محافظت می‌کنند و آن را با شخص سوم به اشتراک نمی‌گذارند. پیوت (Pivot) زمانی است که استارتاپ جهت استراتژی‌های خودش را سریعا تغییر می‌دهد. معمولا این تغییرات به دلیل عدم بازدهی اتفاق می‌افتند و طی آن بر ویژگی‌های دیگر محصولات یا مشتری‌ها تمرکز می‌شود. مذاکره در آسانسور (Elevator Pitch) فرض کنید در یک آسانسور با یک سرمایه‌گذار هم مسیر شده‌اید و تنها ۳۰ تا ۱۲۰ ثانیه فرصت دارید او را متقاعد کنید که روی ایده‌ی شما سرمایه‌گذاری کند. به ‌عبارتی شما باید در این چند ثانیه مشکل، راه‌حل آن و بازار مشتری‌ها را برای سرمایه‌گذار توضیح بدهید و او را متقاعد کنید. نرم‌افزار به‌عنوان سرویس (SaaS) به یک محصول نرم‌افزاری گفته می‌شود که از راه دور به وسیله‌ی اینترنت یا سیستم رایانش ابری کنترل می‌شود. چگونه یک استارتاپ راه‌اندازی کنیم شما برای ساختن یک استارتاپ موفق به ۳ چیز احتیاج دارید: ایده‌ی ساختن محصولی که مشتری‌ها واقعا به آن علاقه داشته باشند، پیدا کردن یک هم‌بنیان‌گذار و کم کردن هزینه‌ها تا جای ممکن. اکثر استارتاپ‌هایی که شکست می‌خورند، معمولا در عمل کردن به یکی از این ۳ مورد ناموفق هستند. درواقع شما به یک ایده‌ی خاص و عالی برای شروع کردن استارتاپ خود نیازی ندارید. کافی است تکنولوژی جدیدی به کاربران معرفی کنید که در حال حاضر از آن برخوردار نیستند. این تکنولوژی جدید باید بتواند نیازهای آن‌ها را به بهترین نحو از بین ببرد. در ادامه بیشتر در مورد مراحل راه‌اندازی استارتاپ بخوانید. ۱- ببینید دنیا چه چیزی کم دارد اگر دقت کنید متوجه می‌شوید که سیستم‌های تاکسیرانی قبل از پیدایش Uber بسیار کسالت‌آور بودند. یا اینکه قبل از پیدایش اسپیس‌ایکس مردم علاقه‌ی چندانی به فضا نداشتند. شما نیز باید فکر کنید و ببینید چه چیزی در دنیا کم است و سعی کنید ایده‌ی جدیدی برای آن ارائه دهید. ۲- آن را یادداشت کنید مهم نیست که چقدر باهوش هستید. مطمئنا بعد از گذشت مدتی برخی جزئیات ایده‌ی خود را فراموش خواهید کرد. افکار شما و مکالماتی که در این زمینه با دیگران انجام می‌دهید بسیار ارزشمند هستند پس تمام افکار و جزئیات مکالمات خود را یادداشت کنید. ۳- یک نمونه‌ی اولیه بسازید بسیاری از ایده‌های خلاقانه‌ی ما حتی بهترین‌ها، متأسفانه هیچ موقع به دنیای واقعی وارد نمی‌شوند و شما حتی اگر آن‌ها را یادداشت کنید، بازهم بعد از گذشت مدتی فراموششان خواهید کرد. تنها چیزی که می‌تواند مانع از فراموش شدن آن‌ها شود، تهیه‌ی یک نمونه‌ی اولیه است. آن‌ها را برنامه‌نویسی کنید یا به‌صورت فیزیکی طراحی کنید و بسازید. بسیاری از مردم در همین مرحله متوقف می‌شوند بنابراین اگر بتوانید از آن گذر کنید، یک قدم از دیگران جلوتر خواهید بود. ۴- نمونه‌ی اولیه را به ۱۰۰ نفر نشان دهید حالا شما باید از نقطه‌ی آسایش خود خارج شوید و نمونه‌ی اولیه خود را به دیگران نشان بدهید و نظر آن‌ها را جویا شوید. بهتر است این ۱۰۰ نفر از میان افراد کاملا ناشناس انتخاب شوند تا شناختن شما در بازخوردشان نسبت به محصول تأثیری نگذارد. چرا ۱۰۰ نفر؟ زیرا شما در این مرحله به چشم‌اندازی وسیع برای بازخوردها احتیاج خواهید داشت. ۵- تکرار کنید مردم کمی هستند که در اولین تلاش خود موفق می‌شوند و شانس اینکه شما جزو این دسته باشید بسیار کم است. بنابراین خودتان را برای طراحی کردن مجدد همه چیز کنید. ۶- یک هم‌بنیان‌گذار (Co-Founder) پیدا کنید زمانی که احساس کردید نمونه‌ی اولیه‌تان به نتیجه رسیده است، به دنبال یک شریک بگردید تا حاضر باشد سال‌های عمر خود را صرف عملی کردن این ایده کند. ۷- کسب‌و‌کار خود را ثبت کنید بعد از صحبت کردن با شریک یا شرکای خود و تعیین توافقات، بهتر است شرکت خودتان را ثبت کنید. می‌توانید مراحل ثبت شرکت را به‌طور کامل در این مقاله مطالعه کنید. ۸- به دنبال سرمایه‌گذار باشید و اولین نسخه را تولید کنید اگر بودجه‌ی کافی برای تولید کردن اولین نسخه از محصول خود ندارید، بهتر است یک سرمایه‌گذار پیدا کنید. بهتر است در حین پیدا کردن سرمایه‌گذار کار تولید را متوقف نکنید؛ زیرا هر استارتاپی نمی‌تواند بودجه‌ی مورد نظر خود را از سرمایه‌گذاران دریافت کند. ۹- راه‌اندازی کنید هرچقدر نسخه‌ی اولیه‌تان ناقص بود، آن را راه‌اندازی کنید. ویژگی‌های اضافه، واسط کاربری بهتر، افزایش سرعت اجرا و دیگر موارد مربوط به بهینه‌سازی از جمله مواردی هستند که می‌توانند در آینده نیز به محصول اصلی اضافه شوند. ۱۰- با کاربران همراه باشید مشتری‌های خود را تحت نظر داشته باشید و ببینید آیا برمی‌گردند یا خیر. اگر برنگشتند، علت را پیدا کنید. ۱۱- دوباره راه‌اندازی کنید هر چقدر احتیاج بود، محصول خود را بعد از اعمال تغییرات دوباره راه‌اندازی کنید. حتی اگر مشاهده کردید که تعداد کمی از مردم دوباره به شما مراجعه کردند، باز هم به کارتان ادامه دهید؛ زیرا این یعنی در حال تولید یک محصول باارزش هستید. ۱۲- محصول را به ۱۰۰۰ نفر نشان دهید شاید رقم بالایی به نظر نرسد؛ اما اولین ۱۰۰۰ نفر نقاط ضعف محصول شما را شناسایی خواهند کرد. از آنجایی که شما هنوز ناشناخته هستید، شاید لازم باشد این افراد را به‌صورت دستی استخدام کنید. هیچ ایرادی ندارد حتی اگر شده لپ‌تاپ آن‌ها را قرض بگیرید و وب‌سایت‌ خود را به آن‌ها نشان بدهید و نظرشان را جویا شوید. ۱۳- رشد کنید پاول گراهام، دانشمند علوم کامپیوتر و سرمایه‌گذار، استارتاپ‌ها را تشویق می‌کند که در هفته ۵ درصد رشد داشته باشند. اگر ۴ سال به همین ترتیب ادامه دهید، در طی گذشت این مدت به تعداد ۲۵ میلیون کاربر خواهید رسید. به‌ عبارت‌ دیگر، تبدیل به یکی از بزرگ‌ترین استارتاپ‌ها خواهید شد. ۱۴- به موفقیت برسید شما می‌توانید شرکت خودتان را به شخص دیگری بفروشید یا سرمایه‌گذاران را قانع کنید که با شما همکاری کنند. شما تا اینجا موفق شده‌اید استارتاپ خود را به نتیجه برسانید؛ بعد از این به خودتان بستگی دارد که بخواهید آن را ادامه دهید یا آن را به صاحبان جدیدش واگذار کنید.
  2. 1 امتیاز
    سلام، در qml جدولی دارم که با ارث بری از listView ایجاد شده و علاوه بر اطلاعات اعداد حاوی اطلاعات تصویر هم هست. برای گزارشگیری از این جدول به صورت pdf باید تصاویر و نوشته‌هایی به عنوان سربرگ اضافه کنم. برای الصاق تصاویر و گزارشگیری از این جدول به صورت pdf چه راهی در qml پیشنهاد می‌کنید؟
  3. 1 امتیاز
    با سلام بهترین راه استفاده از یک کتابخانه مناسب است! در زیر من سه کتابخانه را معرفی میکنم. اگر موفق به ساخت فایل pdf نشدید در اسرع وقت یک مثال با یکی از این کتابخانه‌ها که کار کرده‌ام می‌زنم. کتابخانه های کار با اسناد PDF: HARU PoDoFo jagPDF
  4. 1 امتیاز
    نحوه ساخت یک کتابخانه (Shared Object (.so در سیستم عامل لینوکس توسط کامپایلر GCC مرحله 1: ابتدا باید در برنامه ای که قصد دارید آن را به کتابخانه عمومی تبدیل کنید باید یک رابط مناسب Factory Method برای لینک در زمان اجرا بسازید. نکته! توجه داشته باشید که می توانید با استفاده از پلی مورفیسم یک اشاره گر از یک رابط که به صورت مجرد تعریف شده است را در Factory Method کتابخانه خود انتقال دهید. تابع سازنده رابط کتابخانه را به شکل زیر در Main برنامه کتابخانه تعریف کنید...! #include "encryptorPlugin.h" extern "C" { extern PluginEnctyptorPtr create_plugin() { return PluginEnctyptorPtr(new encryptor_plugin); } extern bool destroy_plugin(PluginEnctyptorPtr instance) { if(instance !=NULL){ instance =NULL; delete instance; return true; } return false; } } int main(int argc, char *argv[]) { return 0; } مرحله 2: در این مرحله باید یک کلاس مجرد بسازید و متدهایی که باید زمان فراخوانی اشاره گر کلاس به آنها دسترسی داشته باشید را تعریف نمایید. مانند کلاس زیر که من تعریف کرده ام... #ifndef __PLUGIN_H__ #define __PLUGIN_H__ #include <sstream> #include <string.h> typedef char* Bytes; typedef unsigned int size_t; typedef const char* cBytes; #define DELOBJ(obj) {if(obj!=NULL){delete obj;obj=NULL;}} enum encryptAloglType { BASE64, HASH , MD4 ,MD5 ,OPENSSL }; enum ioType { CPP_STREAM , C_LOWLEVEL }; class Encryptor_Interface { public: virtual ~Encryptor_Interface() {} virtual void getEncBuffer(Bytes & buffer, cBytes fileName) const = 0; virtual void getDecBuffer(std::istringstream** sstream, cBytes fileName) const = 0; virtual void setIoType(ioType =C_LOWLEVEL) = 0; virtual void setAlgolType(encryptAloglType) = 0; virtual void dispose(int) =0; virtual size_t getReadedSize() =0; }; typedef Plugin_Interface* PluginEnctyptorPtr; #endif // __PLUGIN_H__ class ISCLVoterManager { public: virtual ~ISCLVoterManager(){}; virtual bool Init(int nSysID,int nNodeID,const char* strFileName) = 0; connections }; مرحله 3: در این مرحله بعد از پیاده سازی الگوریتم های متدهای کلاس مجرد ساخته شده باید سورس کتابخانه خود را در لینوکس کامپایل کنید. اگر توزیع لینوکس شما از bash استفاده میکند می توانید به روش زیر کامپایل را انجام دهید... gcc -ggdb3 -shared -fPIC libdep.c -o libEncryptor.so در این مرحله در صورتی که خطایی وجود نداشته باشد باید کتابخانه شما کامپایل شده باشد البته به صورت Shared Library. مرحله 4: اکنون در این مرحله کافی است که از رابط زیر که من به صورت template نوشته ام به صورتی که به اشاره خواهم کرد استفاده نمایید. در این کلاس کافی است که شما رابط مجرد کتابخانه را به صورت اشاره گر ویا در صورتی که متدهای شما در کتابخانه به آرگومانهایی نیاز دارند به همراه آرگومانهای کلاس را به سازنده این کلاس ارسال نمایید. در این کلاس با استفاده از تکنیک استراتژی شما می توانید انوع رابط های کتابخانه ها را به راحتی استفاده نمایید فقط کافی است که یک کلاس Wrapper بنویسید که کلاس مجرد Solver را به ارث برده باشد و در متد solve این کلاس نحوه پیاده سازی کتابخانه خود را بنویسید. زمانی که شما در پروژه های خیلی بزرگ کار میکنید که از چند ده کتابخانه مختلف استفاده میکنند به راحتی می توانید از این کلاس ژنریک استفاده نمایید تا هم اتصالات سخت را از بین برده باشید و هم کلاس های سبک رابطی را تهیه کرده اید که اصل Single Responsibility را هم به خوبی راعایت کرده باشید وهم کسانی که از رابط شما استفاده میکنند درگیر جزییات پیاده سازی نخواهند شد. /* * Library_Loader.h * * Created on: Jan 1, 2019 * Author: f.shiri */ #ifndef PLUGINLOADER_H_ #define PLUGINLOADER_H_ #include "Encryptor_interface.h" #include <stdexcept> #include <memory> #include <dlfcn.h> #define LibEncryptorName "./libEncryptor.so" #define LibFactoryMethod "create_plugin" #define LibDestyoryMethod "destroy_plugin" #define LogicFileName "logic.ini" #define __CleanupLibClose __attribute__((cleanup(closedl))) #ifdef SCL_EQUIPPED #include "SCLVoter_Interface.h" #include "initsclvoter.h" extern ISCLVoterManager* pSCLVoterManager; #endif typedef Encryptor_Interface* encAbstractPtr; //typedef ISCLVoterManager* pISCLVoter; /* load shared library or static library and dynamic * declare library virtual function. * template arg1 : interface class library pointer. * */ template<class InterfacePtr> class PluginLoader { private: /*clean up macro function calling by compiler, delete the pointer when the pointer's life cycle is end */ static inline int closedl(void* handle) { int tmp = -1; if (handle) tmp = dlclose(handle); handle = NULL; return tmp; } struct { /* union data type contained * dynamic link library objects. * */ union { void* dlsym; InterfacePtr (*factoryMethod)(); } factoryObject; union { void* dlsym; bool (*destoryMethod)(InterfacePtr); } destroyObject; /* shared library handler */ } libraryObject; void* m_handle; public: explicit PluginLoader() { } ; ~PluginLoader() { } ; // Dynamic load, encryption function from shared library. /* * arg1 : shared library name. * arg2 : reference factory method name in shared library. * arg3 : reference declarative interface class pointer. * arg4 : own request for the symbol in library or main executable. // arg5 : reference destroy method name in shared library. * return type : reference interface pointer. */ template<class CInterfacePtr> inline void operator()(cBytes libName, cBytes factoryFuncName, CInterfacePtr** pClassInterface,cBytes destroyFuncName =NULL) { dlerror(); /* * The RTLD_DEEPBIND attribute specifies that when resolving a symbol in a shared library, * the symbols in the shared library are put ahead of the global symbol scope. * example-> When you load the ???.so, it has it's own request for the symbol. * Because you use RTLD_DEEPBIND this definition is looked up in the dependencies of this library first, * before looking in the main executable. */ __CleanupLibClose void* m_handle = dlopen(libName, RTLD_DEEPBIND | RTLD_NOW | RTLD_LOCAL); if (!m_handle) { throw std::runtime_error(dlerror()); } if(factoryFuncName!=NULL){ if (!(libraryObject.factoryObject.dlsym = dlsym(m_handle, factoryFuncName))) { throw std::runtime_error(dlerror()); } } if(destroyFuncName!=NULL){ if (!(libraryObject.destroyObject.dlsym = dlsym(m_handle, destroyFuncName))) { throw std::runtime_error(dlerror()); } } *pClassInterface =(*libraryObject.factoryObject.factoryMethod)(); } template<class CInterfacePtr> bool destroy(CInterfacePtr** pClassInterface) { return libraryObject.destroyObject.destoryMethod(*pClassInterface); } private: PluginLoader(const PluginLoader&); PluginLoader& operator=(const PluginLoader&); }; /* this class is invoke strategy shared library wrapper * template arg1: reference interface class */ template<class InterfacePtr> class Solver { public: Solver(){}; Solver(cBytes cLibName, cBytes cFactoryFuncName ,cBytes cDestroyFuncName=NULL) :m_interfacePtr(NULL){ m_pluginLoader(cLibName, cFactoryFuncName, &m_interfacePtr ,cDestroyFuncName); } virtual ~Solver(){ m_pluginLoader.destroy(&m_interfacePtr); DELOBJ(m_interfacePtr); } // important: this pure virtual method must be implemented in derived class. virtual void solve() =0; protected: template<class CInterfacePtr> inline void getInterface(CInterfacePtr& inputInterFace){ if(m_interfacePtr!=NULL){ inputInterFace = m_interfacePtr; } } private: //shared library interface class member. InterfacePtr m_interfacePtr; //instance of plugin loader class. PluginLoader<InterfacePtr> m_pluginLoader; }; /*proxy class shared library. this class is immutable type * class type: pointer type of shared library interface class. * template arg1 : encrypt interface class pointer * template arg2 : string stream reference pointer * */ template<class InterfacePtr ,typename InputType> class EncryptLibraryLoader : public Solver<InterfacePtr>{ protected: public: // arg1 : shared library name. // arg2 : reference factory method name in shared library. // arg3 : reference destroy method name in shared library. // arg4 : output string stream EncryptLibraryLoader(InputType outStream ,cBytes cLibName, cBytes cFactoryFuncName ,cBytes cDestroyFuncName=NULL) : Solver<InterfacePtr>(cLibName,cFactoryFuncName,cDestroyFuncName) , m_outStream(outStream) { /* important: must be call getInterface in super class and get * interface class reference and copy in member pointer in this class. */ getInterface(m_interfacePtr); } virtual ~EncryptLibraryLoader() { //clean up member pointer DELOBJ(m_interfacePtr); DELOBJ(m_outStream); } /* get the byte stream from encrypt logic.ini file. * arg1 : reference bytes stream. * return type : reference stream pointer * * important: must be call getInterface in super class and get * interface class reference and copy in member pointer in this class. * */ inline void solve(){ if(m_outStream!=NULL){ try { if (m_interfacePtr!=NULL) { m_interfacePtr->setIoType(C_LOWLEVEL); m_interfacePtr->getDecBuffer(m_outStream,const_cast<char*> (LogicFileName)); } //important : if interfacePtr is loaded. // this method dispossess member static pointer in memory section of library. m_interfacePtr->dispose(0); } catch (std::runtime_error& e) { printf("%s \n", e.what()); } } } private: //EncryptLibraryLoader(); EncryptLibraryLoader(const EncryptLibraryLoader&); EncryptLibraryLoader& operator=(const EncryptLibraryLoader&); //shared library interface class member. InterfacePtr m_interfacePtr; InputType m_outStream; }; /*proxy class SclVoter library. this class is immutable type * class type: pointer type of shared library interface class. * template arg1 : SclVoter interface class pointer * template arg2 : Number of nodes with type int * */ template<class InterfacePtr,typename InputType> class SclVoterLibraryLoader : public Solver<InterfacePtr>{ protected: public: // arg1 : shared library name. // arg2 : reference factory method name in shared library. // arg3 : reference destroy method name in shared library. // arg4 : numbers of node explicit SclVoterLibraryLoader(InputType nNode ,cBytes cLibName, cBytes cFactoryFuncName, cBytes cDestroyFuncName=NULL) : Solver<InterfacePtr>(cLibName,cFactoryFuncName,cDestroyFuncName), m_x_nNode(nNode){ } virtual ~SclVoterLibraryLoader() { //clean up member pointer DELOBJ(m_interfacePtr); } /* initializing SCLVoter */ inline void solve(){ /* important: must be call getInterface in super class and get * interface class reference and copy in member pointer in this class. */ getInterface(m_interfacePtr); if(m_interfacePtr!=NULL){ char strConfigPath[100]; copy(strConfigPath,m_x_nNode); if(!m_interfacePtr->Init(strConfigPath)) { printf("Error initializing SCLVoter (file %s) !\n",strConfigPath); } } } private: SclVoterLibraryLoader(); SclVoterLibraryLoader(const SclVoterLibraryLoader&); SclVoterLibraryLoader& operator=(const SclVoterLibraryLoader&); //shared library interface class member. InterfacePtr m_interfacePtr; InputType m_x_nNode; }; #endif /* PLUGINLOADER_H_ */ و در این مرحله به استفاده از آبجکت های زیر از کتابخانه های خود استفاده نمایید. std::istringstream* file=NULL ; { Solver<encAbstractPtr> *loader = new EncryptLibraryLoader<encAbstractPtr,std::istringstream**> ( &file ,LibEncryptorName, LibFactoryMethod , LibDestyoryMethod); // initial encryption library. loader->solve(); loader=NULL; } Solver<ICLAbstractPtr> *loader = new SclVoterLibraryLoader<ICLAbstractPtr,int> ( m_nNodeId ,SCLVOTER_SO_PATH, SCLVOTER_GET_INSTANCE_FUNCTION_NAME ); if(pSCLVoterManager == NULL) { return false; } // initial SCLvoter. loader->solve(); loader=NULL; در صورتی که نیاز به استفاده از کتابخانه در ویژوال سی ++ بود در همین تاپیک اعلام کنید تا انجام بدم.
  5. 1 امتیاز
    نام فایل‌های تست واحد فایل‌های تست را هم‌نام با کامپوننتی که تست می‌کند نام‌گذاری کنید. فایل‌های تست را با پسوند .spec. نام‌گذاری کنید. چرا؟ راهی ثابت را برای شناسایی تست‌ها فراهم می‌کند. چرا؟ الگوی هم‌گام با karma یا راه‌انداز‌های تست دیگر فراهم می‌کند. نام فایل‌های تست end to end فایل‌های تست e2e را به دنبال نام امکاناتی که تست می‌کند، با پسوند .e2e-spec. نام‌گذاری کنید. چرا؟ راهی ثابت برای شناسایی سریع فایل‌های تست e2e فراهم می‌کند. چرا؟ الگویی را مطابق راه‌اندازهای تست و سیستم‌های build خودکار فراهم می‌کند. نام ماژول (Module) های انگولار به نام نشانه‌ی ماژول پسوند Module را متصل کنید. به نام فایل پسوند .module.ts را بدهید. ماژول‌ها را با توجه به نام امکاناتی که ارائه می‌دهد و پوشه‌ای که در آن قرار دارد نام‌گذاری کنید. چرا؟ راهی ثابت را برای شناسایی و اشاره به ماژول‌ها فراهم می‌کند. چرا؟ نامگذاری شتری بزرگ ( Upper camel case) برای شناسایی اشیائی که می‌توانند توسط سازنده (constructor) نمونه سازی شوند عمومی است. ‌‌چرا؟‌ به راحتی ماژول را به عنوان ریشه‌ی امکاناتی که به همان شکل نامگذاری شده‌اند مشخص می‌کند. ماژول‌های روتینگ (routing) را با پسوند RoutingModule نام‌گذاری کنید. نام یک فایل حاوی ماژول روتینگ را با routing.module.ts تمام کنید. چرا؟ یک ماژول روتینگ (RoutingModule) ماژولی است که به صورت اختصاصی برای تنظیم کردن روتر (router) انگولار استفاده‌ می‌شود. یک قرارداد ثابت برای نام‌گذاری کلاس‌ها و نام فایل‌ها باعث می‌شوند این ماژول‌ها به راحتی پیدا شده و شناسایی شوند.
  6. 1 امتیاز
    اگر شما از آن دسته از کاربرانی هستید که هزینه‌ای برای گیت‌هاب پرداخت نمی‌کنید، این هفته‌ی خوبی است برای شما! با توجه به تاریخ، گیت‌هاب همیشه حساب‌های رایگان ارائه داده است، اما با توجه به قوانین آن مخازنِ شما باید در قالب عمومی ایجاد می‌شدند. در صورتی که شما نیاز به داشتن مخزنی از نوع خصوصی داشتید در این صورت مجبور به پرداخت هزینه‌ای در قبال آن بودید. خبر خوش این است که، این محدودیت از امروز از بین رفته و شما می‌توانید مخازن خود را به صورت خصوصی و بدون پرداخت هزینه‌ای ایجاد کنید.
  7. 1 امتیاز
    با سلام، یا توجه به مقاله‌ی ذکر شده زیر در ارتباط با انتخاب زبان برنامه‌نویسی و تفاوت عمده‌ی زبان‌های کامپایلری و مفسری لازم است تعاریفی در رابطه با جزئیات زبان‌های کامپایلری که خود تفاوت‌هایی را شامل می‌شوند بپردازیم. در صورتی که مقاله‌ی زیر را مطالعه نکرده‌اید پیشنهاد می‌کنیم قبل از خواندن این مقاله آن را مرور کنید. در این مقاله شما تفاوت عمده‌ی آن‌ها را خواهید آموخت که شامل توضیحات کامپایلر و روش‌های کامپایل می‌باشد. کامپایلر چیست؟ کامپایلر به ابزار (برنامه یا مجموعه‌ای از برنامه‌ها) گفته می‌شود، که متنِ نوشته شده‌ی برنامه‌نویسان (در قالب کُد) را که از سطح بالاتر (زبان مبدأ) برخوردار است و درک آن برای انسان مُیسر می‌باشد، دریافت کرده و آن را به زبان سطح پایین‌تر (زبان مقصد) مانند اسمبلی یا کُد ماشین ترجمه می‌کند. زبان‌های کامپایلری در دو دسته‌‌ی بومی (Native) و مجازی (Virtual) کامپایل از نوع بومی روشی است که کد‌های نوشته شده‌ را به صورت مستقیم به کُد ماشین ترجمه می‌کند. کامپایل از نوع مجازی روشی است که کد‌های نوشته شده‌ را ابتدا به کُدمیانی (کد‌مشترک یا همان بایت کُد - Byte Code) در جاوا و زبان میانی (CIL) در Net. تبدیل می‌کند که خودِ آن شبیه به کُد ماشین است. در این فرایند کد مربوطه توسط کامپایلر مخصوص یعنی JIT (کامپایلری از نوع Just-In-Time) در زمان اجرا توسط سیستم‌عامل، به دستورالعمل‌های قابل فهم برای پردازنده‌ تفسیر و اجرا می‌شود (که این فرایند شبیه به فرایند عملکرد اجرایی مفسر‌ها است). زبان‌های بومی (زبان‌هایی که کد‌ آن‌ها به کد ماشین به صورت مستقیم توسط کامپایلر قبل از اجرای آن‌ها توسط سیستم‌عامل، ترجمه می‌شوند که به اصطلاح ahead-of-time (جلوتر از زمان) یا همان AOT نام دارد) مانند: C, C++, Rust, Haskell, Clean, Swift, Go, Fortran, D زبان‌های مجازی (زبان‌هایی که کد آن‌ها توسط یک رابط میانی به زبان مشترک ترجمه می‌شود) : Java و خانواده‌ی دات‌نت مانند C#, Visual Basic.Net و C++/CLR نکته قابل توجه در مورد C++/CLR آن است که این نوع استاندارد در مورد سی‌پلاس‌پلاس بر پایه‌ی چهارچوب دات‌نت است. در این نسخه از زبان شما با محدودیت‌های بسیاری مواجه بوده و به ویژگی‌ها و کیفیت نهایی برنامه‌های تولید شده‌ی واقعی در قالب Native محروم خواهید بود. روش کامپایل و و انواع آن‌ها کامپایلر‌ها به صورت بومی (Native) و کراس (Cross) تقسیم بندی می‌شوند. به طور کلی آن دسته از کامپایلر‌ها که کد‌های باینری را تولید می‌کنند از نوع محلی یا همان Native نام دارند؛ در واقع به هر کامپایلی که بر روی سیستم‌های معماری x86 نوع x86، بر روی سیستم‌های x86-64 نوع x86-64 و بر روی سیستم‌های PowerPC نوع powerpc و بر روی arm نوع arm را تولید کند کامپایل بومی می‌گویند. چرا که تنها برای یک پلتفرمِ هدف کد‌های ماشین رو تولید خواهد کرد (در صورت نیاز برای اجرا بر روی پلتفرم‌های دیگر باید آن را بر روی پلتفرم متناسب با آن پیکربندی کنید) در واقع یک وابستگی به سخت‌افزار وجود خواهد داشت که کد‌های شما بر اساس آن تولید می‌شود. اما در رابطه با کامپایلر‌ها از نوع Cross یا به اصطلاح عبوری وابستگی خاصی به سخت‌افزار ندارند، در این روش کافی است سخت‌افزار، پلتفرم (معماری و سیستم‌عامل) مورد نظر را یک بار برای آن معرفی کرده و اقدام به کامپایل کنید. کامپایل به صورت کراس کد‌ها را به برنامه‌ی قابل اجرا برای بیشتر از یک پلتفرم فراهم می‌کند. برای مثال در صورتی که بر روی پلتفرم ویندوز هستید می‌توانید برنامه‌ی نوشته شده‌ی خود را برای پلتفرم اندروید یا آی‌او‌اس که برای arm هستند ارائه دهید. اولین کامپایلری که این ویژگی را پشتیبانی می‌کند GCC است. این امکان وجود دارد که شما کد‌های نوشته شده‌ی خود را بر روی پلتفرم میزبان برای پلتفرم‌های هدف (مقصد) کامپایل کنید. البته جدیداً کامپالر کلَنگ (Clang) به عنوان یکی از بهترین انتخاب بین برنامه‌نویسان ++C جهت کراس‌کامپایل مطرح می‌شود. کامپایلر‌های پیشنهادی: GCC Clang MinGW MSVC مزایا و معایب زبان‌های کامپایلری از نوع کلاس بومی (Native) از سرعت بسیار بالایی برخوردار هستند (دلیل آن ترجمه‌ی مستقیم کد‌ها به کد ماشین است) در مقابل بزرگترین مزیتی که زبان‌های نوع کلاس مجازی (Byte Code) دارند به خاطر وجود یک برنامه‌ی واسط جهت شبیه‌سازی کد‌های ترجمه شده به کد قابل فهم برای پردازنده، اجرا شدن آن‌ها در هر پلتفرم بدون کامپایل مجدد امکان پذیر است که البته این ویژگی خود نیازمند نصب بودن JVM بر روی پلتفرم مربوطه می‌باشد. در نوع بومی برای اجرا در هر پلتفرم لازم است سورس کد‌ها را برای پلتفرم مقصد کامپایل کنید که نیازی به وجود ماشین مجازی مانند JVM یا برنامه‌ی خاصی ندارد. کد‌های میانی تحت کامپایلِ درجا JIT : Just In Time همانطور اشاره شد زبان‌های برنامه‌نویسی Java و خانواده‌ی Net. به ترتیب توسط Java Byte Code بر روی ماشین مجازی جاوا JVM و CIL : Common Intermediate Language بر روی زیر ساخت CLI : Common Language Infrastructure از هم جدا می‌شوند. در نظر داشته باشید CIL نام تغییر یافته‌ی MSIL می‌باشد. معنای ماشین مجازی CLR و JVM جی‌وی‌ام یا همان JVM : Java virtual machine نوعی ماشین مجازی (واسطی) است که وظیفه اجرای کد جاوا را برعهده دارد. زمانی که در مورد برنامه‌های نوشته شده توسط جاوا صحبت می‌کنیم، حتما باید JVM بر روی سیستم شما نصب باشد تا قابلیت اجرا شدن برنامه‌های تحت جاوا را داشته باشد. سی‌اِل‌آر یا همان CLR : Common Language Runtime نوعی ماشین مجازی (واسطی) است که کد‌های مربوط به CIL را برای سیستم تفسیر و اجرا می‌کند. البته تفاوت‌هایی در خروجی این کد با کد‌های جاوا وجود دارد که در آن زبان IL به عنوان یک زبان شبیه به زبان ماشین مانند اسمبلی (assembly) می‌باشد. در CLR کد‌های تولید شده‌ی بایت‌کد، کمتر از دستورالعمل‌ها و ابر‌داده‌های JVM است. تفاوت اصلی CLR و JVM تفاوت اصلی JVM و CLR در این است که JVM جهت اجرای کد‌های جاوا استفاده می‌شود و CLR مدیریت برنامه‌های اجرایی دات‌نت را مدیریت می‌کند. به طور کلی، JVM امکان اجرای کد‌های کامپایل شده‌‌ی جاوا را فراهم می‌کند که در بسیاری از سیستم‌عامل‌ها و سخت‌افزار‌ها موجود است. از سوی دیگر، CLR یک بستر (محیطی) را برای اجرای برنامه‌های نوشته شده در چهارچوب دات‌نت همراه با امکان مدیریت حافظه، مدیریت خطاها، امنیت و غیره را فراهم می‌کند. نسل جدید JIT برای دات‌نت (نام کد RyuJIT) به لُطف Net. و نسخه‌ی Net Core. نام RuyJIT کُد شناسه از کامپایلر Net. است که وظیفه‌ی آن ترجمه‌ی کد‌های #C به بایت‌کُد IL است که RuyJIT کد‌های بایت‌کُد از نوع IL را به کُد ماشین ترجمه می‌کند. همانطور که مشخص است، جهان به سمت محاسبات ۶۴ بیتی حرکت می‌کند، اما باید در نظر داشته باشید سرعت برنامه‌های ۶۴ بیتی همیشه بیشتر از ۳۲ بیتی‌ها نمی‌باشد! برای مثال نمونه‌ای از آن را می‌توان به کامپایلر JIT برای دات‌نت مثال زد؛ تغییرات و بهبود‌هایی که در نسل بعدی کامپایلر JIT بر روی Net Core. صورت گرفته است نسخه‌ی ۶۴ بیتی آن است که اجازه می‌دهد برنامه‌ها دو برابر سریعتر از نسخه‌ی قبلی خود در دات‌نِت اجرا شود. این امر باعث می‌شود که نظرات شما را در مورد این نسخه از کامپایلر دات‌نت تغییر دهد. همانطور که به نظر می‌رسد، معماری ۳۲ بیتی x86 کامپیوتر‌ها که از زمان‌های ایجاد تا به کنون در نوع خود بسیار عالی بوده‌اند، اما مشکل بزرگی که دارند متاسفانه پشتیبانی تا حداکثر ۴ گیگابایت حافظه‌ی اصلی (Ram) است. با توجه به رُشد روز افزون معماری ۶۴ بیتی x64 نیاز به حافظه‌های بیش از ۴ گیگابایت جدی شد و امروزه ما می‌بینیم که اکثر سخت‌افزار‌ها و حتی دستگاه‌های موبایل نیز مجهز به حافظه‌های بیش از ۴ گیگابایت هستند. برای بهره‌مندی از قابلیت‌های معماری جدید Net Core. کامپایلر خود را با بهینه‌سازی‌های چشمگیری ارائه داده است که می‌تواند تا دو برابر سریعتر از نسل قبلی خود عمل کند. در نظر داشته باشید که، معماری RyuJIT تقریبا نه سال پیش طراحی شده است و کارهای اجرایی از هفت سال پیش آغاز شده است. RyuJIT به عنوان یک کامپایلر تکامل یافته از JIT32 موجود (که از x86 و ARM32 پشتیبانی می‌کند) اجرا شد و به تدریج جایگزین بسیاری از بخش‌های "بَک‌اِند" آن کامپایلر با یک تخصیص دهنده‌ی رجیستر جدید و تولید کننده‌ی کد همراه با برخی از ویژگی‌های جدید و بهبود‌ یافته در "فرانت‌اِند" برای بهینه سازی در اجرا معرفی شده است. در طول این انتقال به کد‌های نسل جدید معماری، سعی بر این بوده است که کد‌های نسل قبل را در کنار نسل جدید نگه داشته شود. انجام این کار‌ها مزایایی داشته است مانند حفظ هزینه‌ها و باز نویسی‌های بسیار! اما مسلماً هزینه‌هایی هم دربر داشته است که کمترین آن‌ها سردرگم بودن توسعه‌دهندگان در باره‌ی آینده‌ی Jit بوده است. در حال حاضر عملکرد RyuJIT برای کد‌های قدیمی بسیار خوب بوده است و سرانجام وقت آن رسیده است که کد‌های نسل قبل در JIT در آینده‌ای نزدیک تمرکز شود. نسل جدید از JIT با تمرکز بر پشتیبانی از معماری ۶۴ بیتی با نام RyuJIT سریعتر از JIT64 است. زبان‌هایی که از JIT/CLR پشتیبانی می‌کنند زبان‌های اصلی این کامپایلر C#, VB.Net و C++ Managed یا همان C++/CLR می‌باشند. نکته: سی++ در این نسخه تغییراتی از جانب مایکروسافت داشته است و از نسخه‌ی استاندارد آن کمی متفاوت است. برای مثال مدیریت حافظه به صورت خودکار و همچنین تغییرات جزئی از قبیل سینتکس را دارا می‌باشد. ساختار برنامه‌های زبان کامپایلری از نوع بومی (Native) در زبان‌های مادر C و ++C در صورتی که تمایل دارید در رابطه با جزئیات ساختار برنامه‌های سریعترین زبان‌‌های برنامه‌نویسی یعنی C و ++C مطلع شوید توصیه می‌شود مقاله‌ی مرتبط با آن را که در زیر آمده است مطلعه کنید.
  8. 1 امتیاز
    اگر شما توسعه دهنده سی‌پلاس‌پلاس هستید، توصیه می‌کنیم این سری از مقالات را دنبال کنید زیرا در این تاپیک قصد داریم به آخرین تغییرات مرتبط با سی‌پلاس‌پلاس مدرن اشاره کنیم. بنابراین در بخش اول، مهم‌ترین موارد منسوخ شده و اشکلات رفع شده و ویژگی‌های سی++ را پوشش خواهیم داد. جزئیات C++ نسخه ۱۷ (بهبود‌ها و تغییرات) بیایید به آرامی شروع کنیم، امروز ما به عناصر حذف شده و یا به موارد بهبود یافته‌ی کتابخانه استاندارد بپردازیم. معرفی به صورت سلسله مراتبی عناصر حذف شده و توسعه یافته (در این بحث) شفاف سازی در زبان قالب‌ها ویژگی‌ها تغییرات اول کتابخانه تغییرات دوم کتابخانه مستندات و لینک‌ها قبل از هر چیز، اگر شما خودتان می‌خواهید استاندارد جدید را کاوش کنید آخرین پیش نویسه را در این بخش مطالعه کنید. در صورتی که می‌خواهید بدانید کدام کامپایلر از ویژگی‌های جدید پشتیبانی می‌کند، در این بخش آن را پیگیری کنید. تغییرات جدید از نسخه ویرایش سوم ۲۰۱۵ ویژوال استودیو در دسترس می‌باشند. علاوه بر این، لیستی از توصیف‌های مختصر از تمامی ویژگی‌های زبان سی‌پلاس‌پلاس ۱۷ تهیه شده است که در این بخش می‌توانید آن را ببینید که در قالب PDF از طرف مرجع رسمی می‌باشد. مواردی که حذف شده اند پیش نویس کنونی زبان حاوی ۱٬۵۸۶ صفحه است! با توجه به الزامات سازگاری، ویژگی‌های جدید اضافه شده اند، اما حذف نشده اند. خوشبختانه چیزهای وجود دارد که از بین خواهند رفت. مواردی که ترجیح داده شده است که حذف شوند حذف تریگراف تریگراف‌ها کاراکترهای ویژه ترتیبی هستند که در موقع عدم پشتیبانی سیستم از نوع ۷ بیتی اَسکی (ASCII) همانند ایزو 646 استفاه شوند. برای مثال =?? کاراکتر ویژه‌ای مانند # تولید شده را در قالب -?? تولید می‌کند. تمامی مجموعه کاراکترهای اصلی سی‌پلاس‌پلاس در قالب 7 بیتی اسکی قرار دارند. موضوع فوق به ندرت مورد استفاده قرار می‌گیرد، بنابراین حذف آن ممکن است به ترجمه ساده کد کمک کند. اگر شما می‌خواهید اطلاعات بیشتری در رابطه با کارآیی تیرگراف‌ها در سی++ کسب کنید به این لینک مراجعه کنید. ---------------------------------------------------------------------------- | trigraph | replacement | trigraph | replacement | trigraph | replacement | ---------------------------------------------------------------------------- | ??= | # | ??( | [ | ??< | { | | ??/ | \ | ??) | ] | ??> | } | | ??’ | ˆ | ??! | | | ??- | ˜ | ---------------------------------------------------------------------------- شما جزئیات بیشتر را می‌توانید در N4086 بیابید. اگر شما واقعا بهتری گراف‌ها در ویژوال استودیو نیاز دارید، نگاهی به مشخصه /Zc:trigraphs در بخش پیکربندی داشته باشید. همچنین، کامپایلرهای دیگر ممکن است مواردی را پشتیبانی نکنند. وضعیت انجام شده کنونی در کامپایلر های GCC:5.1 و Clang:3.5 می‌باشد. حذف کلمه کلیدی register کلمه کلیدی register در استاندارد 2011 سی‌پلاس‌پلاس منسوخ شده است و دیگر استفاده از آن معنایی ندارد. این کلمه کلیدی در حال حاضر حذف شده است. این کلمه کلیدی محفوظ است و ممکن است در نسخه های بعدی باز نویسی شود (مثلا autokeyword به عنوان یک چیز قدرتمند مجددا مورد استفاده قرار گرفته است). جزئیات بیشتر در رابطه با این مورد در P0001R1 قابل مشاهده است. البته فعلا در MSVC انجام نشده است اما در کامپایلر‌های GCC 7.0 و Clang 3.8 انجام شده است. حذف Operator++ bool این اپراتور برای زمان بسیار زیادی است که منسوخ شده است! در سی پلاس پلاس ۹۸ تصمیم بر آن گرفته بودند که از آن استفاده کنند اما در نسخه ۱۷ سی‌پلاس‌پلاس کمیته موافقت خود را جهت حذف آن از زبان اعلام کرده است. جزئیات بیشتر در رابطه با این مورد در P0002R1 قابل مشاهده است. البته فعلا در MSVC انجام نشده است اما در کامپایلر‌های GCC 7.0 و Clang 3.8 انجام شده است. حذف مشخصات استثنایی از سی پلاس پلاس ۱۷ در سی پلاس پلاس ۱۷، مشخصات استثنایی بخشی از نوع سیستمی خواهند بود (به P0012R1 نگاه کنید). با این حال، استاندارد شامل مشخصات استثنایی قدیمی و منسوخ شده اند که به نظر غیرعلمی و غیرقابل استفاده است. void fooThrowsInt(int a) throw(int) { printf_s("can throw ints\n"); if (a == 0) throw 1; } کد بالا در سی‌پلاس‌پلاس ۱۱ رد (منسوخ شده است). تنها اعلامیه استثنایی علمی throw() است، به این معنی است که این کد چیزی را در قالب throw انجام نخواهد داد. اما از سی‌پلاس‌پلاس ۱۱ به اینور، برنامه نویسان توصیه کرده اند که کسی از آن استفاده نکند. برای مثال در کامپایلر Clang 4.0 شما باید خطای زیر را دریافت کنید: error: ISO C++1z does not allow dynamic exception specifications [-Wdynamic-exception-spec] note: use 'noexcept(false)' instead جزئیات بیشتر در رابطه با این مورد در P0003R5 قابل مشاهده است. البته فعلا در MSVC انجام نشده است اما در کامپایلر‌های GCC 7.0 و Clang 3.8 انجام شده است. حذف auto_ptr این یکی از به روز رسانی‌های خوبی است که در سی‌پلاس‌پلاس ۱۱، ما اشاره گرهای هوشمند را دریافت کردیم : unique_ptr,shared_ptr و weak_ptr. با تشکر از این حرکتی که کمیته انجام داده بود، معنای واقعی این به روز رسانی در این بود که زبان می‌تواند پشتیبانی مناسبی از انتقال منابع منحصربفرد را داشته باشد. در این میان auto_ptr یک چیز قدیمی و نادرست در زبان بود به نا به دلایلی auto_ptr در این جا منسوخ شده است و باید به صورت خودکار به unique_ptr تبدیل شود. توجه داشته باشیم که auto_ptr مدت کوتاهی است که از سی‌پلاس‌پلاس ۱۱ به اینور منسوخ شده است و بسیاری از کامپایلر ها منسوخ شدن آن را گزارش می‌دهند که به صورت زیر خواهد بود: warning: 'template<class> class std::auto_ptr' is deprecated در حال حاضر آن به وضعیت نامناسب تبدیل شده است، و اساساً کد شما کامپایل نخواهد شد. در اینجا خطا از طرف MSVC 2017 زمانی که از گزینه /std::c++latest استفاده کنید اعلام خواهد شد. error C2039: 'auto_ptr': is not a member of 'std' اگر شما نیاز به کمک از تبدیل از auto_ptr به unique_ptr دارید، می‌توانید Clang Tidy را بررسی کنید، زیرا آن عمل تبدیل خودکار را انجام خواهد داد. اطلاعات بیشتر در سند N4190 موجود است. همچنین موارد مرتبط دیگری با سند N4190 وجود دارند که در کتابخانه خذف شده اند مانند: unary_function/binary_function ptr_fun() mem_fun()/mem_fun_ref() bind1st()/bind2nd() random_shuffle قوانین جدید خودکار برای Direct-List-Initialization از سی پلاس پلاس ۱۱ به اینور که ما یک مشکل بزرگی در این رابطه داشتیم: auto x { 1 }; از initializer_list اینطور نتیجه‌گیری شده است. با استاندارد جدید، ما می‌توانیم این مشکل را حل کنیم. بنابراین آن می‌تواند به عنوان نوع int که اکثر مردم تصور می‌کنند شناسایی شود. برای اینکه این اتفاق بیافتد، ما نیاز داریم که دو روش تخصیص مقدار اولیه را درک کنیم: کپی و مستقیم. auto x = foo(); // copy-initialization auto x{foo}; // direct-initialization, initializes an // initializer_list (until C++17) int x = foo(); // copy-initialization int x{foo}; // direct-initialization برای مقدار دهی اولیه، سی‌پلاس‌پلاس ۱۷ قوانین جدیدی را معرفی می‌کند: For a braced-init-list with only a single element, auto deduction will deduce from that entry; For a braced-init-list with more than one element, auto deduction will be ill-formed. برای مثال: auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int> auto x2 = { 1, 2.0 }; // error: cannot deduce element type auto x3{ 1, 2 }; // error: not a single element auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int> auto x5{ 3 }; // decltype(x5) is int جزئیات بیشتر را در سند N3922 می‌توانید مشاهده کنید. همچنین جزئیات در رابطه با فهرست خودکار موجود هستند که توسط جناب آقای Ville Voutilainen اشاره شده است. این اضافات در سی‌پلاس‌پلاس از زمان MSVC 14.0، GCC 5.0 و Clang 3.8 کار می‌کنند. گزینه static_assert بدون هیچ نوع پیغامی این واضح است که، این به شما این امکان را می دهد که فقط بدون داشتن گذراندن پیام، نسخه دارای پیغام در دسترس خواهد بود. این سازگاری با سایر موارد مانند BOOST_STATIC_ASSERT وجود دارد. static_assert(std::is_arithmetic_v<T>, "T must be arithmetic"); static_assert(std::is_arithmetic_v<T>); // no message needed since C++17 جزئیات بیشتر در سند N3928 در دسترس است. پشتیبانی شده در MSVC 2017 ٬ GCC 6.0 و Clang 2.5. انواع مختلف شروع و پایان در محدوده حلقه از سی‌پلاس‌پلاس ۱۱ به بعد، محدوده مبتنی بر حلقه ها به صورت داخلی تعریف شده است: { auto && __range = for-range-initializer; for ( auto __begin = begin-expr, __end = end-expr; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } } همانطور که می‌بینید، __begin و __end دارای نوع مشابه هستند. این ممکن است باعث مشکلاتی شود. برای مثال زمانی که شما چیزی شبیه یک نگهبان (محافظ) که از نوع داده دیگری است را داشته باشید مشکل ساز خواهد بود. در سی‌پلاس‌پلاس ۱۷ آن به صورت زیر تغییر کرده است: { auto && __range = for-range-initializer; auto __begin = begin-expr; auto __end = end-expr; for ( ; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } } انواع __begin و __end ممکن است متفاوت باشد چرا که فقط اپراتور مقایسه مورد نیاز است. این تغییر کلی باعث می‌شود که این ویژگی تجربه بیشتری را در این زمینه برای کاربران ارائه دهند. جزئیات بیشتر در P0184R0، پشتیبانی شده در MSVC 2017 ،GCC 6.0 و Clang 3.6.
  9. 1 امتیاز
    مقدمه در دنیای برنامه‌نویسی، نوع جوابی که برای سوالات فنی خود می‌گیرید، هر چقدر که به سختی جواب دادن سوال بستگی دارد، همانقدر هم به روش پرسیدن شما بستگی دارد. با مطالعه‌ی این راهنما قادر خواهید بود طوری سوال کنید که به احتمال بیشتری جواب رضایت بخشی دریافت کنید. هدف ما از این سند در مرجع برنامه نویسی ایران، این است که فرهنگ مکاتبه و رسیدگی به مشکلات همدیگر را در زمینه‌های مرتبط افزایش و بهینه سازی کنیم. بنابراین، امروزه که برنامه‌نویسی بیش از پیش گسترده شده، می‌توانید از وجود افراد با‌تجربه استفاده کنید و جواب‌های خوبی دریافت کنید. با این حال حتی اگر افراد با‌تجربه هم برای پرسیدن سوال روش‌های توصیه شده در این راهنما را به کار گیرند جواب‌های مفید‌تری دریافت می‌کنند. اولین چیزی که باید درک کنیم این است که افراد با‌تجربه سوال های سخت و طولانی را دوست دارند که به خوبی ذهن را درگیر می‌کند. اگر به ما یک سوال جالب توجه بدهید که به آن فکر کنیم از شما سپاس‌گزار خواهیم شد. سوالات خوب محرک ذهن بوده و یک هدیه هستند. سوالات خوب به ما کمک میکنند تا فهم خود را توسعه دهیم و عموماً باعث آشکار شدن مشکلاتی میشود که ممکن است ما ندانیم یا به آنها توجهی نکرده باشیم. در میان افراد با‌تجربه یک سوال خوب یک چالش مهیج است. با این وجود بسیاری از تازه‌کار ها گمان میکنند که افراد با‌تجربه در مقابل سوالات ساده با دشمنی و تکبر برخورد می‌کنند و به نظر می‌رسد که واکنش گستاخانه‌ای با افراد تازه‌کار و ناآگاه دارند. اما به هیچ وجه این‌طور نیست! چیزی که بدون شرمندگی باید بگوییم، خصومت با افرادی است که ظاهراً تمایلی به تفکر در موضوع ندارند و جواب دادن به سوالشان را به نوعی وظیفه‌ی افراد با تجربه می‌دانند. از دید افراد با‌تجربه چنین افرادی باعث هدر رفتن وقت می‌شوند پس وقت خود را صَرف جواب دادن به سوالات بهتر میکنند. همچین افراد با‌تجربه بسیار داوطلب هستند و در زمان‌هایی که مشغول نباشند به پاسخ دادن به سوالات می‌پردازند. در آن مواقع غرق سوالات هستند. پس بدون ترس سوالات را فیلتر می‌کنند و ترجیح می‌دهند که به سوالاتِ بهتر جواب دهند. نوع رفتار شما شایستگی شما را برای دریافت جواب نشان می‌دهد. افراد شایسته زیرک، اندیشمند، هشیار و علاقمند به شرکت فعالانه در توسعهٔ یک راه‌حل هستند. بهترین راه برای گرفتن یک جواب سریع و خوب اینست که آن را مانند یک شخص زرنگ و مطمئن بپرسید، شخصی که واقعاً نیاز به کمک در یک مشکل خاص دارد. قبل از این که سوال کنید قبل از پرسیدن یک سوال فنی از طریق ایمیل، شبکه اجتماعی یا انجمن یک وبسایت، این کار‌ها را انجام دهید: سعی کنید جواب خود را با جستجو در ویکی‌پدیا و یا در قسمت‌های ویکی سایت مربوطه پیدا کنید. سعی کنید جواب خود را با جستجو در آرشیو انجمنی که می‌خواهید بفرسیتد، پیدا کنید. سعی کنید جواب خود را با جستجو در وب پیدا کنید. سعی کنید جواب خود را با خواندن manual (راهنما) پیدا کنید. سعی کنید جواب خود را با خواندن FAQ (سوالات متداول) پیدا کنید. سعی کنید جواب خود را از طریق بازبینی یا آزمایش پیدا کنید. سعی کنید جواب خود را با پرسیدن از یک دوست باتجربه پیدا کنید. اگر یک برنامه‌نویس هستید، سعی کنید جواب خود را با خواندن کدمنبع پیدا کنید. از فنونی استفاده کنید. برای مثال متن پیغام ارور را در گوگل جستجو کنید. حتی اگر به نتیجه ای نرسید، گفتن اینکه «من عبارت زیر را گوگل کردم، اما چیز امیدوار کننده‌ای پیدا نکردم» چیز خوبی برای یک گروه پستی یا خبری است، حداقل به این دلیل که مشخص می‌شود جستجو کمکی نمی‌کند. وقت بگذارید. انتظار نداشته باشد که بتوانید مشکل پیچیدهٔ خود را با چند ثانیه گوگل کردن حل کنید. FAQ ها را بخوانید و بفهمید، آرام و باتمرکز بنشنید و کمی در مورد مشکل خود فکر و گمانه‌زنی کنید. به یکباره تمام سوالات خود را ارسال نکنید فقط به خاطر اینکه اولین جستجوی شما به هیچ جوابی نرسید (یا به جواب‌های زیادی رسید). سوال خود را آماده کنید. به آن فکر کنید. سوالات شتاب‌زده به جواب‌های شتاب‌زده منجر خواهد شد، یا اصلاً به هیچ جوابی نمی‌رسد. هر چه بیشتر این را نشان دهید که برای حل مسئلهٔ خود قبل از درخواست کمک، فکر و تلاش کرده‌اید، همانقدر احتمال بیشتری خواهد رفت که واقعاً به شما کمک کنند. از پرسیدن سوال اشتباه، اجتناب کنید. اگر سوالی بپرسید که بر اساس فرض‌های ناقص و اشتباه است، یک فرد با تجربه ممکن است با این تصور که «یک سوال احمقانه است...» بخواهد به شما یک جواب لفظی و بی‌فایده بدهد، و به امید اینکه شما درس بگیرید از تجربهٔ گرفتن آنچه پرسیدید، نه آنچه مورد نیاز شما بود. ما وقتی می‌توانید به جواب برسید که یک سوال قابل توجه و برانگیزندهٔ ذهن بپرسید، سوالی که بطور ضمنی باعث کمک به تجربهٔ جامعه می‌شود، نه آنکه فقط بصورت انفعالی خواستار دانش از دیگران باشید. از طرف دیگر، روشن ساختن اینکه شما توانایی و تمایل کمک در پروسهٔ حل مسئله را دارید، شروع بسیار خوبی است. «آیا کسی می‌خواهد منبعی معرفی کند؟»، «مثال من چه چیز کم دارد؟»، و «چه وبسایتی را بهتر است بررسی کنم» به احتمال بیشتری جواب خواهند گرفت نسبت به این سوال که «لطفاً روش دقیق کاری که باید انجام دهم را بنویسید.». چون [در حالت اول] شما این را روشن می‌سازید که واقعاً راغب به تکمیل پروسه [ی حل مشکل] هستید اگر شخصی فقط مسیر صحیح را به شما نشان دهد. وقتی سوال می‌کنید: انجمن خود را به دقت انتخاب کنید به این حساس باشید که کجا سوال خود را مطرح می‌کنید. شما احتمالاً نادیده گرفته خواهید شد اگر: سوال شما دارای عنوان مناسب نباشد. یک سوال بسیار ابتدایی را در انجمنی پست کنید که انتظار سوالات فنی پیشرفته را دارند. یا بالعکس. یک سوال مشترک را در چند گروه خبری پست کنید. یک ایمیل شخصی به کسی بفرستید که نه سابقه آشنایی با شما دارد، و نه شخصاً مسئول حل مشکل شماست. افراد با تجربه سوالاتی که بیجا در مکان خاصی پست شود را پاک می‌کنند تا کانالهای ارتباطی‌شان را از غرق شدن در بی‌ربطی حفظ کند. شما نمی‌خواهید این اتفاق برایتان بیفتد؛ بنابراین اولین قدم این است که انجمن درست را انتخاب کنید. باز هم، گوگل و سایر روشهای جستجوی وب، دوست شما هستند. از آنها استفاده کنید. رها کردن یک ایمیل به سوی شخص یا انجمنی که با آن آشنا نیستید، در بهترین حالت یک ریسک است. در مورد اینکه آیا سوال شما مورد استقبال واقع می‌شود یا نه، حدس‌های خوشبینانه نزنید. اگر مطمئن نیستید آن را جای دیگری بفرستید یا اینکه از فرستادن آن خودداری کنید. به یکباره سوال خود را به همه‌ی کانال های کمک‌رسانی ارسال نکنید، این کار مانند فریاد زدن است و افراد را عصبانی می‌کند. به آرامی از میان آنها گام بردارید. عموماً سوالاتی که در یک انجمن عمومی و درست (بجا) پرسیده شوند، احتمال اینکه جواب مفید بگیرند بیشتر است تا آنهایی که در جای خصوصی پرسیده می‌شوند. چندین دلیل برای این وجود دارد. یک دلیل ساده، مقدار منابع پاسخگو است. یکی دیگر تعداد بازدیدکنندگان است؛ افراد با‌تجربه ترجیح می‌دهند به سوالاتی جواب دهند که افراد بیشتری را آموزش دهد، تا سوالاتی که فقط به درد افراد کمی بخورد. به وضوح، برنامه‌نویسان چیره‌دست و سازندگان نرم‌افزارهای محبوب، همواره بسیار بیشتر از توان پاسخ‌گویی‌شان، پیغام‌های انبوه و بی‌هدف دریافت می‌کنند. شما با اضافه شدن به این سیل، یکی از آن موارد بسیار زیاد هستید. از عناوین پرمعنا و دارای موضوع مشخص، استفاده کنید در لیست‌های پستی، گروه‌های خبری یا انجمن‌های وب، عنوانِ موضوع، فرصت طلایی شماست تا با حدود ۵۰ کاراکتر یا کمتر، توجه متخصصانِ قابل را جلب کنید. با عناوینی مثل «لطفاً به من کمک کنید»، آن را هدر ندهید (پیغام‌هایی با این‌گونه عناوین به راحتی دور انداخته می‌شوند). سعی نکنید با عمق اضطراب خود، افراد با تجربه را تحت تأثیر قرار دهید؛ در عوض، از آن فضا برای یک توصیف بسیار مختصر از مشکل خود استفاده کنید. نامطلوب: کمک! کتابخانه X روی لپ‌تاپ من درست کار نمی‌کند! هوشمندانه: با استفاده از امکانY از کتاب‌خانه X برنامه من کار نمی‌کند! هوشمندانه تر: با استفاده از امکان Y در کتاب‌خانه X نسخه 5.8 برنامه من کرش (Crash) می‌کند. تصور کنید که به یک لیست از سوالات یک آرشیو نگاه می‌کنید، که فقط خطوط عنوان‌ها نمایش داده می‌شوند. عنوان پست خود را طوری انتخاب کنید که بخوبی سوال شما را منعکس کنید، تا شخص بعدی که آرشیو را جستجو می‌کند، بتواند دنبال آن ریسمان (thread) را بگیرد و به یک جواب برسد، بجای اینکه دوباره آن سوال را پست کند. رسیدن یک سوال در یک پاسخ، به خودی خود مورد شک است، چون آن فقط توسط افرادی دیده خواهد شد که این ریسمان را دنبال می‌کنند. پس یک ریسمان (تاپیک) جدید را آغاز کنید، مگر اینکه مطمئنید می‌خواهید فقط از افرادی بپرسید که در حال حاضر در این ریسمان فعال هستند. پاسخ دادن را آسان کنید پایان دادن سوال با این عبارت که «لطفاً پاسخ خو را به ... بفرستید»، جواب گرفتن شما را کاملاً بعید می‌سازد. بصورت واضح، از لحاظ دستوری صحیح، و با املای صحیح بنویسید مهم است که سوال خود را واضح و خوب بیان کنید. قبل از ارسال سوال خود یکبار متن سوالتان را بررسی و سعی خود را بکنید تا زبان (بیان) خود را بهبود دهید (صیقل دهید). لازم نیست که رسمی و سنگین باشد. در واقع افراد با تجربه به آن طرز بیانی بها میدهند که غیر رسمی، عامیانه، شوخ‌طبعانه و همراه با دقت و ظرافت باشد. اما باید دقیق باشد؛ باید نشانه‌هایی از اینکه که شما اندیشه و توجه می‌کنید را داشته باشد. این نکته بسیار مهم است که به زبان رسمی آن کانال ارتباطی سوال خود را ارسال کنید. برای مثال اگر در انجمنی که زبان رسمی آن فارسی است سوال خود را به زبان انگلیسی (یا فینگلیش) بنویسید سوال شما معمولا یا پاک خواهد شد و یا نادیده گرفته می‌شود. اگر دارید سوال خود را در انجمنی می‌پرسید که از زبان بومی شما استفاده نمی‌کند، شما یک میزان محدودی از خطاهای املایی و دستوری خواهید داشت، اما از روی تنبلی دچار خطاهای بیش از حد نشوید (بله، افراد معمولاً می‌توانند آن تفاوت را تشخیص دهند). همینطور اگر نمی‌دانید که شخص پاسخگو چه زبانی دارد، به انگلیسی بنویسید. افراد با‌تجربه مشغول، سوالات با زبانی که نمی‌فهمند را نادیده می‌گیرند، و انگلیسی زبان کاری اینترنت است. با نوشتن به زبان انگلیسی، این احتمال را که سوالتان بدون خوانده شدن پاک شود، به حداقل می‌رسانید. سوال خود را در قالب‌های استاندارد و در دسترس مطرح کنید نامه خود را به صورت پاراگراف‌هایی که از خطوط به هم پیچیده شده تشکیل شده‌اند، نفرستید. این کار، پاسخ گویی به قسمت‌های مختلف نوشته شما را دشوار می‌کند. هرگز تصور نکنید که مخاطبین شما قادر به خواند فایل‌های اختصاصی مانند Microsoft word یا Excel هستند. افراد مختلف از سیستم عامل‌های مختلف و برنامه‌های متفاوتی برای ویرایش متن استفاده می‌کنند پس بهترین گزینه این است که فایل خود را به صورت متنی ارسال کنید. در صفحات گفتگو، از اشکال خندان (Smile) و امکانات HTML استفاده نکنید. یکی دو تا از این اشکال ایرادی ندارد. اما در صورت استفاده بیش از حد. بهای سوال شما را کاهش می‌دهد و احتمال نادیده گرفته شدن سوال شما افزایش پیدا می‌کند. اگر شما از یک پردازش‌گر ایمیل با صورت گرافیکی کاربری مانند MS، Outlook، Netscape، Messenger و یا از این‌گونه‌ها استفاده می‌کنید، آگاه باشید که در صورتی که از تنظیمات پیش‌فرض آن استفاده می‌کنید، ممکن است این قوانین نقض شوند. بیشتر این پردازشگرها دارای یک دستور در فهرست خود به نام view source هستند از این گزینه در پوشه نامه‌های فرستاده خود استفاده کنید و فرستادن نوشته ساده (plain tent) بدون ضمایم غیر ضروری را بررسی کنید. درباره مشکل خود دقیق و آگاه باشید نشانه‌های مشکل ایجاد شده یا bug ها را به دقت و روشنی شرح دهید. محیطی که در آن این مشکل ایجاد می‌شود را شرح دهید. (سیستم عامل، کاربرد و ...) شرکت فروشنده و مدل آنرا هم معرفی کنید مثلاً (Fedora Coret یا Slackware 91 و ...). مطالعاتی که بر روی این مشکل انجام داده‌اید را شرح دهید. مراحل تشخیص مشکل و رفع آنرا که انجام داده‌اید، قبل از طرح سوال، شرح دهید. هرگونه تغییر در سخت‌افزار یا نرم‌افزار که اخیراً انجام شده است را شرح دهید. تلاش کنید تا به سوالاتی که پیش‌بینی می‌کنید از شما پرسیده شوند، پیش‌تر پاسخ دهید. حجم مطالب دلیلی بر دقیق بودن آن نیست باید دقیق و آموزنده بنویسید. این هدف با نوشتن حجم زیادی از داده‌ها و کدها در نامه تقاضای کمک محقق نمی‌شود. اگر یک مشکل بزرگ و پیچیده دارید، سعی کنید تا آنرا تا حد ممکن خلاصه و مرتب ارائه کنید. این امر حداقل سه فایده دارد. اول اینکه معلوم شود که شما برای خلاصه کردن سؤال خود تلاش کرده‌اید یا تمایل بیشتری برای پاسخ به شما وجود خواهد داشت. دوم اینکه با خلاصه‌سازی پاسخ مفیدتری هم خواهید گرفت؛ و سوم اینکه در حین خلاصه کردن و پیرایش گزارش خود ممکن است بتوانید مشکل را حل کنید یا راه حل کوتاه‌تری برای آن پیدا کنید. بدون اطمینان ادعای یافتن یک bug را نکنید! هنگامی که با یک نرم‌افزار به مشکل برخوردید، بدون اطمینان کامل ادعای یافتن یک bug جدید را مطرح نکنید. راهنمایی: تا هنگامی که با یک ضمیمه به کد منبع نتوانید مشکل را برطرف کنید یا با آزمایش رگرسیون با ورژن قبلی که نشان دهنده یک رفتار نادرست باشد، شما نباید مطمئن شوید. این امر در مورد وب سایت‌ها و مدارک هم صدق می‌کند سندی را به عنوان bug یافتید، باید متنی را جایگزین آن کنید یادآوری می‌شود که کاربران بسیاری هستند که مشکل شما را تجربه نکرده‌اند. همچنین شما با خواندن مطالب و وب سایت‌های مرتبط، در مورد آن نرم‌افزار آموزش دیده‌اید در غیر این صورت شما کاری را اشتباه انجام می‌دهید و نه نرم‌افزار. افرادی که یک نرم‌افزار را تهیه می‌کنند، تلاش می‌کنند تا آن نرم‌افزار حداکثر کارایی مطلوب را داشته باشد. اگر شما ادعا کنید که یک bug در آن یافته‌اید، در واقع کامل بودن کار آنها را زیر سؤال برده‌اید و این باعث رنجاندن آنهان می‌شود، حتی اگر حق با شما باشد. به خصوص ذکر کلمه bug در عنوان نامه، کار سیاست مدارانه‌ای نیست. وقتی که سوال خود را مطرح می‌کنید، بهتر است فرض کنید که شما کار اشتباهی را انجام می‌دهید، حتی اگر مطمئن باشید که یک bug واقعی را یافته‌اید. اگر واقعاً این طور باشد، در مورد آن در پاسخ‌ها خواهید شنید. با این کار نگهدارنده‌های نرم‌افزار از شما عذرخواهی خواهند کرد، همچنین اگر شما اشتباه کرده باشید، باید از آنها عذرخواهی کنید. به جای حدس‌های خود نشانه‌های مشکل را شرح دهید نوشتن در مورد اینکه خودتان علت مشکل پیش آمده را چه می‌دانید، مفید نیست (اگر فرضیات شما به‌کلی اشتباه باشد آیا با دیگران مشورت می‌کنید؟). لذا سعی کنید که به دوست‌داران کامپیوتر از علائم و نشانه‌های اولیه مشکل موجود بگویید و نه از فرضیات و تئوری‌های خود. بگذارید آنها خود تفسیر کنند و مشکل را تشخیص دهند اگر احساس می‌کنید که ذکر کردن حدس خودتان می‌تواند مهم باشد، آنرا روشن و تحت عنوان حدس خودتان بیان کنید و همچنین ذکر کنیدن که چرا این پاسخ نمی‌تواند جوابگوی مسئله باشد. هدف را مشخص کنید، نه مرحله اگر به دنبال این هستید که بدانید چطور باید کاری را انجام دهید (مثل گزارش کردن یک اشکال یا bug )، با شرح دادن هدف خود شروع کنید. بعد از آن فقط برخی از مراحل خاص که برای رسیدن به آن طی کردید و موفق نشدید را شرح دهید. اغلب، افرادی که به کمک تکنیکی نیاز دارند، هدف بلند مرتبه‌ای را در ذهن می‌پرورانند و در راهی که فکر می‌کنند تنها راه رسیدن به هدف است گمراه می‌شوند. آنها برای کمک گرفتن مرحله به مرحله می‌آیند اما نمی‌دانند که مسیر اشتباه است تلاش قابل توجهی برای گذر از این مرحله مورد نیاز است. سوال نامطلوب: چگونه می‌توان در برنامه FooDraw مقادیر RGB رنگ را بر مبنای شانزده‌تایی انتخاب کرد؟ سوال هوشمندانه: من تلاش می‌کنم که جدول رنگ‌ها را روی یک تصویر با مقادیر انتخابی خودم قرار دهم. در حال حاضر تنها راهی که به نظرم می‌رسد اینست که هر ردیف از جدول را اصلاح کنم اما نمی‌توانم در برنامه FooDraw رنگ‌ها را بر مبنای مقادیر RGB شانزده‌تایی انتخاب کنم. سوال دوم هوشمندانه بود. جواب این سوال ابزار بهتری برای آن کار را پیشنهاد می‌دهد. سوال را صریح مطرح کنید برای سوال‌هایی که انتهای مشخصی ندارد، بازه زمانی محدودی برای پاسخگویی به آنها در نظر گرفته نمی‌شود. کسانی که می‌خواهند پاسخ‌های مفیدی به شما بدهند، مشغول‌ترین افراد هستند. (چون در اغلب کارها به تنهایی کار می‌کنند). این گونه افراد نسبت به سوال‌هایی با بازه زمانی نامحدود حساسیت دارند و تمایل چندانی به پاسخ‌گویی به آنها ندارند. شما هنگامی که یک پاسخ مفید دریافت می‌کنید که از پاسخگویی خود در مورد چیزی که می‌خواهید به‌طور صریح پرسیده باشید (از اشاره‌گر استفاده کند، که بفرستید، پیوست را بررسی کنید یا هر چیز دیگر). این کار تلاش پاسخگو را بر روی هدف شما متمرکز می‌کند و به طور ضمنی حدی از نظر زمانی برای پاسخگویی و صرف انرژی برای کمک به شما ایجاد می‌کند. این کار خوبی است. برای درک دنیایی که متخصصین در آن زندگی می‌کنند، به مهارت به عنوان یک منبع و زمان فراوان برای پاسخگویی به یک مورد کمیاب فکر کنید. هر چه زمان کمتری را برای پاسخگویی به سوال خود به طور ضمنی در نظر بگیرید، احتمال اینکه جواب واقعاً مناسب از جانب یک فرد خبره و پرمشغله دریافت کنید، بیشتر می‌شود بنابراین بهتر است که برای سوال خود قالبی در نظر بگیرید که زمان مورد نیاز به پاسخگویی به آن را از جانب یک فرد خبره به حداقل برساند. اما این کار اغلب مشابه ساده‌سازی یک سوال نیست. به عنوان مثال، ممکن است برای شرح مناسبی از X یک راهنمایی بکنید؟ معمولاً سوال هوشمندانه‌تری است نسبت به اینکه ممکن است لطفاً X را توضیح دهید! اگر شما یک کد نادرست دارید، بهتر است در مورد اینکه چه اشکالی دارد بپرسید تا اینکه درخواست کنید کسی آنرا اصلاح کند. سوالهای بی‌معنی را حذف کنید از به پایان رساندن درخواست سوال خود با جملات بی‌مفهومی مانند کسی می‌تواند به من کمک کند؟ یا آیا جوابی وجود دارد؟ پرهیز کنید. اولاً، اگر شرح خود را تا نیمه نوشته بودید، این گونه سوال‌ها زائد هستند. دوماً، به دلیل زائد بودن آنها کاربران آنها را آزاردهنده تلقی می‌کنند و احتمال دارد که جواب‌هایی بی عیب و نقص ولی بی اعتنا مانند بله، به شما می‌توان کمک کرد. یا خیر، هیچ کمکی نمی‌توان کرد به شما بدهند. به طور کلی، از سوالهای آری یا خیر باید اجتناب شود مگر اینکه تنها جواب بله یا خیر برای شما کافی باشد. سوال خود را با کلمه «فوری» نشانه‌دار نکنید، حتی اگر برای شما اینگونه باشد: این مشکل شماست، نه دیگران. اظهار ضرورت کردن نتیجه معکوس می‌دهد. بیشتر کاربران به راحتی اینگونه سوال‌ها را که با خودخواهی و گستاخی درخواست توجه فوری و ویژه می‌کنند را حذف می‌کنند. تنها یک شبه استثناء وجود دارد. اگر شما در یک محل با مرتبه بالا و با یک نرم‌افزار کار می‌کنید و از نظر زمانی تحت فشار هستید، گفتن مودبانه محدودیت زمانی خود می‌تواند مؤثر باشد تا دیگران را به پاسخ دادن به شما ترغیب کند. البته این کار ریسک بالایی دارد، چون معیار جالب بودن مسائل از نظر کاربران دیگر با شما متفاوت است. به عنوان مثال فرستادن نامه از یک ایستگاه فضایی بین‌المللی قانع کننده است اما از جانب یک انسان با احساس خوب و مهربان یا یک سیاستمدار خیر. در واقع، نوشتن کلمه «فوری» باعث می‌شود که از سوال شما اجتناب و دوری شود حتی اگر از نظر آنها مهم باشد. اگر فکر می‌کنید که این امری مبهم است، دوباره این مطالب را بخوانید تا کاملاً آنرا درک کنید، قبل از آنکه نوشته‌ای را به جایی بفرستید. ادب و احترام را رعایت کنید مؤدب باشید. از جملاتی مانند «لطفاً» و «با تشکر از توجه شما» یا «ممنون از ملاحظه شما» استفاده کنید. به طور واضح بیان کنید که شما اینکه دیگران وقت خود را برای کمک به شما رایگان صرف می‌کنند، تحسین کنید. صادق بودن، به اندازه واضح، دقیق، با دستور زبان صحیح و مشروح بودن و پرهیز از قالب‌های مالکانه، مهم نیست و حتی جایگزین آنها هم نمی‌تواند باشد. کاربران بطور کلی علاقه دارند که گزارش‌های دقیق تکنیکی از bug ها و ایرادها را هر چند بی ادبانه دریافت کنند تا نوشته‌های مؤدب ولی ابهام‌آمیز. (اگر این امر برای شما مبهم است، به یاد داشته باشید که سوال‌ها را با چیزی که توسط آن می‌توان یاد گرفت ارزش‌گذاری می‌کنند). به هر حال اگر مشکلات تکنیکی خود را ردیف کنید، مؤدب بودن شانس شما را برای دریافت پاسخ مفید افزایش می‌دهد. باید ذکر شود که تنها مخالفتی که از سوی کاربران قدیمی نسبت به این نوشته دریافت کرده‌ایم، در رابطه با توصیه‌های قبلی ما برای تشکر پیشاپیش است. برخی از کاربران احساس می‌کنند که این دلالتی به منظوری دارد و نه تشکر. توصیه ما اینست که هم پیشاپیش تشکر کنید و هم بعد از پاسخ‌گویی و یا ادب و احترام را به روشهای دیگری بیان کنید قبلاً با جملاتی مثل: «با تشکر از توجه شما» یا «ممنون از ملاحظه شما». روش حل را با یادداشت مختصری پاسخ دهید بعد از اینکه مسئله حل شد، یادداشتی به همه کسانی که به شما کمک کرده‌اند بفرستید، آنها را از نحوه‌ی حل مطلع کنید؛ و باز هم از یاری آنها تشکر کنید. پاسخ شما نباید طولانی و شامل جملاتی ساده مثل: «ایراد از کابل شبکه بود، با تشکر از همه» باشد. حتی اگر پاسخ ندهید، بهتر از این جملات است. پاسخ کوتاه و خلاصه‌ای شیرین بهتر است از یک مقاله طولانی مگر اینکه عمق تکنیکی مسئله زیاد باشد. ذکر کنید که چه عملی مشکل را حل کرد اما لزومی ندارد که تمام مراحل حل مشکل را گزارش کنید. برای برخی از مسائل مناسب است که خلاصه‌ای از مراحل رفع مشکل را گزارش کنید. وضعیت نهایی مسئله خود را شرح دهید. توضیح دهید که چه روشی شما را به حل رساند و بعد از آن به داده‌هایی که جواب نمی‌رسد اشاره کنید. روشهای اشتباه را باید بعد از جواب صحیح و دیگر مطالب خلاصه بیاورید تا اینکه خلاصه شما تبدیل به یک داستان کارآگاهی نشود. از افرادی که به شما کمک کردند نام ببرید، با این کار با آنها دوست هم می‌شوید. در نهایت، این گونه خلاصه نویسی به تمام کسانی که کمک کرده‌اند، احساس رضایت‌مندی و نزدیکی به مسئله می‌دهد و این کم ارزش نیست. اگر شما یک تکنسین یا فرد باتجربه نیستید، مطمئن باشید که این احساس برای راهنماها و متخصصینی که از آنها کمک گرفته‌اید، بسیار مهم است. اگر نفهمیدید... اگر جواب را نفهمیدید، فوراً تقاضای روشن کردن پاسخ نکنید. از همان اندازه‎هایی که برای پاسخ اولیه خودتان (دستورالعمل‎ها ( FAQS)، وب و دوستان ماهر) برای فهمیدن جواب استفاده کنید. سپس اگر باز هم نیاز به شفاف سازی نشان دهید که چه چیزی یادگرفته‎اید. برای مثال تصور کنید که من به شما می‎گویم: "به‎نظر می‎رسد که شما Zentry گرفته شده‎ای دارید، باید آنرا تمیز کنید." در این صورت یک جواب نامناسب این خواهد بود: « Zentry چیست؟» و یک جواب خوب این خواهد بود "بسیار خوب، من صفحه اصلی را خواندم و به Zentry ها تحت عنوان سوئیچ‎های –Z و –P اشاره شده است اما هیچ یک از تمیز کردن Zentry چیزی نگفته‎اند. آیا اینها درست است یا من نکته‎ای را متوجه نشده‎ام؟" اخلاق حرفه ای داشته باشید با توجه به راه‎های مفصلی که در این‎جا گفته شد یا راه‎های مشابه بعید است که در راه‌های ارتباطی با افراد باتجربه اشتباه کنید. به‎طور دقیقی با جملات متفاوت به شما گفتیم که چگونه می‎توان اشتباه کرد. اگر چنین اتفاقی افتاد بدترین کار اینست که از این تجربه خود ناله کنید، ادعا کنید که شفاهاً مورد توهین قرار گرفته‎اید، تقاضای عذرخواهی کنید، نقستان را حبس کنید، به شکایت کردن تهدید کنید، از افراد شکایت کنید و غیره. در عوض پیش بروید. این امری طبیعی است. درواقع مناسب و سالم است. گاهی اوقات افراد بدون هیچ دلیل روشنی شخصاً شما را مورد حمله قرار می‎دهند حتی اگر شما اشتباهی نکرده باشید (یا فقط در ذهن آنها دچار اشتباه شده‎اید) در این موارد، شکایت کردن روشی واقعاً اشتباه است. این افرادِ متجاوز، نادان هم هستند که بدون هیچ دلیلی، خود را با تجربه می‎دانند یا با آزمایش‎های روان‎شناسی می‎خواهند بدانند که اشتباه کرده‎اید یا خیر. خوانندگان دیگر هم آنها را نادیده می‎گیرند و یا با روش خودشان با آنها برخورد می‎کنند رفتار این‎گونه افراد خود آنها را دچار مشکل می‎کند که به شما ربطی ندارد. اجازه ندهید که داخل این‎گونه بحث‎ها به دام بیفتید. بعد از اینکه بررسی کردید که آیا آنها واقعاً توهین هستند و نه اشاره‎ای به اشتباه شما و نه اشاره‎ای به اشتباه شما و نه اشاره‎ای زیرکانه به جواب واقعی سوال شما اغلب توهین‎ها نادیده گرفته می‎شوند. به اطلاعات موجود در فایل های ارسالی و ضمیمه توجه کنید در بسیاری از مواقع ممکن است سوال شما همراه با فایل (یا فایل های) ضمیمه‌ای باشد که مشکل را دقیق‌تر به پاسخ دهند‌گان شرح میدهد. حتما قبل از ارسال فایل ضمیمه به موارد زیر توجه کنید: فایل ارسالی حاوی اطلاعات شخصی افراد نباشد. این موارد حریم شخصی افراد را نقض میکند و ممنوع می‌باشد. در صورتی که سوال شما مربوط به نحوه‌ی نمایش آن اطلاعات است میتوانید با ابزار ویرایش تصویر یا فایل، اطلاعات شخصی را حذف کنید.
این صفحه از پرچمداران بر اساس منطقه زمانی تهران/GMT+03:30 می باشد
×