پرچمداران
-
در نوشتههای وبلاگ
- همه بخش ها
- فایل
- دیدگاه فایل
- نقد و بررسی فایل
- مقالات
- مقاله دیدگاه
- مقاله نقد و بررسی
- صفحات استاتیک
- صفحه دیدگاه
- صفحه نقد و بررسی
- کتابخانهها
- کتابخانه دیدگاه
- کتابخانه نقد و بررسی
- رویداد
- دیدگاه های رویداد
- بازبینی رویدادها
- تصاویر
- دیدگاه های تصویر
- نقد های تصویر
- آلبوم ها
- نظر های آلبوم
- نقد های آلبوم
- پست ها
- نوشتههای وبلاگ
- دیدگاه های وبلاگ
- بروزرسانی وضعیت
- پاسخ های دیدگاه ها
-
تاریخ سفارشی
-
همه زمان ها
4 خرداد 1397 - 13 اردیبهشت 1403
-
سال
12 اردیبهشت 1402 - 13 اردیبهشت 1403
-
ماه
14 فروردین 1403 - 13 اردیبهشت 1403
-
هفته
6 اردیبهشت 1403 - 13 اردیبهشت 1403
-
امروز
13 اردیبهشت 1403
-
تاریخ سفارشی
سه شنبه, 6 اسفند 1398
-
همه زمان ها
مطالب محبوب
در حال نمایش مطالب دارای بیشترین امتیاز از زمان سه شنبه, 6 اسفند 1398 در نوشتههای وبلاگ
-
3 امتیازدر این مقاله من قصد دارم به معرفی ده فریمورک برتر جهان در بازهٔ سالهای ۲۰۱۹ و ۲۰۲۰ اشاره کنم که در حوزهٔ صنعت وب کاربرد دارند. معمولاً در سایتها، وبلاگها و گروههای تلگرامی حرف از فریمورکهای شناخته شدهای مانند Asp.net core و یا Laravel به گوش میرسد. اما واقعیت این است که فریمورکهایی که در مورد آنها بحث میشود جایگاه خاصی در بین فریمورکهای قدرتمند و به عنوانی ناشناخته مانند Drogon، h2o، ulib و غیره ندارند! جالب است بدانید فریمورکهایی که در ادامه نامهایشان را میشنوید به قدری سریع و قدرتمند هستند که مو بر تنِ شما سیخ خواهد کرد! برای مثال در این مقایسه جایگاه فریمورکهای داتنت به بالاتر از ۵۰ و لاراول به بیشتر از ۲۰۰ رتبه میرسد! این در حالی است که بر خلاف انتظارِ عام، فریمورکهای تحت سی/سی++ و راست به عنوان سریعترین فریمورکها شناخته میشوند. در واقع مقایسه بر اساس نتایج گرفته شده از مرجع Techempower میباشد که هر ساله یک مقایسه در رابطه با کارآیی و کیفیت فریمورکهای وب میپردازد. سنجشِ فوق بر اساس وظایفی مانند سریالسازی جیسان، دسترسی به پایگاه داده و عملیات سمت سرور، پردازش و غیره میباشد. در این آزمایشها عملکرد فریمورک بر روی سیستمعامل، به صورت فولاِستک و میکرو اندازهگیری شده است که هر کدام را در رتبهٔ خاصی از وضعیت آن سوق میدهد. بهترین فریمورکها از نظر بنچمارک (کارآیی) در سال ۲۰۱۹ در دورِ ۱۸ بین ۲۲۰ فریمورک متعلق به h2o و ulib بوده است. کتابخانهٔ h2o یکی از قویترین مواردی است که میتوان به آن اشاره کرد. در سال ۲۰۲۰ این رتبهبندی به نفعِ فریمورک جدیدتری به نام دراگون (Drogon) و مجدداً ulib جمع بندی شده است که نشان میدهد فریمورک ulib به عنوان یکی از برترین فریمورکهای نوشته شده تحت سی و سی++ و همچنین دراگون تحت استانداردهای ۱۴ و ۱۷ زبان برنامهنویسی سیپلاسپلاس معرفی شده است. بنابرین بهتر است در مورد دراگون بیشتر بدانیم: این فریمورک تحت زبان برنامهنویسی ++C در استاندارد ۱۴ و ۱۷ توسعه یافته و بر روی سکوهای لینوکس، مک و ویندوز قابل اجراست. دراگون تحت ویژگی non-blocking I/O کار میکند و سرعت را همراه با دقت بسیار بالایی به خصوص بر روی پلتفرمهای FreeBSD تضمین میکند. لینک مخزن توسعه و کدهای دراگون. مثال از کد اولیه: #include <drogon/drogon.h> using namespace drogon; int main() { app().setLogPath("./") .setLogLevel(trantor::Logger::kWarn) .addListener("0.0.0.0", 80) .setThreadNum(16) .enableRunAsDaemon() .run(); } با توجه به مقایسههای صورت گرفته در آزمایشهای مختلف زیر رتبهبندی فریمورکها مشخص میشود. آزمایشهای فوق بر روی پردازندهٔ Dell R440 Xeon Gold صورت گرفته است که در این لینک آمده است. JSON serialization Single query Multiple queries Fortunes Data updates Plaintext آزمایشهای مربوطه تنها به ۱۰ مورد اول اشاره کرده است، بنابراین برای مشاهدهٔ لیست بیشتر و جزئیات آنها به مرجع آن مراجعه کنید.
-
2 امتیازدر سالی که گذشت (۲۰۲۲)، سیپلاسپلاس محبوبترین زبان برنامهنویسی با رشد شاخص محبوبیت ۴.۶۲٪ انتخاب شد! جایزه زبان برنامهنویسی سال TIOBE به ++C تعلق گرفت! این جایزه به زبان برنامهنویسی تعلق میگیرد که بیشترین افزایش محبوبیت را در یک سال تجربه کرده است. شاخص TIOBE میزان محبوبیت زبانهای برنامهنویسی را اندازهگیری میکند. با این حال، قبل از نتیجهگیری، توجه به این نکته مهم است که Index (شاخص) نه چیزی در مورد کیفیت یک زبان برنامهنویسی میگوید و نه ادعا میکند. این رتبهبندی با تجزیه و تحلیل تعداد مهندسان ماهر در یک زبان خاص، تعداد دورههای آموزشی در آن زبان و تعداد فروشندگان شخص ثالثی که محصولات یا خدمات مرتبط با آن زبان را ارائه میدهند، محاسبه میشود. این فهرست ماهانه بهروز میشود و بر اساس دادههای موتورهای جستجوی محبوب مانند گوگل، بینگ و یاهو است. جایزهٔ زبان برنامهنویسی سال TIOBE در ژانویه هر سال بر اساس رتبهبندی سال قبل اعلام میشود. سیپلاسپلاس یک زبان برنامهنویسی در سال ۲۰۲۲ انتخاب شد که با محبوبیت رشد ۴.۶۲ درصد و بیشترین رشد انتخاب شده است. این زبان برنامهنویسی سطح بالا با کارایی بالا و چندمنظوره برای توسعهٔ نرمافزارهای سیستمی، برنامههای کاربردی و بازیهای ویدیویی با انعطافپذیری و قابلیت کنترل سطوح پایین است. این زبان در نوامبر ۲۰۲۲ جاوا را پشتسر گذاشت و به رتبهٔ سوم شاخص رسید و محبوبیت آن به طور پیوسته در حال افزایش است. نایب قهرمان در سال ۲۰۲۲ به ترتیب C با رشد ۳.۸۲ و پایتون با ۲.۷۸ درصد رشد بودهاند.
-
2 امتیازیک سوأل بسیار مهم و پر مخاطب در بارهٔ زبانبرنامهنویسی سیپلاسپلاس در سالهای اخیر این است که «آیا جایگزینی برای این زبان وجود دارد و یا قابل جایگزین است»؟ در بسیاری از پاسخها نشان از گزینههایی مانند Go، Rust و D دیده میشود که بهتر است نسبت به نظرات متخصصهای برنامهنویسی به این موضوع پرداخته شود، ابتدا باید در نظر گرفت که هر ابزاری میتواند جایگزینی داشته باشد اما شرایط و نحوهٔ استفادهٔ آن در رابطه با نیاز متفاوت است. اخیراً سوألات زیادی در این موضوع دیده شده است که میگویند، Rust یک زبان برنامهنویسی ایمن، سریع و سیستمیِ جایگزین برای سیپلاسپلاس است! اما آیا واقعاً اینگونه است یا صرفاً ما بر اساس احساسات و اشتیاق به بهروز شدن به این موضوع میپردازیم؟ پاسخ برای این سوأل به صورت زیر در مدلهای مختلف میتواند مطرح شود که نتیجهگیری و تصمیم از خلاصهٔ آن به عهدهٔ خودِ شماست. من بر این باورم که زبانهای برنامهنویسی همه و همه در حال بهروز رسانی و بهتر شدن نسبت به نسخهها، استانداردها، و نسلهای گذشتهٔ خودشان هستند و به هیچ عنوان هیچ زبانی تا به امروز به طور جدی منسوخ شده اعلام نشده است. برای درک این مطلب بهتر است ابتدا به واژهٔ «منسوخ شده» یا «Deprecated» بپردازیم، این واژه زمانی مورد استفاده قرار میگیرد که شرایط زیر بر آن حاکم باشد: گزینهٔ مورد نظر به طور رسمی از طرف سازنده، پشتیبان یا صاحب آن بد دانسته شده و رسماً کنار گذاشته شود. گزینهٔ مورد نظر بهروز رسانی نشود و آخرین بهروز رسانی آن نیز شامل مشکلاتی باشد که بعد از مدتها نیز حل نشده باشد. گزینهٔ مورد نظر دیگر مورد استفاده قرار نگیرد و کاربردی هم در بین رقبای خود نداشته باشد. گزینهٔ مورد نظر دیگر پشتیبانی نشود و به قولی مُرده باشد. گزینهٔ مورد نظر به علاوهٔ این که شامل این موارد میشود، باید دارای یک جایگزین مناسب و عالی باشد. با توجه به این معیارها و با در نظر گرفتن رسالت هر یک ابزارها باید به آن توجه کرد که هر زبان یا ابزار برنامهنویسی خارج از این، در مرحلهٔ پیشرفت قرار گرفته است که آن نشان دهندهٔ زنده بودن و کاربردی بودن آن است. از طرفی، زبانی مثل سیپلاسپلاس جایگزین نمیشود چرا که هیچ یک از دلایل و معیارهای بالا شامل حال آن نمیشود، اتفاقاً برعکس این زبان دارای ویژگیهای معیاری زیر است: این زبان به طور رسمی توسط کمیتهٔ استانداردسازی که متعلق به هیچ یک از شرکتهای غول صنعتی و یا خصوصی نمیباشد پشتیبانی میشود. این زبان به طور مداوم در حال بهروز رسانی است و کاربردهای چند-منظوره و همه جانبهٔ خود را داراست. این زبان از ویژگیهای از ویژگیهای بسیار خوب به همراه سریعترین بازدهیها را داراست. این زبان رقیبهای بسیاری دارد، اما هیچ کدام از آنها هنوز در عمل و دامنهٔ وسیعی موفق به نمایش عملکرد بهتری نبودهاند. این زبان همانند دیگر ابزارها دارای مشکلاتی است، اما با توجه به پوشش و پشتیبانی از ویژگی BC در روند استانداردسازی و بهروز رسانی به خوبی از پس آنها بر آمده است. برای مثال، زبان جاوا یکی از بهترین زبانهای برنامهنویسی است و خیلی از شرکتها مانند گوگل در سیستمهای توزیع شده از آن استفاده میکنند. اما به معنای این نیست که به سرعت سی++ میرسد و در حد مقایسه با آن است. این زبان میتواند دهها و صدها برابر کندتر از سی++ باشد و این مربوط به طراحی، ساختار و مسائل مربوط به زبان است. از طرفی سیپلاسپلاس محبوب است زیرا که ویژگیهای زیر را دارد و طی سالهای بسیاری آن را ثابت کرده است: کارآیی (پرفرمنس) و سرعت فوقالعادهٔ این زبان، البته خیلی از زبانها ادعا میکنند که همچین ویژگیای را دارند که در عمل نتیجهٔ جالبی مشاهده نمیشود. ذاتِ چند-سکویی و چند-منظوره بودن آن، حداقل همهٔ سیستمها میتوانند کدهای سی++ را کامپایل و اجرا کنند. این زبان به راحتی میتواند با زبانها و فناوریهای دیگری ارتباط برقرار کرده و با آنها تعامل داشته باشد. این زبان به عنوان یکی از کممصرفترین زبانهای برنامهنویسی از نظر مصرف انرژی محسوب میشود. بسیاری از مهندسین این زبانها را به صورت مقطعی و بارها دیده و با آن آشنا هستند. کتابخانههای پیشفرض استاندارد STL و دیگر کتابخانههای سی++ بسیار قدرتمند و گسترده هستند. کتابخانههای نوع سوم (Third-Party) بسیار قدرتمند و بهروز هستند. اولویتهای سیستمهای یونیکس و حتی ویندوز اکثراً بر روی C و ++C است و بازنویسی آنها با زبانهای دیگر هزینهٔ بسیاری را به ارمغان میآورد. بسیاری از وابستگیهای ایجاد شده در سالهای بسیار طولانی بر اساس سی و سی++ بوده و بازنگری و بازنویسی آنها مشروط بر این که رابطها باید بازنویسی شود بسیار سخت و کاری مشابه اختراع دوبارهٔ چرخ است. عملکرد تا حدی قابل پیشبینی است و میتواند آن را درک کرد، چیزی که در زبانهایی مانند جاوا، سیشارپ و گو نمیتواند پیشبینی کرد چرا که پیشبینی چرخهٔ GC دشوار است، هیچ رقیب جدیای در این باره در سطح سی++ وجود ندارد که مدیریت حافظه را برای شما در قالب یک RAII ارائه کند، هرچند در مورد Objective-C و Rust میتوان آنها را به صورت جداگانه مورد بررسی قرار داد و نه عین آن. پشتیبانی از پارادایم (سبک)های طراحی را سی++ به خوبی پشتیبانی میکند، برای مثال برنامهنویسی عمومی در زمان کامپایل را به خوبی ارائه میکند. پشتیبانی از برنامهنویسی سیستمی و سطح پایین در این زبان یک مزیتی دیگری است که در کنار تمامی ویژگیهای سطح بالای خود ارائه میکند. اما در این میان زبانهایی مثل Rust، Go، Swift و غیره ادعای جایگزینی را دارند اما ادعاهای فنی به تنهایی کافی نیستند، در دسترس بودن گسترده از جامعه به اندازهٔ کافی به همراه جامعهٔ معتمد به آن مهم است. علاوه بر ویژگیهای فنی زبان سی++، یک نقطه قوت بسیار مهم این زبان در بحث غیر فنی آن است، در واقع در پشت این زبان نه یک پیادهسازی محدودی وجود دارد و نه یک سازمان که در آینده در مورد آن تصمیم بگیرد و آن را کنترل کند. در حالی که تمامی زبانهای مطرح و ادعا کننده داخل یک چهارچوبی کنترل میشوند که به شدت آیندهٔ آنها را تیره و تار میکند. به طور کلی آزاد بودن یک ابزار و قدرت یک جامعه فارغ از جغرافیا، سازمان، نژاد و زبان یک قدرت بسیار خارقالعادهای را برای یک ابزار به ارمغان میآورد که به تنهایی بسیار اهمیت دارد. در این اواخر بسیاری از مهندسین به فکر بازنویسی بسیاری از موارد شدن و تحقیقات نشان میدهد ابزارهایی گرافیکی بسیار قدرتمند و سریع که اخیراً طراحی شدهاند، مانند وُلکان که با سی++ نوشته شده است زمانی میتوانند با راست و زبانهای دیگر امروزی بازنویسی شوند که یک سیستمعامل جدید با زبانهای جدید ساخته شود! بنابراین صرفاً میتوان یک نسخهٔ Wrapper یا همان (پوشنده) چرا که تقریباً همهٔ سیستمعاملهای مدرن امروزی با زبانهای سی و سی++ نوشته شدهاند. از طرفی تولید یک سیستمعامل بسیار پر خطر است و سرمایهگذاری کلان، زمان و هزینههای بسیاری را میطلبد و تا زمانی که چنین نرمافزارهایی تحت سلطهٔ زبانهایی مانند سی++ قرار گرفته باشند پادشاهی سیپلاسپلاس ادامه خواهد داشت. نکتهٔ پایانی من معتقدم هر ابزار و زبانهای برنامهنویسی جایگاه و شرایط استفادهٔ خودشان را شامل میشوند، دقیقاً مانند ابزارهای موجود در یک جعبهابزار بهتر است ابزارهای خود را طوری بچینید که در جای لازم از مناسبترین آنها استفاده کنید. با این حال زبانها و ابزارهای مانند سی یا سی++ طی سالها ثابت کردهاند که معمولاً در همهٔ حوزهها غالب هستند و میتواند هر کاری را که بخواهید با آنها انجام دهید و یا با یک جایگرین مناسب آن را مدیریت کنید و این بستگی به مهارت و انتخاب شخصی شما دارد. همچنین صحبتهای اخیر کمیتهٔ استانداردسازی در رابطه با نحو ۲ از سیپلاسپلاس میتواند مفهوم خوبی در آیندهٔ این زبان باشد. مقالات مرتبط با این موضوع که میتواند به عنوان مکملی از پیش تعریف شده برای شما مفید باشد:
-
2 امتیازمدتی است در مورد مسدود شدن اپلیکیشنهای ایرانی برای iOS از طرف شرکت اپل خبرهایی به گوش میرسد که در سایتها و پایگاههای خبری از سمت نویسندگان و افراد غیرفنی تجزیه تحلیل و روشهای دور زدن آنها ارائه میشود. واقعیت بر دلیل نوشتن این مقاله این است که این فرصت و مشکلات کنونی آبی گلآلود برای سودجویانی شده است که کاربران از آن بیخبرند! هر روز یک توسعهدهنده یک سایت جدید راهاندازی میکند و با ادعای ارائه بستری نامحدود اقدام به تبلیغات میکند. بنده نیز به عنوان توسعهدهنده وظیفهٔ خودم میدانم که یک بار برای همیشه توضیحات شفاف و روشنی را در اختیار کاربران iOS قرار دهم تا متوجه اصلِ موضوع باشند (بعد از آن تصمیم با خود شما)! اول از خودمان شروع کنیم، آیا واقعاً حرکتهایی که ما داشتهایم درست بوده است؟ به گونهای که انگار اقدامات ما ایرانیها بدون عیب و ایراد بوده و اپل بدون دلایل منطقی اقدام به تحریم ما کرده است! (هدف از این مقاله به هیچ عنوان طرفداری از اقدامات شرکت اپل نیست، چرا که این شرکت به عنوان فروشندهٔ محصولات خود وظیفه دارد به پشتیبانی و ارائهٔ خدمات به کاربرانش باشد نه اینکه هم سود کند و هم به خاطر مسائل سیاسی برخی از مشتریان خود را محدود کند. بنابراین ما اپل را هم محکوم به آن میکنیم که هیچ ارزشی به کاربران و توسعهدهندگان ایرانی به خاطر مسائل سیاسی قائل نیست)، و در مقابل مشترکین و حتی شرکتها و فروشگاههای اپلیکیشن موظف هستند به جای توجیح کارهای غیر قانونی و ناعادلانهٔ خود (و استفاده از چنین فرصتها)، اقدامات به شفاف سازی روشهای انتشار و توسعه کنند که مسلماً کاربران عادی و غیر حرفهای از این امر بی خبرند! به گونهای که انگار ما عادت کردهایم هر زمان که مشکلی گریبان گیر ملت ما میشود به جای حل آن از روش صحیح و قانونی، اقدام به فشار بیشتر و سوء استفاده از آن فرصت کنیم که اصلاً روش انسان دوستانهای نیست (حداقل از فرهنگ اصیل ایرانی چنین انتظاراتی نداریم). اما واقعیت امر در چیست و دلایل مسدود سازی نرمافزارها بر روی iOS در چیست؟ اینطور که به گوش میرسد و به گفتهٔ پایگاههای خبری و سایتهای فناوری خبرها اینگونه است که، اپل تا کنون چندین بار برخی اپلیکیشنهای ایرانی را مسدود یا رَد اعتبار کرده است ولی این بار، اپلیکیشنهای پرداخت الکترونیکی و موبایلی مانند آسان پرداخت و نرمافزار بانکهای معروف ایرانی تحریم شدند. افزون بر این، اپهای محبوب و پر کاربردی مانند اسنپ، تپسی، فونپی، دیجیکالا، فیدیبو، سیباپ نیز جزو تحریم شدهها هستند. در قدم اول ممکن است دلایل این کار را به خاطر مسائل سیاسی بدانیم، این مسئله تا حدی ممکن است درست باشد، اما با بازنگری و یادآوری حریم خصوصی و حقوق مشتری در جامعهٔ بشری از سمت اپل نیز حکم میکند که جوابگوی خدمات پس از فروش خودش باشد. بنابراین بهانه تراشی بخشی از اقدامات میتواند باشد اما مسئلهٔ اصلی این نیست! اجازه دهید جایگاه خودمان را برعکس در نظر بگیریم، با این حساب که ما به عنوان خدمات دهندههای ایرانی بستری را فراهم کرده باشیم که به جامعهٔ بزرگی از دنیا خدمات ارائه میدهیم. بنابراین قوانین و چهارچوبهای شفاف و مشخصی را عنوان خواهیم کرد که خارج از آن باید اقدام به یادآوری و گوشزد، تذکر و در نهایت برخورد قانونی و تحریم را در برنامه داشته باشیم که یک روند قانونی و طبیعی است. این قوانین در صورتی اجرا میشوند که حقوق توسعه، تولید، نشر و پشتیبانی رسمی محصولات نادیده گرفته شود. بنابراین فرض کنید شما صاحب فروشگاهی هستید که نویسندگان (توسعهدهندگان) و ارائهدهندگان خدمات آن همگی ساعتها، ماهها و سالها زمان بر توسعه و تولید محصولات خود گذاشتهاند. حال ممکن است آن را رایگان و یا حتی با دیدگاه تجاری در اختیار کاربران قرار دهند. بنابراین عقل و منطق اجازه میدهد که شما نرمافزار رایگان را به صورت رایگان و نرمافزارهای تجاری را در قبال پرداخت هزینهٔ آن مورد استفاده قرار دهید. در غیر این صورت اگر محصولی که شما ارائه دادهاید با نقض این موارد مواجه شود (بدون شک اولین تصمیمی که خواهید گرفت حذف خدمات پس از فروش، پشتیبانی و ... خواهد بود). اما واقعیت این مسئله چیست؟ آیا اپل اقدام به تحریم بی دلیل بر روی اپلیکیشنهای ایرانی داشته است؟ اگر منطقی به قضیه فکر کنیم، به راحتی میتوان این مسائل را بررسی و دلایل تحریم را درک کرد؛ من در این مقاله ابتدا به دلایل تحریم اپل میپردازم که پاسخ روشن و صریح این اقدامات اخیر را در این باره به شما خواهد داد. هرچند من به عنوان یک برنامهنویس باید به دنبال توسعه و تولید محصولات و حتی دور زدن تحریمهای ناشیانه در این حوزه باید باشم، اما اینکه هم نوعان و همکاران خودم هم در این باره خبرها و اطلاعات دروغ را به مشتریان این حوزه میدهند قابل تحمل نیست! چرا که اول باید از خودمان شروع کنیم! بهتر است در نظر داشته باشیم قوانینی که در اپل نیز ذکر شدهاند به این اشاره دارد که در صورت خروج از این چهارچوب که ممکن است امنیت و حقوق مادی و معنوی توسعهدهنده و ناشر را پایمال کند، هیچ گونه تعهدی در رابطه با ادامهٔ همکاری و یا پشتیبانی از آن خدمات را نخواهند داشت. بنابراین شخصاً ندیدم حتی در یکی از فروشگاههای ایرانی اشارهای به این حقوق شده باشه (حتی برعکس و شدیداً بر خلاف مواردی هستند که ذکر شدهاند که با دلیل و اسناد معتبر خود مرجع اپل آنها را شفاف سازی خواهم کرد). به عنوان مثال، اگر شما یک کاربر عادی یا حتی تازه کار باشید، یا اگر شما یک توسعهدهندهٔ تازهکار و حتی حرفهای باشید بهتر است به این بخش از قوانین اپل (App Store Review Guidelines) توجه جدی کنید! این بخشی از قوانین صریح و شفاف اپل در حوزهٔ اپلیکیشنهای iOS و فروشگاه خودش است که در زیر آمده است: App Store Review Guidelines Introduction Apps are changing the world, enriching people’s lives, and enabling developers like you to innovate like never before. As a result, the App Store has grown into an exciting and vibrant ecosystem for millions of developers and more than a billion users. Whether you are a first time developer or a large team of experienced programmers, we are excited that you are creating apps for the App Store and want to help you understand our guidelines so you can be confident your app will get through the review process quickly. The guiding principle of the App Store is simple - we want to provide a safe experience for users to get apps and a great opportunity for all developers to be successful. We do this by offering a highly curated App Store where every app is reviewed by experts and an editorial team helps users discover new apps every day. For everything else there is always the open Internet. If the App Store model and guidelines are not best for your app or business idea that’s okay, we provide Safari for a great web experience too. On the following pages you will find our latest guidelines arranged into five clear sections: Safety, Performance, Business, Design, and Legal. The App Store is always changing and improving to keep up with the needs of our customers and our products. Your apps should change and improve as well in order to stay on the App Store. A few other points to keep in mind: We have lots of kids downloading lots of apps. Parental controls work great to protect kids, but you have to do your part too. So know that we’re keeping an eye out for the kids. The App Store is a great way to reach hundreds of millions of people around the world. If you build an app that you just want to show to family and friends, the App Store isn’t the best way to do that. Consider using Xcode to install your app on a device for free or use Ad Hoc distribution available to Apple Developer Program members. If you’re just getting started, learn more about the Apple Developer Program. We strongly support all points of view being represented on the App Store, as long as the apps are respectful to users with differing opinions and the quality of the app experience is great. We will reject apps for any content or behavior that we believe is over the line. What line, you ask? Well, as a Supreme Court Justice once said, “I’ll know it when I see it”. And we think that you will also know it when you cross it. If you attempt to cheat the system (for example, by trying to trick the review process, steal user data, copy another developer’s work, manipulate ratings or App Store discovery) your apps will be removed from the store and you will be expelled from the Developer Program. You are responsible for making sure everything in your app complies with these guidelines, including ad networks, analytics services, and third-party SDKs, so review and choose them carefully. Some features and technologies that are not generally available to developers may be offered as an entitlement for limited use cases. For example, we offer entitlements for CarPlay Audio, HyperVisor, and Privileged File Operations. Review our documentation on developer.apple.com to learn more about entitlements. We hope these guidelines help you sail through the App Review process, and that approvals and rejections remain consistent across the board. This is a living document; new apps presenting new questions may result in new rules at any time. Perhaps your app will trigger this. We love this stuff too, and honor what you do. We’re really trying our best to create the best platform in the world for you to express your talents and make a living, too. در قوانین ذکر شده به صراحت عنوان شده است که اگر به فکر برنامههای آزمایشی هستید بهتر است از محیط Xcode با همان حساب توسعهدهندگی استفاده کنید که تنها بر روی دستگاه خودتان میتواند اجرا شود. در صورتی که به فکر بحث تجاری آن هستید باید تمامی حقوق مربوطه را رعایت کنید و حتی نباید به فکر کپی کردن، درز اطلاعات، به خطر اندازی حریم خصوصی و دیگر مسائل بپردازید که در این صورت اپل محصول شما را رَد خواهد کرد. فشار دو طرفه، بهانه تشدید بهانه... بهانه و باز هم بهانه!!! مسلماً برای همه روشن است که سیاستهای آمریکایی و شرکتهای آن منتظر بهانههایی هستند که سریعاً فشارها را به سمت ملت ایران وارد کنند، بنابراین مانند اقدامات اخیر Github که متأسفانه مجبور هستند بر اساس سیاستهای دولتی خود اقدام به محدود سازی خدمات خود به ایرانیها باشند (اپل بسیار مشتاقانهتر به دنبال بهانه و ایجاد فشار به ملت ما میشتابد). بنابراین باز هم یادآوری کنیم محصولی که بابت آن پول پرداخت میشود اعمال محدودیت و فشار بر آن دیگر جایز و انساندوستانه نیست! جالبتر از این موارد یادآوری این موضوع است که دوستان داخلی به جای حل مشکلات با فرصت طلبیها و سوء استفادهها و بیانصافیها هم فشار وارده را بر کاربران iOS بیشتر کردهاند و هم وضعیت و بهانههای بیشتری به دست شرکت اپل میدهند! این واقعیتی است که باید پذیرفت (به گونهای که در شرایط اقتصادی کنونی هم فشار از خارج هم داخل بر ملت ما وارد است). کاش منصفانه به فکر راه حلهای مشکلات کنونی باشیم... ملت ما در چنین شرایطی هر جا که به کمک هم شتاب کردهاند موفقتر بودهاند و خواهند بود (اما به روش درست نه غلط!!!). حال با در نظر گرفتن نقض قوانین صریح از سمت فروشگاههای ایرانی که به آن هم افتخار میکنند، آیا نباید انتظار داشت تا روزی اپل یا هر شرکت دیگری صبرش به پایان برسد و خیس و خُشک را باهم بسوزاند؟! بخشی از ادعاهایی که بزرگترین مرجع ایرانی (سیباپ) اپلیکیشنهای iOS ارائه شده است به صورت زیر میباشد: زمانی که دسترسی به هزاران اپلیکیشن خارجی با ارزش ۵۰،۰۰۰ دلار در کشور ما با افتخار حقوق توسعهدهنده و ناشر را زیر سوأل میبرد نباید انتظار داشت چنین تحریمهایی حق ماست؟ حال آنکه چنین فروشگاههایی جدیداً از محدودیتهای اخیر سوء استفاده کرده و حتی با وعدههای دروغین اقدام به فروش اشتراک ویژه میکنند که در ازای آن هیچ تضمینی از امنیت، حقوق مادی و معنوی و حتی اجرا شدن نرمافزارهای موجود در آن فروشگاه وجود ندارد! متأسفانه دروغها و فرصت طلبیها از چنین فرصتها به جای حل مسائل و اختلافهای سیاسی و تجاری چیزی به جز بدتر کردن وضعیت کنونی نخواهد داشت. حتی هیچ شانسی برای بهتر شدن وضعیت کنونی باقی نخواهد ماند. نقل قول زیر از طرف سیباپ است که ادعا کرده است با پرداخت اشتراک شما قادر به دانلود بدون مشکل اپلیکیشنها خواهید بود. راه حلهای ناشیانه و واقعا مسخره که از طرف فروشگاهها و نویسندگان خبری اخیر به دستمان رسیده است به صورت زیر هستند: استفاده از نسخه وب اپلیکیشن حقیقت نفهته در پشت این راه حلها به این صورت است که یک فناوری به عنوان PWA یا همان (Progressive web applications) وجود دارد که همان نسخهٔ وب به شمار میآید! در واقع اپلیکیشنهای نوشته شده به این روش بسیار بدتر از حتی یک وبسایت کامل هستند و تنها به روشهای غیر بومی و خارج از محیط Xcode تحت فناوریهای وب مانند HTML, CSS و JavaScript توسعه داده میشوند. در نهایت هیچ ربطی به نسخهٔ اصلی و نوشته شده به روش طبیعی نرمافزارهای iOS ندارد و تنها نسخهٔ محدود شدهای از وبسایت خدماتی است که با حقههای فریبنده و کاملاً ناشیانه اقدام به ساخت میانبر و ایجاد آیکون بر روی صفحه گوشی شما میکنند که اینطور برداشت کنید نسخهٔ واقعی اپلیکیشن را نصب کرده اید!!! در حالی که بهتر است به جای آن از همان وبسایت استفاده کنید. مسخره است نه؟! دسترسی به برنامههایی که پیشتر از اپ استور دانلود کردهاید دسترسی به برنامههایی که پیشتر از اپاستور دانلود شده است روشی کاملاً مسخرهتر است که به شما پیشنهاد میدهد تا نسخههای قدیمی اپلیکیشنهایی که اپل آنها را نگهداشته است اما توسعهدهندهگان آنها هم نمیتوانند آن را بهروز رسانی کنند استفاده کنید! این کار چه فایدهای دارد دقیقاً؟ تعداد اپلیکیشنهایی این چنینی بسیار محدود هستند مانند دیوار ... که آخرین بهروز رسانی آن به ۲ سال پیش مربوط است!!! جیلبریک کردن این روش ممکن است کارایی داشته باشد، اما تمامی مسائل امنیتی و خدماتی که اپل آنها را ارائه میکند را از بین برده و در واقع در این روش هیچ تضمینی برای حفظ اطلاعات و صحت عملکرد دستگاه شما وجود ندارد (در واقع شما از روش بسیار خطرناک از بین هزاران حفرههای شکافته شدهٔ امنیتی عبور کرده و از برنامهٔ مورد نظرتان که شاید آن یک اپلیکیشن بانکی و ... باشد استفاده میکنید). راه حل سیب اپ (بزرگترین فروشگاه ایرانی برای برنامه های iOS) این پیشنهاد زمانی معتبر است که فروشگاه و یا فروشگاههای مربوطه با شفافیت کامل بیان کنند که راهحلهای فعلی هیچکدام نهایی نیست و اصلاً مخصوص کاربر نیست!!! چرا که مشتری نه توسعهدهنده است و و نه شرکت! بنابراین زمانی که با حرکتهای ظاهراً حرفهای اما در حقیقاً کاملاً غیر حرفهای از هر کاربر یک توسعهدهنده یا شرکت و یا سازمان میسازند طبیعی است که باید هزینههایی مانند ۹۹ تا ۲۹۹ دلار در سال را بپردازند که مسلماً منجر به پولی شدن حق نصب اپلیکیشن خواهد بود که از بیخ غلط است! بنابراین انتظار میرود تحت هیچ شرایطی مردم را نَفَهم فرض نکنیم! مطمئنان هر عقل سلیمی میتواند تشخیص دهد که این روش دقیقاً همان مثال معروف (ماهی گرفتن از آب گلآلود است) در واقع شما باید پول به چیزی بپردازید که خودش روش غیرقانونی و نامناسب است!!! برخی از توسعهدهندگان و سایتهای خبری و حتی استورها چنین ادعا میکنند که هیچ محدودیتی در توسعه و انتشار برنامههای iOS وجود ندارد، آیا این حقیقت است؟ طبق توضیحاتی که در بالا اشاره کردم، هیچ روش منطقی در داخل کشور وجود ندارد که قانونی باشد، اگر کسی مدعی به انتشار است مطمئنان از همین روشهایی که اشاره شد استفاده میکند که خارج از این نیست. فروشگاههای جدید و مدعی بدون محدودیت چگونه کار میکنند؟ متأسفانه با وجود شرایط کنونی و محدودیتهای اپل افراد و فروشگاههای زیادی در چندین ماه اخیر ایجاد شدهاند که از این فرصت برای ارائه خدمات به شیوهٔ PWA و دو روش دیگر که ذکر شد استفاده میکنند که هیچ یک از آنها ارائه دهندهٔ خدمات واقعی نیستند. (اگر شما فروشگاهی را میشناسید که از روشهای قانونی برای نشر برنامهها استفاده میکند که نیاز نباشد هر چند وقت یک بار برنامه را حذف و دوباره نصب کنند و یا در بهترین حالت شما را به عنوان توسعهدهندهٔ اپل معرفی نکنند به ما معرفی کنید تا به گوش همگان برسانیم!). روشهای پیشنهادی و رسمی اپل چیست؟ طبق اسناد رسمی، اپل میگوید اگر شما برنامهٔ خودتان را به صورت استاندارد توسعه دادهاید میتوانید به دو روش آن را منتشر کنید؛ روش اول این است که آن را در فروشگاه اپل منتشر کنید (که در این روش بنابر اساس سیاستهایی که دارند مسلماً تحریم ما خواهد بود که شاهدش بودیم - حذف اپلیکیشنهای ایرانی از فروشگاه اپل). روش دوم آن است که شما اپلیکیشن خود را در قالب روشهای Ad-Hoc ایجاد کنید که محدود بر ۱۰۰ دستگاه (کاربر) خواهد بود. این روش نیز به گونهای قابل استفاده است اما محدود بر تعداد کاربران خواهد بود و برای اهداف داخلی و سازمانی خودمان طراحی شده است و بدون شک امضاء و مدیریت آن همراه با تولید آمار بسیار زیادی از تأییدیهها سرسام آور خواهد بود. درواقع اپل میگوید اگر میخواهید در دامنهٔ بزرگتر یعنی جهان، استفاده کنندهٔ اپلیکیشن شما باشد باید در فروشگاه من آن را منتشر کنید تا هم امنیت و هم پشتیبانی آن را تضمین کنم. روشهای دیگر نیز با عنوان (Enterprise Program) مطرح هستند که مخصوص تیمهای توسعهای که در برنامه Enterprise یا همان تجاری ثبت نام کردهاند نیز میتوانند از توزیع داخلی استفاده کنند. این روش همان روشی است که اپل برای عموم اکثراً محدود کرده است و مختص تحریمهای ایران نیست. درواقع همان روشی که بعضی از شرکتهای ایرانی هر روز میگویند اپلیکیشن را از لینک جدید دریافت کنید!!! که البته همراه با هزینهٔ سالانه ۲۹۹ دلار است! روشهای محدودتر دیگری وجود دارد که کاربران با محدودیت بیشتری با آن میتوانند برنامهها را صرفاً برای مصارف ازمایشی و خودمانی استفاده کنند که این دسته با عنوان University Program شناخته شده اند و توانایی نشر برنامه به جامعهٔ هدف بزرگتری را نخواهند داشت. با توجه به این تعاریف مشخص است که دو روش پیشفرض استاندارد و Ad-Hoc باقی مانده است. تکلیف روش اول مشخص است که تا زمانی که تحریمها وجود دارد نباید انتظار داشت که در اپاستور بتوان اپلیکیشنهای ایرانی را بارگذاری کرد. اما روش ادهاک همان روشی است که اجازه میدهد با خرید و ثبت دستگاه در بانک گواهیهای معتبر اپل اپلیکیشنهای خود را به مدت ۱ سال یا بیشتر امضا کنید (این روش برای توسعهدهندگان) پیشنهاد شده است که احتمالاً روشهای فعلی استورها این باشد! مسلماً این روش هزینهٔ شارژ و امضای توسعهدهنده را خواهد داشت. البته لازم به ذکر است این روش قطعی نیست و اگر اپل بداند که به زودی هم خواهد دانست میلیونها کاربر توسعهدهنده پیدا کرده است! مسلماً طی اقداماتی روشهایی برای حل آن ارائه خواهد داد. خب راه حل منطقی چیست؟ با توجه به مستندات و منابع رسمی که اعلام کردهاند، از اولین ساعتهای مسدود شدن نرمافزارهای بانکی و پرداختی، شرکتهایی که در این مجموعه اپ یا اپهایی داشتند؛ راهحل موقت خود را ارایه کردند، عمدهترین راهحل استفاده از اپهای مسدود شده روی گوشیهای آیفون، مراجعه به نسخه وب اپلیکیشن یا استفاده از پلتفرمهای دیگری مانند اندروید است. مدیران اسنپ و دیجیکالا از کاربرانشان درخواست کردند به طور موقت نسخه وب آنها را استفاده کنند تا مشکل حل شود. برخی شرکتها مانند سیباپ و تپسی، نسخه جدید و مجزایی از اپاستور ارایه داده و از کاربرانشان درخواست کردند این اپلیکیشن را از روی سایت آنها دریافت و نصب کنند. سیباپ در پیامهای ویدیویی و اطلاعیه رسمی، به کاربران خود وعده داده است بهزودی نسخه جدیدی از اپلیکیشن سیباپ ارایه خواهد شد که دیگر مشکل مسدود بودن یا عدم اعتبارسنجی توسط اپل را ندارد (که این روش زمانی قابل تأیید خواهد بود که به روشهایی غلطی که در بالا اشاره شد عمل نشود و رسالت و شعارهای فریبانهٔ خود را تغییر دهند) که مسلماً باید اول حقوق مادی و معنوی و حریم خصوصی مصرف کننده را تضمین کنند و در نهایت به روشهای قانونی مجوزهای لازم را از اپل دریافت کنند که با توجه به شرایط حاکم کمی غیر ممکن و دور از انتظار است!!! روشهای بهتری جهت نصب و راهاندازی اپلیکیشنهای ایرانی وجود دارد که با نامهای Add-Hoc نیز معروف هستند که محدود به نوع توسعهدهنده و تجاری معرفی میشوند. البته روشهای تجاری همان روشهایی است که سیباپ و دیگر شرکتها مورد استفاده قرار دادهاند. اما روش روش نوع توسعهدهنده میتواند با در نظر گرفتن ثبت دستگاه شما در پروفایل این مشکل را تا حدی برطرف کند که فروشگاههایی مانند اناردونی با در نظر گرفتن هزینهٔ ثبت دستگاه آن را تا به مدت ۱ سال تضمین میکنند. روش درست و صحیحتر آن است که دقیقاً طبق قوانین اپل عمل شود، در واقع تمامی مادهها و تبصرههای عنوان شده توسط شرکت اپل در اپاستور را باید پذیرفت. اما مشکل اصلی و اساس این مشکلات این است که اپل قبلاً هم گفته است حاضر به ارائهٔ خدمات به ایران نیست. (یاد شعار استیو جابز مرحوم افتادم که ما خواهیم گفت کاربر از چه چیزی باید استفاده کنند نه آنها) در واقع اپل با این اقدامات و فشارهای خود رسماً میگوید شما بهتر است از محصولات دیگر استفاده کنید که عمل زشت و بسیار نژادپرستانه است. آیا فروشگاههای داخلی به داد مردم میرسند یا از آب گلآلود ماهی میگیرند؟ قضیه این است!!! خوشبختانه در حالت عادی خدمات فروشگاههای داخلی خوب به نظر میرسد، اما وقتی به واقعیتهای آنها میپردازیم میبینیم که فرصتهای خوبی برای پول به جیب زدنهای خیلی خوشگل فراهم شده است که هرچند برای فراهم سازی بستر آن باید زحمت کشید و پول خرج کرد... اما در ازای چه خدماتی چه چیزی به دست میآورند؟ وقتی به خدماتی قرار است پولی پرداخت شود، آن سرویس باید بدون هیچ دغدغه و مشکلات مادی و معنوی قابل استفاده باشد. با توجه به عدم شفاف سازی کاربران که دلیل آن را نداشتن دانش فنی میدانند. از جانب بعضی از توسعهدهندگان و فروشگاههای ایرانی ترجیح دادهشده است که، خدمات ارائه شود اما با دریافت هزینه! کافی است یک حساب کتاب ساده انجام دهید، وقتی شما قرار است توسعهدهندهٔ اپل باشید باید هزینهٔ سالیانه آن را پرداخت کنید که چیزی حدود ۹۰ تا ۱۲۰ دلار بسته به مالیات متغیر است. و اگر قرار است امضاء از نوع سازمانی داشته باشید باید هزینهای معادل ۲۹۹ دلار برای آن بپردازید که در نهایت هر ۱۰ الی ۲۰ روز یک بار هزینه نزدیک به ۳ میلیون تومان برای خرید اکانت تجاری باید تقدیم کنید! در قبال آن به دست آوردن برخی از فروشگاهها مانند سیباپ هزینهی حداقل ۳۰،۰۰۰ تومان را بابت آن دریافت میکنند. به گفتهٔ خودشان تعداد کاربران میلیونی... با پرداخت چنین هزینههایی معادل صدها شاید هم هزاران و میلیونها برابر آن را به دست خواهند آورد!!! فرصت خوبی برای راهاندازی کسبوکار و به قول قدیمیها (ماهی گرفتن از آب گلآلود) است نه! البته فروشگاههایی هم وجود دارند که با روشهای PWA ادعای به اشتراک گذاری اپلیکیشنها را دارند که از اشاره به نسخه وب بودن و محدودیتهای آن دریغ میکنند. اخیراً هم که با حقهبازیهای هرچه تمام هزینههای چند برابری با وعدههای دروغین به مردم خدمات میدهند که شخصاً با خرید حساب ۱ ساله بعد از ۳ ماه دوباره از ما پول خواستن! حالا که در جریان واقعیت قرار گرفتهاید، بهتر است خودتان قضاوت کنید (چرا که به عنوان یک برنامهنویس این ننگ است که بدانیم اما به زبان نیاوریم که چه چیزی به خُرد ملت میدهیم). آیندهٔ نرمافزارهای iOS ایرانی چطور خواهد شد؟ شما کاربران عزیز باید در نظر داشته باشید که هیچ روش رسمی و قانونی به جز مواردی که اشاره شده است وجود ندارد، مشخص نیست با این وضعیت چه بلایی به بازار اپلیکیشنهای ایرانی در پلتفرم iOS خواهد آمد، اما با توجه به مسائل سیاسی که دولت ایالات متحدهٔ آمریکا اعمال کرده است و تمامی تحریمهای بانکی و ... از قبل گریبان گیر ما شده است کمی بعید است بدون حل مسائل سیاسی این دو کشور به این راحتی ها بتوان راه حلهای دائمی و مطمئن معرفی کرد. بنابراین، باید منتظر ماند تا دید آیا نظر اپل در این بهانه تراشیها تغییر خواهد کرد یا خیر! البته بر اساس نظرات کارشناسی برخی از حقوقدانها و سیاستمداران اینطور عنوان میشود که شرکتها بعضاً مجبور هستند بر خلاف میل خود طبق دستورات دولت خودشان اقدام کنند. در نهایت، باید منتظر ماند و دید که آیا حتی با پذیرفتن هزینههای بسیار بالا و رعایت قوانین کامل اپل باز هم اقدام به مسدود کردن برنامههای ایرانی خواهد کرد یا خیر. هدف از این مقاله این است که با چشمان باز حقیقت پنهاد در پشت این مسائل را بدانید.
-
2 امتیازمدتی قبل بود که من در رابطه با شاخصهای در حال رشد زبانهای برنامهنویسی در کانالهای شخصی نظری داده بودم که با توجه به وضعیت شاخص، زبان برنامهنویسی ++C سریعترین رشد را بعد از مدتها به خود اختصاص داده است. این تغییرات و بیداری زبان طبق انتظاری که داشتم بعد از ظاهر شدن زبان برنامهنویسی Rust در بین ۲۰ زبان برنامهنویسی برتر و همچنین نهایی شدن استانداردهای 2a و پیشرفتهای اخیر به خصوص رضایتبخشی کاربران از استاندارد 17 زبان ++C رخ داده است که دور از انتظار هم نبود. طبق شاخص محبوبیت طی چند سال گذشته، ++C با توجه به شاخص TIOBE در سپتامبر، سریعترین زبان در حال رشد در بسته برنامهنویسی است. این زبان در سالهای گذشته، محبوبیت سهم خود را در فراز و نشیبها داشته است. اما با مقیاسه با سالهای گذشته در حال حاضر رسماً سریعترین رشد را در بین تمامی زبانهای تحت پوشش اتوماسیون QA در شرکت Tobie را دارد. با این حال مدیرعامل Tobie جناب Paul Jansen گفته است، من فکر میکنم که استاندارد جدید سی++ یکی از دلایل این رشد اصلی باشد. به خصوص ویژگیهای جدید module که قرار است جایگزین مکانیزم وحشتاک قبلی شود. با این روند سی++ بیشترین رشدها که متعلق به #C با ۱.۱۸+ و R با ۱.۳۳+ را شکست میدهد.
-
2 امتیازهنگامیکه شما برای اولین بار از C به CPP مهاجرت می کنید، یا اصلا برنامه نویسی را قصد دارید با CPP شروع کنید، با مفاهیم متعددی روبرو خواهید شد که شاید برای شما جالب باشند که بدانید، این ایده ها چطور شکل گرفتند، چطور به CPP افزوده شدند و اهمیت آن ها در عمل (هنگام برنامه نویسی و توسعه نرم افزار) چیست. در این پست وبلاگی IOStream، به این خواهیم پرداخت که ایده Overloading و Template و Auto Deduction چطور از CPP سر در آوردند. همانطور که شما ممکن است تجربه کرده باشید، هنگامیکه برنامه نویسی و توسعه نرم افزاری را با C شروع می کنید، برنامه شما چیزی بیش از یک مجموعه بی انتها از توابع و استراکچرها و متغیرها و اشاره گرها و ... نخواهند بود. از همین روی شما مجبور هستید مبتنی بر ایده مهندسی نرم افزار و پارادیم برنامه نویسی ساخت یافته، برای هر کاری یک تابع منحصربفرد پیاده سازی کنید. این تابع باید از هر لحاظی از قبیل نام، نوع ورودی ها، نوع خروجی و حتی نوع عملکرد منحصربفرد باشد تا بتواند یک کار را به شکل صحیح کنترل کند که همین مسئله می تواند در پیاده سازی برخی نرم افزارها، انسان را در جهنم داغ و سوزان قرار بدهد. مثلا پیاده سازی یک برنامه محاسباتی مانند ماشین حساب که ممکن است با انواع داده های محاسباتی مانند عدد صحیح (Integer) و عدد اعشاری (Float) رو به رو شود. از همین روی فرض کنید، ما قرار است یک عمل محاسباتی مانند جمع از برنامه ماشین حساب را پیاده سازی کنیم. برای اینکه برنامه به شکل صحیحی کار کند، باید عمل جمع یا همان Add برای انواع داده های موجود از قبیل عدد صحیح و اعشاری پیاده سازی شود. اگر شما این کار را انجام ندهید، برنامه شما به شکل صحیحی کار نخواهد کرد (یعنی نتایج اشتباه ممکن است برای ما تولید کند). در تصویر زیر، نمونه این برنامه و توابع مرتبط با آن پیاده سازی شده است: #include <stdio.h> int AddInt(int arg_a, int arg_b) { return arg_a + arg_b; } float AddFloat(float arg_a, float arg_b) { return arg_a + arg_b; } double AddDouble(double arg_a, double arg_b) { return arg_a + arg_b; } int main(int argc, const char* argv[]) { int result_int = AddInt(1, 2); float result_float = AddFloat(10.02f, 21.23f); double result_double = AddDouble(9.0, 24.3); printf("Result Integer: %d", result_int); printf("Result Float: %f", result_float); printf("Result Double: %lf", result_double); return 0; } به برنامه بالا دقت کنید. ما سه تا تابع Add با نام های منحصربفرد داریم که سه نوع داده مجزا را به عنوان ورودی دریافت می کنند، سه نوع نتیجه مجزا بازگشت می دهند، اگرچه پیاده سازی آن ها کاملا مشابه هم دیگر است و تفاوتی در پیاده سازی این سه تابع وجود ندارد. ولی به هر صورت، اگر به خروجی دیزاسمبلی برنامه مشاهده کنید، دلیل این مسئله را متوجه خواهید شد که چرا هنگام برنامه نویسی با زبان C، به نام های منحصربفرد نیاز است، چون اگر توابع نام های مشابه با هم داشته باشند، لینکر نمی تواند به دلیل تداخل نام (Name Conflict)، آدرس آن ها را محاسبه یا اصطلاحا Resolve کند. همانطور که در تصویر بالا خروجی دیزاسمبلی برنامه Add را مشاهده می کنید، اگر توابع نام مشابه داشتند، در هنگام فراخوانی (Call) تابع Add تداخل رخ می داد، چون دینامیک لودر سیستم عامل دقیقا نمی داند که کدام تابع را باید فراخوانی کند. برای همین نیاز است وقتی برنامه نوشته می شود، نام توابع در سطح کدهای اسمبلی و ماشین منحصر بفرد باشد. به هر صورت، به نظر شما آیا راهی وجود دارد که ما پیاده سازی این نوع توابع را ساده تر کنیم یا حداقل بار نامگذاری آن ها را از روی دوش توسعه دهنده و برنامه نویس برداریم؟ بله امکان این کار وجود دارد. مهندسان CPP با افزودن ویژگی Overloading و Name Mangling یا همان بحث Decoration مشکل برنامه نویسان در پیاده سازی توابع با نام های منحصربفرد را حل کردند (البته کاربردهای دیگر هم دارد که فعلا برای بحث ما اهمیت ندارند). ویژگی اورلودینگ در CPP به ما اجازه خواهد داد یک تابع با عنوان Add پیاده سازی کنیم که تفاوت آن ها فقط در نوع ورودی و نوع خروجی است. به عنوان مثال، در قسمت زیر، کد برنامه Add را مشاهده می کنید که با قواعد CPP بازنویسی شده است. #include <iostream> int Add(int arg_a, int arg_b) { return arg_a + arg_b; } float Add(float arg_a, float arg_b) { return arg_a + arg_b; } double Add(double arg_a, double arg_b) { return arg_a + arg_b; } int main(int argc, const char* argv[]) { int result_int = Add(1, 2); float result_float = Add(10.02f, 21.23f); double result_double = Add(9.0, 24.3); std::cout << "Result Integer: " << result_int << std::endl; std::cout << "Result Float: " << result_float << std::endl; std::cout << "Result Double: " << result_double << std::endl; return 0; } همانطور که مشاهده می کنید، ما اکنون سه تابع با نام Add داریم. ولی شاید سوال پرسیده شود که چطور لینکر متوجه تفاوت این توابع با یکدیگر می شود درحالیکه هر سه دارای یک نام واحد هستند. اینجاست که مسئله Name Mangling یا همان Decoration نام آبجکت ها در CPP مطرح می شود. اگر شما برنامه مذکور را دیزاسمبل کنید، متوجه تفاوت کد منبع (Source-code) و کد ماشین/اسمبلی (Machine/Assembly-code) خواهید شد. همانطور که در خروجی دیزاسمبلی برنامه اکنون مشاهده می کنید، توابع اگرچه در سطح کد منبع دارای نام مشابه با یکدیگر بودند، اما بعد کامپایل نام آن ها به شکل بالا تبدیل می شود. به این شیوه نام گذاری Name Mangling یا Decoration گویند که قواعد خاصی در هر کامپایلر برای آن وجود دارد. این ویژگی موجب می شود در ادامه لینکر بتواند تمیز بین انواع توابع Add شود. به عنوان مثال، تابع نامگذاری شده با عنوان j__?Add@YAHH@Z تابعی است که به نوعی از تابع Add اشاره دارد که ورودی هایی از نوع عدد صحیح دریافت می کند. این شیوه نامگذاری خلاصه موجب خواهد شد لینکر بتواند به سادگی بین توابع تمایز قائل شود. با این حال هنوز یک مشکل باقی است، و آن هم تکرار مجدد یک پیاده سازی برای هر تابع است. به نظر شما آیا راهی وجود دارد که ما از پیاده سازی مجدد توابعی که ساختار مشابه برای انواع ورودی ها دارند، جلوگیری کنیم؟ باید بگوییم، بله. این امکان برای شما به عنوان توسعه دهنده CPP در نظر گرفته شده است. ویژگی که اکنون به عنوان Templateها در مباحث Metaprogramming یا Generic Programming استفاده می شود، ایجاد شده است تا این مشکل را اساساً برای ما رفع کند. با استفاده از این ویژگی کافی است، طرح یا الگوی یک تابع را پیاده سازی کنید، تا در ادامه خود کامپایلر مبتنی بر ورودی هایی که به الگو عبور می دهید، در Backend، یک نمونه تابع Overload شده مبتنی بر آن الگو برای نوع داده شما ایجاد کند. #include <iostream> template <typename Type> Type Add(Type arg_a, Type arg_b) { return arg_a + arg_b; } int main(int argc, const char* argv[]) { int result_int = Add(1, 2); float result_float = Add(10.02f, 21.23f); double result_double = Add(9.0, 24.3); std::cout << "Result Integer: " << result_int << std::endl; std::cout << "Result Float: " << result_float << std::endl; std::cout << "Result Double: " << result_double << std::endl; return 0; } به عنوان مثال، در بالا تابع Add را مشاهده می کنید که نوع داده ورودی این تابع و حتی نوع خروجی آن مشخص نشده است و در قالب Typename به کامپایلر معرفی شده است. این یک الگو برای تابع Add است. کامپایلر اکنون می تواند مبتنی بر ورودی هایی که به تابع هنگام فراخوانی یا اصطلاحا Initialization عبور می دهیم، یک نمونه تابع Overload شده از آن الگو ایجاد کند و در ادامه آن را برای استفاده در محیط Runtime فراخوانی کند. حال اگر برنامه بالا را دیزاسمبل کنید، مشاهده خواهید کرد که کامپایلر از همان قاعده Overloading استفاده کرده است تا نمونه ای از تابع Add متناسب با نوع ورودی هایش ایجاد کند. هنوز می توان برنامه نویسی با CPP را جذاب تر و البته ساده تر کرد، اما چطور؟ همانطور که در قطعه کد بالا مشاهده می کنید، هنوز ما باید خود تشخیص دهیم که نوع خروجی تابع قرار است به چه شکل باشد. این مورد خیلی مواقع مشکل ساز خواهد بود. برای حل این مسئله، در CPP مبحثی در نظر گرفته شده است که آن را به عنوان Auto Deduction می شناسیم که سطح هوشمندی کامپایلر CPP را بالاتر می برد. در این ویژگی خود کامپایلر است که مشخص می کند نوع یک متغیر مبتنی بر خروجی که به آن تخصیص داده می شود، چیست. به عنوان مثال، شما می توانید برنامه بالا را به شکل زیر بازنویسی کنید: #include <iostream> template <typename Type> auto Add(Type arg_a, Type arg_b) { return arg_a + arg_b; } int main(int argc, const char* argv[]) { auto result_int = Add(1, 2); auto result_float = Add(10.02f, 21.23f); auto result_double = Add(9.0, 24.3); std::cout << "Result Integer: " << result_int << std::endl; std::cout << "Result Float: " << result_float << std::endl; std::cout << "Result Double: " << result_double << std::endl; return 0; } با استفاده از ویژگی Auto Deduction و کلیدواژه Auto در برنامه، خود کامپایلر در ادامه مشخص خواهد کرد که تابع Add چه نوع خروجی دارد و همچنین نوع متغیرها برای ذخیره سازی خروجی Add چه باید باشد. به عبارتی اکنون تابع Add هم Value و هم Data type را مشخص می کند که این موجب می شود برنامه نویسی با CPP خیلی ساده تر از گذشته شود. حال اگر به نمونه برنامه آخر نگاه کنید و آن را با نمونه C مقایسه کنید، متوجه خواهید شد که CPP چقدر کار را برای ما ساده تر کرده است. در این پست به هر صورت، قصد داشتم به شما نشان دهم که نحوه تحول CPP به صورت گام به گام چطور بوده است و البته اینکه پشت هر ویژگی در CPP چه منطق کلی وجود دارد. امیدوارم این مقاله برای شما مفید بوده باشد. نمونه انگلیسی این مقاله را می توانید در این آدرس (لینک) مطالعه کنید. میلاد کهساری الهادی
-
2 امتیازخب ! Build System چیست ؟ تمام برنامههایی که مینویسیم، معمولاً یک main.c دارند که نقطهٔشروع (start point) برنامهٔما هست. آیا همیشه همین یک فایله ؟ آیا همیشه نیازه که به یکصورت برنامه را کامپایل کنیم ؟ خب مسلماً جواب "نه" هست. چرا که ممکنه برنامهٔ شما دارای دهها فایل داشتهباشه، و نیاز داشتهباشید که هر فایل رو به صورتخاصی با فلگهای خاصی کامپایلکنید. اینجاس که "بیلد سیستم"ها وارد کار میشوند. به احتمال زیاد نمونههای زیادی مشاهده کردید که وقتی یک سورسیرا (source) از مخازن آنلاین گیت، مثل گیتهاب یا گیتلب دریافت میکنید در فایل راهنما (README.md) در بخش Build نوشته که وارد دایرکتوری بشید و دستور make و بعد make install را وارد کنید، دقیقاً کاری که میکنید اینکه برنامهٔ GNU Make را صدا میزنید که فایل تنظیمات رو از دایرکتوری جاری بخواند و دستورات تعیین شده رو انجام بده، این دستورات در فایلی به نام Makefile نوشته میشود. نصب کردن GNU Make این برنامه معمولاً روی تمام سیستمعاملهای معقول مثل GNU/Linux یا اقوام BSD نصب هست، درصورتیکه نبود میتوانید با استفاده از مدیربستهٔ سیستمعاملتون اقدام به نصب کنید، مثلاً برای نصب روی سیستمعامل Debian - Ubuntu - Ubuntu Mint میتوانید به اینصورت عمل کنید : $> apt install make چه کنیم با GNU Make ؟ اوّل از همه باید یک برنامهای داشتهباشیم که بخوایم براش Build System تعیین کنیم و دستورات Makefileش رو بنویسیم. یک نمونهٔ ساده کد چند تکهای را میتوانید از اینقسمت دریافت کنید. ما سه فایل arg.c/arg.h و main.c را به اینصورت داریم (یک ساختار معقول) : . ├── build ├── obj └── src ├── arg.c ├── arg.h └── main.c خب حالا ما باید Makefile خودمان را داخل دایرکتوری ریشه درست کنیم، قبلاً هم گفتم : "برنامهٔ GNU Make به دنبال فایلی به اسم Makefile یا GNUmakefile یا makefile میگرده". در Makefile میتوانیمما قوانین (rule) برای ساخته شدن چیزی و متغیرهایی تعریف کنیم. اینجا من توضیحات خلاصهای را میگویم، باقیماندهٔ مطالب را باید از مستنداترسمی GNU Make یا راهنمای سریع دنبال کنید. هر قوانینای که تعریف میکنیم دارای این ساختار هست : نیازها : هدفها دستورات مثلاً ما میخواهیم که برنامهٔکامپایل شدهٔمان، با اسم args در دایرکتوری build/ قرار بگیره. اینجا "هدف"ما میشه build/args و نیازما هم فایلهای کامپایل شدهٔ arg.c و main.c هست. اوه ! یک هدف دیگههم پیدا شد؛ الآن هدف دوّمما فایلهای کامپایل شدهٔ obj/arg.o و obj/main.o هست و نیازمان هم سورسهای این فایلها یعنی src/arg.h و src/arg.c و src/main.c. خب خیلی زیاد شدن، بهتره که از آخر شروع کنیم و نیازهایمان را برطرف کنیم، اوّلین نیاز فایلهای کامپایلشده هستن : obj/main.o obj/arg.o : src/main.c src/arg.c src/arg.h gcc -c -o obj/main.o src/main.c gcc -c -o obj/arg.o src/arg.o * نکته : سعی نکنید دستورات Makefile را از منطقهٔ کد کپی نکنید، کمی تلاش کنید و بنویسید. خب قبول دارم خیلی زیاد و زشت شد، بیاید این قانون (rule) را به دو تیکه قسمت کنیم : obj/arg.o : src/arg.c src/arg.h gcc -c -o obj/arg.o src/arg.c obj/main.o : src/main.c gcc -c -o obj/main.o src/main.c اگر تا انتها متن ادامه بدید حتماً کوتاهترم خواهد شد :). خب؛ object fileها یا همان فایلهای کامپایل شدهیمان را به دستآوردیم. حالا باید قانون (rule) نیاز اوّلمان را بنویسیم، چه چیزی نیاز داشتیم ؟ فایل کامپایل شدهٔ build/args که نیاز به object fileها داشت، حالا object fileها را داریم و باید نیاز هدفمان را برطرف کنیم : build/args : obj/main.o obj/arg.o gcc -o build/args obj/main.o obj/arg.o obj/arg.o : src/arg.c src/arg.h gcc -c -o obj/arg.o src/arg.c obj/main.o : src/main.c gcc -c -o obj/main.o src/main.c تمام شد. ما دستورات Build System خودمان را به زبان برنامهٔ GNU Make نوشتیم؛ حالا کافیه که فقط وارد دایرکتوریای که فایل Makefile هست بشیم و از ترمینال برنامهٔ make را فراخوانی کنیم : $> make gcc -c -o obj/main.o src/main.c gcc -c -o obj/arg.o src/arg.c gcc -o build/args obj/main.o obj/arg.o حالا میتوانیم برنامهٔ خودمان را اجرا کنیم : $> build/args -name Ghasem -family Ramezani Input Name is [Ghasem] Input Family is [Ramezani] دقّت کرده باشید ما توی نوشتن Makefileمان نیازمندیهارو یکی بالاتر از دیگری نوشتیم. چرا ؟ به خاطر اینکه GNU Make میاد از اوّل فایل شروع میکنه و قوانین (rules)ها را اجرا میکنه. بزارید با یک مثال نشان بدم. Makefile زیر را مدنظرتون داشتهباشید : obj/arg.o : src/arg.c src/arg.h gcc -c -o obj/arg.o src/arg.c obj/main.o : src/main.c gcc -c -o obj/main.o src/main.c build/args : obj/main.o obj/arg.o gcc -o build/args obj/main.o obj/arg.o ما نیاز اصلی خودمان را آخرین قانون (rule) نوشتیم. حالا برنامهٔ make را اجرا میکنیم تا رفتارَش را بهتر متوجه بشیم : $> make gcc -c -o obj/arg.o src/arg.c دیدید ؟ خیلی ساده برخورد کرد، اوّلین قانون (rule) را نگاه کرد تنها نیازمندیش فایلهای src/arg.c و src/arg.v بودن که وابسته به چیزی نبودند و هدفشان را تأمین کردند. اگر بخواهیم باقی قوانین (rules) را فراخوانی کنیم، باید صراحتاً مشخص کنیم : $> make obj/main.o gcc -c -o obj/main.o src/main.c $> make build/args gcc -o build/args obj/main.o obj/arg.o خب دیگه امیدوارم دلیل اینکهما نیازمندی اصلیه خودمان را اوّلین قانون (rule) قرار دادیم را متوجه شده باشید. وقتی make به نیازمندیه obj/arg.o و obj/main.o برای تأمین build/args برمیخوره ادامهٔ قوانین را پیمایش میکنه تا نیازمندیها را برطرف کنه. (اگر گیج شدید احتمالاً، پیشنهاد میکنم همین موارد را روی کاغذ کشیده و قسمت : نیازمندیها و هدفها و دستورات هر قانون را مشخص کنید.) میتوانیم قوانینی (rules) تعریف کنیم برای کارهای خاصی، مثلاً همان make install، یعنی قانون install را فراخوانی کن؛ حالا ما قانون clean را برای حذف کردن فایلهای کامپایلشده مینویسیم : clean : yes | rm -vf build/* obj/* البته باید در اینجا نکتهای را هم حواسمان باشد، باید به GNU Make بگوییم که قانون clean ، یک قانون الکیهست، و با یک "هدف" اشتباه نشود. به اینصورت قانون را ویرایش میکنیم : .PHONY : clean clean : yes | rm -vf build/* obj/* نگرانیای هم دربارهٔ Wildcard ها نداشتهباشید، GNU Make دستتون را باز گذاشته :). متغیرها در GNU Make مسلماً هرجا سخنی از متغیراست، سر و کلهٔ راحتیکار (و تا حدودی پیچیدگی) پیدا میشود. ما میتوانیم متغیرهم داخل Makefile خودمان داشتهباشیم. مثلاً فرض کنید که نیاز دارید تمام سورسکدها با کامپایل clang و سطحبهینهسازیه 3 کامپایل بشند. نیازی نیستکه هربار اینارو تایپ کنیم. کافیه براشون متغیرتعریف کنیم : CC = clang OP = -O3 OBJECT = obj/main.o obj/arg.o ARGS = src/arg.c src/arg.h build/args : $(OBJECT) $(CC) $(OP) -o build/args $(OBJECT) obj/arg.o : $(ARGS) $(CC) $(OP) -c -o obj/arg.o src/arg.c obj/main.o : src/main.c $(CC) $(OP) -c -o obj/main.o src/main.c clean : yes | rm -vf build/* obj/* متغیرهای به خصوصی نیز در GNU Make تعریف شدهاند که میتوانند کار مارا بسیار راحتتر کنند، برای مثال میتوانیم قانون object fileها را به اینصورت بازنویسی کنیم : obj/%.o : src/%.c $(CC) $(OP) -c -o $@ $? برای اطلاعات بیشتر به راهنمایسریع GNU Make مراجعه کنید. یادداشتها یا Code Comments برای استفاده از قابلیت Comment گذاری در کد، کافیه که اوّل خط خودتون از کاراکتر # استفاده کنید. خب دوستان، سعی کردم کلیّات مبحث را بگم؛ ابزار Make قابلیتهای بسیار زیادی داره که حتماً باید خودتون مطالعه کنید. مثلاً خواستید Makefile شما یک Makefile دیگه را صدا بزنه، یا حتیٰ دستورات شرطی اجرا بکند و یا از همه مهمتر بر اساس معماری پلتفرم شما عملیات کامپایل را انجام بده و ... . - موفقوپیروز باشید. ?
-
1 امتیازسادهترین راه برای افزودن کد سفارشی به سایتهایی که بر پایهٔ وردپرس ساخته شدهاند، بدون شکستن کد آن چیست؟ زبان برنامهنویسیِ ++C یکی از محبوبترین زبانهای برنامهنویسی است. آخرین آمار نشان میدهد که این زبان با سرعت بسیار زیادی در حال توسعه و پوستاندازی است. این زبان، علیرغم اینکه بیش از 40 سال از عمرش میگذرد، همچنان زبان انتخابی برای بسیاری از برنامهنویسان در سراسر جهان است. برای بسیاری از موارد مانند برنامههای کاربردی دستکاری تصویر، بازیهای سه بعدی، شبیه سازیها، مرورگرهای وب و نرمافزارهای سازمانی استفاده میشود. دلیلش این است که سیپلاسپلاس در حال تکامل است، به انرژی سبز اهمیت میدهد و در عین حال کارآیی بسیار بالا و بهینهای دارد. از آنجایی که این زبان پیچیدهتر از سایر زبانهای برنامهنویسی است، یک کمیتهٔ فرعی از یک سازمان چند سطحی وظیفه استانداردسازی آن را بر عهده دارد. سیپلاسپلاس اکنون از یک مدل قطار پیروی میکند و هر سه سال یکبار نسخههای جدید دریافت میکند که در مورد استانداردهای جدید، اخیراً مقالاتی منتشر شده است. سیپلاسپلاس معمولاً برای توسعهٔ نرمافزار در مقیاس بزرگ استفاده میشود، اما میتوان از آن برای پروژههای توسعه وب نیز استفاده کرد. ممکن است تعجب کنید که چگونه از آن با وردپرس، یکی از محبوبترین سیستمهای مدیریت محتوا و سازندگان وب سایت امروزه استفاده کنید. در این باره قبلاً من مقالاتی را منتشر کردهام که به صورت زیر آمدهاند: در حالی که بسیاری از وب سایتها با استفاده از وردپرس به عنوان پایه ساخته میشوند، این لزوماً به این معنی نیست که اکوسیستم وردپرس تکامل یافته یا کامل است. به عنوان مثال، وردپرس تمرکز زیادی بر تجربهکاربران و نیازهای وبلاگ نویسان دارد، به همین دلیل است که بر چهار زبان HTML، CSS، جاوا اسکریپت و PHP متکی است و این بدان معناست که برای توسعهدهندگانی که میخواهند به طور کامل از قدرت آن استفاده کنند، محدودیتهایی وجود دارد. در حالی که افزونههایی مانند Custom Post Types برای گسترش عملکرد وردپرس وجود دارد و راههای زیادی برای افزودن قابلیتهای جدید بدون شروع از ابتدا وجود ندارد. همچنین، افزودن کد ++C به طور مستقیم به یک سایت وردپرس توصیه نمیشود زیرا به طور بالقوه میتواند آسیب پذیریهای امنیتی را ایجاد کند و وب سایت را خراب کند. با این حال، اگر نیاز خاصی به اجرای کد ++C در سایت وردپرس شما وجود دارد، در اینجا روشهایی که میتوانید آن را انجام دهید گفته شدهاست: شما می توانید یک برنامه یا کتابخانه مستقل ++C ایجاد کنید و سپس آن را از طریق وب API در معرض دید قرار دهید، که میتواند توسط وردپرس مصرف شود. بیایید نگاهی به مراحل کلی بیندازیم: کد ++C خود را بنویسید و آن را در یک برنامه یا کتابخانه مستقل کامپایل کنید. عملکرد برنامه یا کتابخانه ++C را از طریق وب API به نمایش بگذارید. شما میتوانید از یک کتابخانه به عنوان cpprestsdk برای ایجاد نقاط پایانی API استفاده کنید. برنامه یا کتابخانه ++C را بر روی یک سرور، یا در همان سرور سایت وردپرس خود یا در یک سرور جداگانه، مستقر کنید. در سایت وردپرس خود، از یک افزونه یا کد سفارشی برای درخواست HTTP به API و بازیابی نتایج استفاده کنید. شما میتوانید از کتابخانهای مانند cURL برای ارائه چنین درخواستهایی استفاده کنید. در صورت نیاز از نتایج بازیابی شده در سایت وردپرس خود استفاده کنید. راه دیگر برای افزودن قابلیت ++C به سایت وردپرس استفاده از افزونهای است که به شما امکان میدهد کد ++C را مستقیماً در صفحات یا پستهای وردپرس جاسازی کنید. مراحل بسته به افزونهای که استفاده میکنید متفاوت است، اما در اینجا چند مرحله کلی وجود دارد که میتواند کمک کند. افزونهای را که از کد ++C پشتیبانی میکند را در سایت وردپرس خود نصب کنید. یک صفحه یا پست جدید در وردپرس ایجاد کنید و کد کوتاه [cpp] را به قسمت محتوا اضافه کنید. در کد از نوع برچسبِ [cpp]، کد ++C خود را اضافه کنید. صفحه یا پست را منتشر کنید و آن را مشاهده کنید تا کد جاسازی شده ++C را در عمل ببینید. مجدداً توجه داشته باشید که افزودن کد ++C به طور مستقیم به یک صفحه یا پست میتواند خطرناک باشد. مهم است که پیادهسازی خود را به طور کامل آزمایش کنید تا مطمئن شوید که ایمن و قابل اعتماد است. از هر روشی که استفاده میکنید، به یک پایه محکم در سیپلاسپلاس و مهارتهای یکپارچه سازی وردپرس نیاز دارد. وقتی صحبت از وردپرس به میان میآید، شاید بهتر باشد از زبانی مانند PHP استفاده کنید. اگر میخواهید دربارهٔ ++C و نحوهٔ به حداکثر رساندن آن برای پروژهتان بیشتر بدانید، میتوانید به آموزههای مربوط به سیپلاسپلاس در این سایت را بررسی کنید یا کتابهای پیشنهادی در بخش معرفی زبان را بخوانید. فراموش نکنید که سیپلاسپلاس یک زبان جذاب و همیشه در حال تکامل است و افزودن آن به مجموعه مهارتهای شما سودمند است.
-
1 امتیازبا سلام، با توجه به گزارش آنتونی پولوخین که یکی از اعضای کمیتهٔ استانداردسازی WG21 (سازمانی که توسعهٔ زبان برنامهنویسی سیپلاسپلاس را کنترل میکند). این کمیته سه بار در هر سال، هر بار در یک شهر جدید در سراسر جهان جلسه برگزار میکند. در طول این جلسات، پیشنهاداتی برای تغییر در زبان در نظر گرفته میشود. همچنین به توسعهدهندههای محلی سی++ کمک میکنند تا پیشنهادات خود را ارائه کنند. خلاصهای از جلسهٔ ماه جولای با هدف نهایی شدن استاندارد ۲۳ که نشان میهد پیشرفت بزرگی به عنوان ویژگیهای جدید استاندارد ۲۳ وجود دارد ارائه شده است: فهرست برخی از ویژگیها به صورت زیر آمدهاست: std:mdspan std:flat_map std:flat_set freestanding std:print("Hello {}", "world") formatted ranges output constexpr for bitset, to_chars/from_chars std::string::substr() && import std; std::start_lifetime_as static operator() [[assume(x > 0)]] 16- and 128-bit floats std::generator و البته ویژگیهای بسیار بیشتر از این. ویژگی std::mdspan از زمان اتخاذ عملگر opertator[] چند بعدی در آخرین جلسه، معرفیstd::mdspan به عنوان یک ویژگی سادهتر مطرح شده است و نتیجهٔ یک آرایهٔ چند بعدی غیر مالک به صورت زیر است: using Extents = std::extents<std::size_t, 42,="" 32,="" 64="">; double buffer[ Extents::static_extent(0) * Extents::static_extent(1) * Extents::static_extent(2) ]; std::mdspan<double, Extents=""> A{ buffer }; assert( 3 == A.rank() ); assert( 42 == A.extent(0) ); assert( 32 == A.extent(1) ); assert( 64 == A.extent(2) ); assert( A.size() == A.extent(0) * A.extent(1) * A.extent(2) ); assert( &A(0,0,0) == buffer ); این ویژگی حتی میتواند با سایر زبانهای برنامهنویسی خارج از جعبه کار کند. به عنوان مثال، در پارامتر الگوی سوم خود، std::mdspan میتواند یکی از چندین کلاس طرح بندی از پیش تعریف شده را بگیرد: نوعstd::layout_right: سبک چیدمان برای C یا ++C، سطرها دارای شاخص صفر هستند. نوعstd::layout_left: سبک چیدمان برای Fortran یا Matlab، ستونها دارای شاخص صفر هستند. شما می توانید تمام جزئیات را در سند P0009 بیابید. نویسندگان قول دادهاند که در آینده نزدیک نمونههای زیادی از std:mdspan جدید ارائه کنند. ویژگی std::flat_map و std::flat_set نگهدارندههای شگفتانگیز flat_* از کتابخانهٔ بوست، دیگر در استاندارد اصلی سی++ در دسترس هستند. این خاصیتها در کار با دادههای کم بسیار پرکاربرد هستند. در زیر ساختها، ظروف flat دادهها را در یک آرایه مرتب شده ذخیرهسازی میکنند که به طور قابل توجهی تخصیص حافظهٔ پویا را کاهش داده و موقعیت دادهها را بهبود میبخشد. علیرغم پیچیدگی جستجوی O(log N) و پیچیدگی درجO(N) در بدترین حالت، ظروف مسطح هنگام کار با مقدار کمی از عناصر بهتر از std:unordered_map عمل میکنند. در واقع، در طی فرآیند استانداردسازی، ظروف flat_* به عنوان آداپتور ساخته شدهاند. به این ترتیب، برنامهنویسان میتوانند از نگهدارندههای خود برای پیادهسازی اساسی استفاده کنند: template <std::size_t N> using MyMap = std::flat_map< std::string, int, std::less<>, mylib::stack_vector<std::string, N>, mylib::stack_vector<int, N> >; static MyMap<3> kCoolestyMapping = { {"C", -200}, {"userver", -273}, {"C++", -273}, }; assert( kCoolestyMapping["userver"] == -273 ); const auto& keys = kCoolestyMapping.keys(); // Inspired by Python :) assert( keys.back() == "userver" ); یک نکتهٔ جالب این است که استاندارد STL برخلاف پیادهسازی Boost، کلیدها و مقادیر را در نگهدارندهها جداگانه ذخیره میکند. این مکانِ کلیدیِ بهبود یافته، جستجوی ظرفِ flat را سریعتر میکند. رابط کاملstd::flat_set در سند P1222 توضیح داده شده است، در حالی که شرح رابط std:flat_map در سند P0429 موجود است. مستقل (Freestanding) استاندارد ++C میگوید که امکان پیادهسازی کتابخانهٔ استاندارد به صورت میزبان (hosted) یا مستقل (freestanding) وجود دارد. پیادهسازی میزبان نیاز به پشتیبانی سیستمعامل دارد و باید تمام روشها و کلاسها را از کتابخانهٔ استاندارد پیادهسازی کند. مستقل (freestanding) میتواند بدون سیستمعامل کار کند، سختافزار مهم نیست، و برخی از کلاسها و توابع را شامل نمیشود. تا همین اواخر، هیچ توضیحی برای ایستادن آزاد وجود نداشت و سازندگان سختافزارهای مختلف بخشهای مختلفی از کتابخانهٔ استاندارد را ارائه میکردند. این کارِ پورت کردن کد را سختتر کرد و محبوبیت ++C را در محیطهای تعبیهشده (امبدها) تضعیف کرد. بنابراین، زمان تغییر آن فرا رسیده است! سند P1642 مشخص کرده است که کدام بخش از کتابخانهٔ استاندارد برای freestanding اجباری است. ویژگی std::print روشهایی از کتابخانهء محبوب fmt در C++20 اضافه شد. این کتابخانه آنقدر راحت و سریع بود که برنامهنویسان شروع به استفاده از آن کرده و تقریباً در همهجای کد خود به کار بردهاند، از جمله برای خروجی قالببندی شده: std::cout << std::format(“Hello, {}! You have {} mails”, username, email_count); اما کدی مانند آن به دلایل زیر کامل نیست: تخصیص پویا اضافی. نیاز به std::cout جهت قالببندی خطوط از قبل قالب بندی شده. عدم پشتیبانی از یونیکد. کدی که اندازهٔ فایل باینری حاصل را افزایش میدهد. ظاهری نه چندان جذاب. بنابراین، تمام این مشکلات با اضافه کردن متدهایstd::print حل شد: std::print(“سلام, {}! به جامعهٔ {} خوش آمدید!”, name, community); میتوانید جزئیات، معیارها و گزینههای استفاده ازstd::print باFILE* و استریمها را در سند P2093 بیابید. خروجی قالببندی شده محدودههای مقدار به لطف سند P2286 و، std::format (و std::print) اکنون میتوانند محدودههایی از مقادیر را بدون در نظر گرفتن اینکه در یک ظرف هستند یا توسط std::ranges::views::* ارائه شدهاند خروجی بگیرند. std::print("{}", std::vector<int>{1, 2, 3}); // Output: [1, 2, 3] std::print("{}", std::set<int>{1, 2, 3}); // Output: {1, 2, 3} std::print("{}", std::pair{42, 16}); // Output: (42, 16) std::vector v1 = {1, 2}; std::vector v2 = {'a', 'b', 'c'}; auto val = std::format("{}", std::views::zip(v1, v2)); // [(1, 'a'), (2, 'b')] ویژگی constexpr اخبار تجزیه و تحلیل عالی برای توسعهدهندگانی که با کتابخانههای مختلف کار میکنند وجود دارد: خاصیتهایstd::to_chars/std::from_chars اکنون میتوانند در مرحله کامپایل برای تبدیل مقادیر صحیح از متن به باینری استفاده شوند. این نیز باید هنگام توسعه DSL مفید باشد. به نظر میرسد توسعهدهندههای روسی Yandex Go (به نقل از عضو کمیته) قصد دارند از آن در چارچوب کاربر برای بررسی پرس و جوهای SQL در مرحله کامپایل استفاده کنند. گزینهٔ std::bitset نیز تبدیل به constexpr شده است، بنابراین کار با بیتها در مرحلهٔ کامپایل اکنون بسیار آسانتر از قبل است. دانیل گوچاروف روی std::bitset در سند P2417 کار کرد و الکساندر کارائف در سند std::to_chars/std::from_chars P2291 به او پیوست. با تشکر فراوان از آنها برای این کار خوب انجام شده! ویژگی import std; با توجه به اینکه، اولین ماژول کامل(تمامعیار) به کتابخانهٔ استاندارد (STL) اضافه شد. اکنون میتوان کل کتابخانه را با یک خط بر سند وارد کرد: import std;. اگر کل ماژول کتابخانهٔ استاندارد به جای گنجاندن فایلهای هدر وارد شود، ساختها میتوانند تا ۱۱ برابر (گاهی اوقات حتی ۴۰ بار!) سریعتر شوند. میتوانید بنچمارک ها را در P2412 مشاهده کنید. اگر به ترکیب ++C و C و همچنین استفاده از توابع C از فضای نام جهانی عادت دارید، ماژول std.compat برای شما مناسب است. وارد کردن آن همهٔ توابع فایلهای سرآیند C مانند ::fopen و ::isblank و همچنین محتویات کتابخانهٔ استاندارد را در اختیار شما قرار میدهد. با وجود همهٔ اینها، سند P2465 که ماژولهای جدید را پوشش میدهد، در واقع آنقدرها هم طولانی نیست. ویژگی std::start_lifetime_as تیمور داملر و ریچارد اسمیت یک هدیهٔ فوقالعاده برای همهٔ توسعهدهندگانی که روی برنامههای تعبیه شده (امبد) و پربار کار میکنند گرد هم آوردهاند. اکنون تنها چیزی که برای کار کردن همه چیز نیاز دارید این است: struct ProtocolHeader { unsigned char version; unsigned char msg_type; unsigned char chunks_count; }; void ReceiveData(std::span<std::byte> data_from_net) { if (data_from_net.size() < sizeof(ProtocolHeader)) throw SomeException(); const auto* header = std::start_lifetime_as<ProtocolHeader>( data_from_net.data() ); switch (header->type) {> // ... } } به عبارت دیگر، میتوانید بافرهای مختلف را به ساختارها تبدیل کنید و با آنها بدون reinterpret_cast، کپی کردن دادهها یا خطر عملکرد برنامهتان کار کنید. همه چیز در سند P2590 شرح و مستند شده است. ویژگیهای شناورهای (اعشاری) 16 و 128 بیتی استاندارد ++C اکنون شامل std::float16_t، std::bfloat16_t، std::float128_t و نام مستعار برای اعداد موجود با ممیز شناور است: std::float32_t، std::float16_t. شناورهای 16 بیتی در هنگام کار با کارتهای ویدئویی یا یادگیری ماشین کمک میکنند. به عنوان مثال، float16.h میتواند از انواع جدید شناور کوتاه بهرهمند شود. شناورهای 128 بیتی برای محاسبات علمی شامل اعداد بزرگ بهترین هستند. سندِ P1467 ماکروها را برای بررسی پشتیبانی کامپایلر برای اعداد جدید توصیف میکند، و حتی خاصیتِ stdfloat.properties، در جدول مقایسه با توصیف اندازههای مانتیس و توان در بیتها وجود دارد. ویژگی std::generator زمانی که کروتینها در استاندارد C++20 پذیرفته شدند، ایده این بود که میتوان از آنها برای ایجاد «مولد» استفاده کرد: توابعی که وضعیت خود را بین تماسها به خاطر میآورد و مقادیر جدید را بر اساس آن حالت برمیگرداند. در استاندارد C++23 با اشاره به، std::generator به عنوان یک کلاس جدید یاد میشود که به شما امکان میدهد به راحتی ژنراتورهای خود را ایجاد کنید: std::generator<int> fib() { auto a = 0, b = 1; while (true) { co_yield std::exchange(a, std::exchange(b, a + b)); } } int answer_to_the_universe() { auto rng = fib() | std::views::drop(6) | std::views::take(3); return std::ranges::fold_left(std::move(rng), 0, std::plus{}); } در مثال فوق میتوانید ببینید که ژنراتورها با std::ranges چقدر خوب کار میکنند. std::generator کارآمد و ایمن است. کدی که به نظر میرسد یک پیوند معلق ایجاد میکند در واقع کاملاً معتبر است و هیچ مشکلی ایجاد نمیکند: std::generator<const std::string&=""> greeter() { std::size_t i = 0; while (true) { co_await promise::yield_value("hello" + std::to_string(++i)); // Everything is ok! } } میتوانید مثالها و توضیحاتی دربارهٔ نحوه کارکرد و استدلال پشت این رابط را در سند P2502 بیابید. سورپرایزهای دلپذیر کلاس string استاندارد برای متد substr() برای ارجاعات rvalue یک بازنگری اساسی (بهبود) دریافت کرده است: std::string::substr() &&. مانند مثال زیر: std::string StripSchema(std::string url) { if (url.starts_with("http://")) return std::move(url).substr(5); if (url.starts_with("https://")) return std::move(url).substr(6); return url; } این روش اکنون بدون تخصیص پویا اضافی کار میکند. اطلاعات بیشتر را میتوانید در سند P2438 بیابید. به لطف سند P1169، اکنون میتوانیدoperator() را ثابت اعلام کنید، که برای ایجاد CPO برای محدودهها در کتابخانه استاندارد عالی است: namespace detail { struct begin_cpo { template <typename T> requires is_array_v<remove_reference_t<T>> || member_begin<T> || adl_begin<T> static auto operator()(T&& val); }; void begin() = delete; // poison pill } // namespace detail namespace ranges { inline constexpr detail::begin_cpo begin{}; // ranges::begin(container) } // namespace ranges علاوه بر std::start_lifetime_as، تیمور داملر یک راهنمایی عالی برای بهینهساز ارائه کرد[[assume (x > 0)]]. اکنون میتوانید در مورد مقادیر احتمالی اعداد و سایر متغیرهای ثابت به کامپایلر نکاتی بدهید. برخی از مثالها و معیارها در سند P1774 کاهش پنج برابری در تعداد دستورالعملهای اسمبلی را نشان میدهند. این استاندارد همچنین دارای بسیاری از ویرایشهای جزئی، رفع اشکال و پیشرفتها بوده است، در اینجا منظور استاندارد ۲۳ است. در برخی مکانها، از سازندههای حرکتی (move constructors) به جای سازندههای کپی (copy constructors) استفاده شد (P2266). خوشبختانه برای توسعهدهندگان درایور، برخی از عملیات فرار دیگر منسوخ نمیشوند (P2327 با رفع اشکال در C++20). عملگر<=> کدهای قدیمی را کمتر میشکند (P2468)، کاراکترهای یونیکد اکنون میتوانند با نام استفاده شوند (P2071)، و کامپایلرها عموماً برای پشتیبانی از یونیکد (P2295) مورد نیاز هستند. الگوریتمهای جدید برای محدودهها (ranges::contains P2302, views::as_rvalue P2446, views::repeat P2474, views::stride P1899, و ranges::fold P2322) و std::format_string برای بررسیهای زمان کامپایل اضافه شد. std::format (P2508) و ماکروی #warning در (P2437). محدودهها (Ranges) یاد گرفتاند که چگونه با انواع فقط حرکت کار کنند (P2494). و در نهایت std::forward_like برای ارسال متغیرها بر اساس نوع متغیر دیگری اضافه شد (P2445). برای مدت طولانی، به نظر میرسید مهمترین نوآوری C++23 اضافه کردن std::stacktrace از RG21 بود، اگرچه در آخرین جلسه ویژگیهای مورد انتظار بسیاری اضافه شد. نوآوریهایی برای توسعهدهندگان تعبیه شده، شیمیدانان/فیزیکدانان/ریاضیدانان/...، توسعهدهندگان کتابخانههای یادگیری ماشین، و حتی توسعهدهندگانی که روی برنامههای کاربردی با بار بالا کار میکنند، وجود دارد.
-
1 امتیازسلام. عدم دسترسی به یک سیستم مناسب و با خبر نبودن از حساب کاربری گیت هاب خود یکی از مشکلاتی بود که در این چند ساله برنامه نویسان با آن روبرو بودند. چک کردن حساب ایمیل در تلفن همراه می توانست تا حدودی به این موضوع کمک کند. اما یک اپلیکیشن اختصاصی برای این مورد می تواند این امر را به بهترین شکل پوشش دهد. بعد از کارهایی که برروی اپلیکیشن رسمی شرکت گیت هاب برای پلتفرم iOS انجام شد و خوشبختانه بدون هیچ مشکلی در بزرگ رویداد و کنفرانس شرکت و مایکروسافت - GitHub Universe 2019 در تاریخ November 13-14, 2019 رونمایی شد. به عنوان یکی از اعضای شرکت این نوید را می دهم که نوبت به آن رسید تا اپلیکیشن برای اندروید نیز پیاده شود. در حال حاضر این اپلیکیشن در حال توسعه است و هنوز رونمایی نشده است. برای این اپلیکیشن میزان پشتیبانی API 21+ Android device در نظر گرفته شده است و خواهد توانست از نسخه Android 5.0 به بالا را پشتیبانی کند. می توانید پیشنهادات و نظرات خود را نیز ایمیل کنید. Max [@] Asrez {.DOR.} com Hi, I'm Max Base. GitHub team did work on the official GitHub application for the iOS platform and fortunately unveiled at the big event and conference(GitHub Universe 2019 on November 13-14, 2019). As a member of the company, I have the promise that the app will launch for Android. This app is currently under development and has not been unveiled yet. This app is designed to support Android 21+ API and will support Android 5.0 or later. You can also email your suggestions and comments. Max [@] Asrez {.DOR.} com Best, Max Base با تشکر Max Base / مکس بیس
-
1 امتیازخالق لینوکس از اینتل به خاطر پشتیبانی نکردن از حافظههای ECC انتقاد کرده است. او به پشتیبانی غیررسمی از ECC در پردازندههای AMD بهعنوان اتفاقی مثبت نگاه میکند. این ماجرا برای توسعهدهدنگان قطعاً بسیار مهم و کاربردی است، بنابراین به عنوان نمایندهای از جامعهٔ برنامهنویسان و یک فرد با تجربه در بحث برنامهنویسی و مشکلات آن در مدیریت حافظه نظرات توروالدز برای جامعهٔ ما اهمیت دارد. لینوس توروالدز، خالق لینوکس، بهتازگی پست جدیدی در انجمن آنلاین Real World Tech با محوریت حافظهٔ کد تصحیح خطا (ECC) منتشر کرده است تا از اینتل انتقاد و از ایامدی (AMD) تمجید کند. بر اساس گزارش تامز هاردور، توروالدز میگوید اینتل باید حافظههای ECC را به قطعاتی میناستریم تبدیل کند و پشتیبانی از این حافظه در پردازندههای سری رایزن ایامدی اتفاق بسیار خوبی است. توروالدز با بیان اینکه «ECC کاملا پراهمیت است» اعلام کرد اینتل تأثیر بهسزایی روی رونق نداشتن بازار حافظهی ECC گذاشته است. خالق لینوکس میگوید: «بروید و بهدنبال DIMM-های ECC بگردید؛ پیدا کردن آنها واقعا سخت است. بله، احتمالا به لطف ایامدی، وضعیت DIMM-های ECC اخیرا کمی بهتر شده و این دقیقا همان نکتهای است که میخواهم به آن اشاره کنم.» توروالدز بارها به ضررهایی که اینتل به صنعت ECC و حتی کاربران وارد کرده است اشاره میکند و صحبتهایش را با کلماتی توهینآمیز خطاب به اینتل ادامه میدهد. توروالدز میگوید تیم آبی با پشتیبانی نکردن از ECC در مادربردها و پردازندههایی که برای کاربران عادی عرضه میکند، باعث شده است استفاده از حافظههای ECC زیاد نباشد. خالق لینوکس به مشکلاتی با محوریت آسیبپذیری روهمر (Rowhammer) اشاره میکند و میگوید این دسته از مشکلات امنیتی جدی، از طریق حافظههای ECC بهراحتی رفع میشوند. سلولهای حافظهی DRAM میتوانند انرژی خود را به دیگر سلولهای حافظه منتقل کنند. بهطور معمول این اتفاق صرفا به خاطر نقص در حافظهٔ اصلی سیستم رخ میدهد و نهایتاً به بروز خطا در حافظه منتهی میشود؛ اما حملات مبتنی بر آسیبپذیری روهمر از این نقص بهعنوان مکانیسمی برای دسترسی به سیستم بهره میگیرند. توروالدز میگوید هنگام توسعه دادن کد برای کرنل سیستم عامل، دستوپنجه نرم کردن با حافظهٔ استاندارد بسیار سخت است. او بهطور دقیقتر به این موضوع اشاره میکند که در اکثر اوقات نمیتوان بهطور دقیق فهمید خطای غیر قابل توضیح کرنل در کجا رخ داده است. در واقع این خطاها در اغلب اوقات ممکن است سختافزاری باشند، نه نرمافزاری؛ خطاهایی که بهراحتی توسط ECC قابل رفع هستند. توروالدز از ایامدی به خاطر پشتیبانی غیررسمی از ECC تمجید میکند. او خوشحال است که ایامدی تصمیم گرفته این پشتیبانی را به پردازندههای سری رایزن که در دسترس مشتریان عادی قرار میگیرند گسترش دهد. بدین ترتیب ایامدی کاربران را قادر میسازد بدون پرداخت هزینهی گزاف تهیهٔ قطعات سختافزاری در سطح سرور، به ECC دسترسی داشته باشند. اینکه پشتیبانی غیررسمی از ECC به گسترش استفاده از آن کمک میکند، موضوعی است که نیاز به بحث دارد؛ زیرا در اغلب اوقات ECC بهدرستی کار نمیکند. اما خالق لینوکس میگوید حتی پشتیبانی غیررسمی، قدمی روبهجلو در جهت درست محسوب میشود.
-
1 امتیازشما برنامه نویس هستید یا توسعهدهنده؟ آیا تا به حال فکر کردهاید که چه نوع عنوانی متناسب با مهارتهای شماست؟ من یک (توسعه دهنده فول-استک هستم) من یک (برنامهنویس هستم) من یک (توسعهدهندهٔ وب هستم) من یک (توسعهدهندهٔ فرانت اند هستم) من یک (توسعه دهندهٔ iOS هستم) و عناوین بسیار زیاد من در آوردی دیگر که ممکن است منظور دقیق از مهارتهای شما را به درستی مطرح نکنند! من میخوام در رابطه با اصطلاحاتی صحبت کنم که شاید بسیاری از علاقهمندان از استفادهٔ به جا از آنها بیخبر هستند. داستان این مقاله از اینجا شروع میشه که امروزه عناوین متعددی در رشتهٔ مهندسی کامپیوتر به خصوص گرایش نرمافزار و (برنامهنویسی) به چشم میخوره که ممکنه باعث سردرگمی بشه. نکته اصلی اینجاست که ما به عنوان صاحب عنوان تخصصی خود باید بدانیم که دارای چه مهارتهایی هستیم و در دنیای فناوری تحت چه عنوانی باید خود را در زمینه تخصصی معرفی کنیم. تفاوت بین کدنویس، برنامهنویس و توسعهدهنده در این پست قصد داریم با اصطلاحاتی آشنا شویم که ممکن برای اکثر افراد غیرمتخصص و گاه متخصص نیز سوال باشد که این عنوانها (کدنویس، برنامه نویس و توسعهدهنده) به چه کسانی با چه تخصصهای گفته میشود. ما به عنوان صاحب “عنوان تخصص” خود باید بدانیم که دارای چه مهارتهایی هستیم و در دنیای فناوری تحت چه عنوانی باید خود را در زمینه تخصصی معرفی کنیم. در این مقاله تصمیم گرفتم تفاوتهای بین کدنویس (Coder)، برنامهنویس (Programmer) و توسعهدهنده (Developer) را مشخص کنم. بنابراین به ترتیب عناوین هر یک از آنها را توضیح و در رابطه با نکات مهم متمایز کنندهٔ آنها اشاره خواهیم کرد. 1.کدنویس (Coder) کد نویس به کسی گفته میشود که میتواند بدون داشتن مهارت خاص یا حتی رشته مرتبط کدنویسی کند و نیاز به دانش تخصصی و واقعی علوم کامپیوتری ندارد. معمولاً کسانی که دارای تخصص دیگری هستند اما آشنا به منطق برنامهنویسی نیستند کُدِر میگویند. برای مثال تغییر دادن و یا ویرایش کدهای از قبل نوشته شده و حتی ایجاد نمونهای از کدهایی موجود به صورت (کپی) که میتواند نتیجهای به صورت کار بر روی یک سیستم نرمافزاری بر روی وب مانند WordPress یا غیره شود که با کمی تغییرات بر اساس نیاز پروژه خود را به صورت نه چندان حرفهای ایجاد و توسعه نمایند. اصطلاح درست این نوع اشخاص کُدر میباشد. 2.برنامهنویس (Programmer) برنامهنویس به کسی گفته میشود که توانایی و تخصص مرتبط با برنامهنویسی و علوم کامپیوتری را دارد. به عنوان مثال یک مهندس نرمافزار از شاخه مهندسی کامپیوتر که با منطق برنامه نویسی آشنا است برنامه نویس محسوب میشود. برنامهنویس میتواند برنامهای را تحت یکی از زبانهای برنامهنویسی که خود آن را ترجیح میدهد برنامه نویسی کند. برای مثال، کلاسی را طراحی و پیاده سازی کرده و توابع مورد نیاز خود را در آن ایجاد و توسعه دهد. برنامهنویس میداند در کجا باید از چه نوع دستورات و توابعی استفاده کند تا کدِ نهایی او نتیجهای ایجاد کند که از آن انتظار میرود. یک برنامهنویس توانایی این را دارد که کُدهای نوشته شده توسط دیگر برنامهنویسان را بخواند، درک کند و حتی آنها را ویرایش کند. توجه داشته باشید که یک برنامهنویس توانایی کنترل و مدیریت کردن بخشهای بسیار پیچیدهٔ یک محصول را ندارد. برای مثال اگر قرار است پروژهای را طراحی و توسعه نمایید برنامهنویس بخش بَک-اِند توانایی مدیریت بخش فرانت-اند (رابطکاربری) را ندارد و برعکس! بنابراین برنامهنویسان تنها کُدهایی را مینویسند که قرار است در بخش مورد نیاز عملیاتی را انجام دهند و کاری به این ندارند که طراحی رابطکاربری تحت چه نوع فناوری و زبانی در حل توسعه است و یا ارتباط با پایگاه داده چگونه صورت میگیرد چرا که برنامهنویسان مرتبط با آن بخشها با استفاده از مهارت های تخصصی خود در آن بخش آن را هندل خواهند کرد. برنامهنویسان معمولاً تیمهای توسعه یک محصول را ایجاد میکنند و همگی آنها وابسته یکدیگر هستند بنابراین اگر برنامهنویس واحد بک اند شما نتواند به موقع کدهای مورد نیاز بخش فرانتاند شما را آماده و تحویل دهد پروژه شما در زمان تعیین شده به نتیجه مطلوبی نخواهد رسید. 3.توسعه دهنده (Developer) در رابطه با توسعهدهنده باید به این توجه داشته باشید که توسعهدهنده به تنهایی عنوان نمیشود. بنابراین توسعهدهنده به صورتهای مختلفی وجود دارند (توسعهدهنده وب، توسعهدهندهٔ نرمافزار، توسعهدهندهٔ موبایل که در رابطه با نوع پلتفرم باز متفاوت هستند؛ توسعه دهنده رابط کاربری، توسعهدهندهٔ تجربه کاربری و در نهایت توسعه دهنده فول-استک). توسعهدهنده کسی است که علاوه بر برنامهنویس بودن مهارت و دانش کافی در لایههای مختلف پروژه در اختیار داشته باشد که متناسب با نوع تخصص نیز متفاوت است. توسعهدهنده کسی است که میتواند بر اساس نوع پروژه وظایف خاصی را در اختیار بگیرد به عنوان مثال اگر به صورت تیمی بر روی یک پروژه کار میکنید که شامل برنامه نویس هایی است که هر کدام بخشی از پروژه را برنامهنویسی میکنند کافی است یک توسعهدهنده داشته باشید تا تمامی کدهای شما را آنالیز، اشکال زدائی و بررسی کند و در نهایت آنها را با یکدیگر ارتباط داده و تبدیل به یک پروژه قابل استفاده نماید. چرا که توسعهدهنده دانش مورد نیاز در لایههای مختلف را دارد و میداند بخشهای مختلف یک محصول نرمافزاری یا غیره را که چگونه است و چطور باید برنامهنویسی شوند به آنها تسلط دارد. توسعهدهنده شخصی است که نباید فقط به یک زبان یا ابزار برنامهنویسی اکتفا کند چرا که برای توسعه محصول حتما باید از چند زبان برنامهنویسی مورد نیاز در پروژه اطلاعات کاملی داشته و بتواند هر جا که نیاز بود کدای مورد نیاز را توسعه و به نتیجه نهایی تبدیل کند. توجه داشته باشید که یک تیم شامل چندین توسعه دهنده به عنوان یک تیم کاملا حرفهای و زبان زد محسوب میشوند برای مثال شرکتهای بسیار بزرگ نه تنها برنامهنویسان حرفهای در تیم خود استخدام میکنند بلکه توسعه دهندگانی را از نوع (Full-Stack) در اختیار دارند که مدیریت حساس پروژه را به عهده گرفته و پروژه را با دانشی که دارد به خوبی مدیریت میکند و زمانی که جایی پروژه به نکتهای برسد که برنامهنویسان توانایی حل آن را ندارند توسعه دهنده فول-استک میتواند با مهارتها و تجربیات خود آن را حل کند. در رابطه با برنامهنویسان فولاستک و ویژگیهای این دسته از برنامهنویسان را در ادامه آورده شده است. 4.توسعه دهندگان فرانت-اند (UI/UX) این نوع توسعهدهندگان برنامهنویسانی هستند که مهارت کاملی در رابطه با لایههای مختلف و چندین زبان و فناوریهای مورد نیاز در بخش User Interface و User Experience را دارند و میتوانند طراحی مناسبی را متناسب با نوع پروژه و تجریبات مشتری ایجاد و توسعه دهند. این نوع برنامهنویسان یکی از مهمترین بخشهای توسعهدهندگان در تیم محسوب میشوند که شاید تجربیات و بازخوردهای مشتری را به سمت این نوع توسعه دهنده ارسال کنند. این نوع توسعه دهندگان علاوه بر داشتن دانش طراحی و تجربه کاربری دانش مرتبط با روانشناسی رنگها و جلوههای بصری دارند که آنها را میتوانند در قالب برنامه نویسی پیاده سازی کنند. 5.توسعه دهندگان بک-اند این نوع توسعه دهندگان برنامهنویسان بسیار ماهری در بخش لایههای زیرین پروژه یعنی (منطقی) دارند که تمامی اطلاعات لازم را در رابطه با لایههای زیرین در اختیار دارند و میدانند چطور باید با دیتابیس ارتباط برقرار کنند، میدانند چطور باید با APIهای سیستم عامل کار کنند و میدانند کدهای خود را بر اساس نوع ABI و APIها چگونه باید مدیریت کنند؛ موارد بسیار زیادی که نیاز است در بخش منطقی یک پروژه ایجاد شود را به تنهایی حل و توسعه میدهند تا نتایج آن در اختیار توسعه دهنده فرانت اند قرار بگیرد. اما وظیفهای در رابطه با طراحی تجربهکاربری و یا رابط کاربری نداشته و نمیتوانند در این بخش مانور دهند. از این نوع توسعه دهندگان تنها میتوان انتظار نوشتن کُدهای بی نقص و عالی در لایههای پایین را داشت. 6.توسعه دهندگان فول-استک این نوع توسعهدهندگان علاوه بر داشتن مهارتهای مربو به برنامهنویسی، توسعهدهنده در فرانتاند و بکاند نیز هستند تجربیات و مهارتهای بسیار زیادی در شاخههای دیگر علوم مهندسی کامپیوتری را دارند که نکته بسیار مهمی است! رسیدن به این درجه از برنامهنویسی یعنی یک مهندس کامل کامپیوتر که میتواند در تمامی بخشهای یک پروژه در لایههای مختلف نرمافزار، سختافزار، شبکه، پلتفرمها و … صاحب نظر باشند و آن را توسعه دهند. یک فول استک به تنهایی میتواند رهبری یک پروژه را بر عهده بگیرد و درصورتی که نیاز باشد به تنهایی یک پروژه را از صفر تا صد تولید توسعه و اجرا نماید. این نوع توسعهدهندهها یک مهندس واقعی کامپیوتر (نرمافزار) هستند که به خوبی میدانند یک محصول نهایی باید تحت چه شرایطی توسعه و اجرا شود. البته به این نکته توجه کنید توسعهدهندههای فولاستک هم میتوانند از لحاض محدودیت دستهبندی شوند، بعضی از آنها صرفاً در یک حوزه تسلط کافی دارند، مانند Full Stack Web Developer یا Full Stack Android Developer به معنای این است که این گونه توسعهدهندهها میتوانند یک محصول را در سطح وب به طور کامل طراحی و پیاده سازی کند و یا در حوزهٔ ساخت و ساز اپلیکیشنهای اندروید یک محصول را به طور کامل طراحی و برنامهنویسی کند. در غیر این صورت تنها واژهٔ Full Stack Developer میتواند پوشش کاملی بر تسلط کامل یک فرد با تخصصهای بسیار بالا در ساخت و ساز یک محصول در پلتفرمهای متنوع را بدهد که در یک پست جداگانه قبلاً به آن اشاره کردهام: با توجه به تعاریف مرتبط با عناوین باید سعی کنیم که از اصطلاحات صحیح و عناوین مرتبط با خود استفاده کنیم چرا که در صورتی که شما یک برنامهنویس هستید نباید بگویید من یک توسعهدهندهٔ وب هستم! این کار باعث ایجاد انتظار از شما خواهد شد که به احتمال بسیار زیاد توانایی انجام آن را نخواهید داشت. حتی برعکس آن ممکن است شما یک توسعهدهنده باشید اما بگویید یک کُدر حرفهای هستم! این واقعاً اشتباه است! در این صورت درجه تخصصی خود را به شدت تنزل دادهاید. در فرصت مناسبتری در بارهٔ این موضوع، در قالب یک اینفوگرافیک اطلاعاتی نشر خواهم کرد.
-
1 امتیازبا سلام وقت بخیر, در این مطلب میخواهیم در مورد روش کارکرد پیام رسان ها بیشتر بدانیم و با یکدیگر کد یک پیام رسان ساده را پیاده و بررسی کنیم. طرز کار کرد پیام رسان در نظر داشته باشید که هر پیام رسانی که بر ساختار ها پیاده شده باشد از دو قسمت تشکیل شده است. نرم افزار اصلی برای مدیریت درخواست ها (سرور) نرم افزار برای کاربران (کاربر) به نرم افزار اولی سمت SERVER خواهیم گفت و به بعدی سمت CLIENT خواهیم گفت. روم یا تالار گفتگو ما تنها یک اتاق برای گفتگو در نظر میگیریم و هر کاربری که به سرور متصل شود را در همان تالار اضافه خواهیم کرد. تالار های گفتگو صرفا برای تقکیک سازی ارسال و دریافت ها و محدود کردن بازه ی کاربران مورد نظر... (ممکن است یک کاربر در چند اتاق بطور همزمان باشد.) سیستم های پیام رسان پیشرفته تر مانند تلگرام و ... تالار های زیادی را شامل می شوند. (هر کاربر خودش در کانال و گروه های مختلفی عضو است که هر کدام از آنها یک کانال متفاوت محسوب می شوند.) * دقت شود که منظور از کانال صرفا یک اتاق یا تالار گفتگو است و منظور کانال ارتباطی و پروتکل نیست. نرم افزار اصلی نرم افزار اصلی وظیفه دارد تا تمام کاربرانی که وارد تالار شده اند را به یاد داشته باشد و هر لحظه اماده دریافت درخواست هایی از طرف کاربرانش باشد. و پیام هایی را که از کاربران دریافت می کند برای تمامی کاربران دیگر هم ارسال کند که بسته به خلاقیت و نیاز می تواند هر یک از این بخش ها متفاوت طراحی شود. نرم افزار اصلی باید از قبل اجرا شده باشد. تا کاربران دیگر با استفاده از نرم افزار مخصوص به خودشان بتوانند به سرور متصل شوند و ارسال و دریافت داشته باشند. در نظر داشته باشید که اگر در نرم افزار اصلی اختلالی پیش بیایید و متوقف بشوند. قطا برای تمام کاربران مشکل پیش می آید. مگر اینکه از پایگاه های داده ی داخلی استفاده کرده باشند. (با خلاقیت می توان به گونه های متفاوتی چنین ساختاری را پیاده کرد) نرم افزار کاربران این نرم افزار جذاب ترین بخش است چرا تمام قابلیت هایی را که در اختیار کاربر قرار می دهیم را مستقیما طراحی می کنیم. در نظر داشته باشید که هر چیزی که در این نرم افزار طراحی می شود باید در نرم افزار اصلی پشتیبانی شوند... بنابراین اگر این دو بخش توسط دو فرد یا دو گروه مجزا طراحی می شوند آنها باید توسط داکیومنت ها و جلساتی به نظرات مشابه ای رسیده باشند. (اگرچه اینها تخصص و وظیفه ی تحلیلگر سیستم است! نه بطور همزمان وظیفه توسعه دهنده و برنامه نویس نرم افزار) پیاده سازی یک نمونه اکنون در نظر داریم تا با استفاده از ساختار کتابخانه BoostAsio پروژه ای را با نام BoostAsioChat ایجاد کنیم که در آن می خواهیم یک پیام رسان با حداقل ترین امکانات پایه طراحی کنیم که بیشتر جنبه شخصی و تفریحی دارد. زیرا از ساختار های استاندارد و ایمن و کاربری کاملا بدور است! (می توانید خودتان توسعه دهید و آنرا جالب تر بسازید) ساختار نرم افزار اصلی و سرور را به این صورت تعریف می کنیم : typedef deque<message> messageQueue; class participant { public: virtual ~participant() {} virtual void deliver(const message& messageItem) = 0; }; typedef shared_ptr<participant> participantPointer; class room { public: void join(participantPointer participant); void deliver(const message& messageItem); void leave(participantPointer participant); private: messageQueue messageRecents; enum { max = 200 }; set<participantPointer> participants; }; class session : public participant, public enable_shared_from_this<session> { public: session(tcp::socket socket, room& room) : socket(move(socket)), room_(room); void start(); void deliver(const message& messageItem); private: void readHeader(); void readBody(); void write(); tcp::socket socket; room& room_; message messageItem; messageQueue Messages; }; class server { public: server(boost::asio::io_context& io_context, const tcp::endpoint& endpoint) : acceptor(io_context, endpoint); private: void do_accept(); tcp::acceptor acceptor; room room_; }; int main(int argc, char* argv[]); ساختار نرم افزار کاربر را هم به این صورت تعریف می کنیم : typedef deque<message> messageQueue; class client { public: client(boost::asio::io_context& context, const tcp::resolver::results_type& endpoints) : context(context), socket(context); void write(const message& messageItem); void close(); private: void connect(const tcp::resolver::results_type& endpoints); void readHeader(); void readBody(); void write(); boost::asio::io_context& context; tcp::socket socket; message readMessage; messageQueue writeMessage; }; int main(int argc, char* argv[]); در نظر داریم تا در این پروژه از thread ها نیز استفاده کنیم... در مورد این مفهوم ها می توانید بصورت مجزا تحقیق کنید. بنابراین روش کامپایل این پروژه به این صورت خواهد بود : $ g++ client.cpp -lpthread -o client $ g++ Server.cpp -lpthread -o server آزمایش همانطور که گفته شد در ابتدا نرم افزار اصلی و سرور باید اجرا شود. در اینجا ما تمام ارتباطات شبکه را بر روی یک سیستم در شبکه داخلی برقرار خواهیم کرد... پس نگرانی در مورد ساختار های درونی شبکه و آی پی / دی ان اس / دامین نخواهیم داشت. بنابراین ای پی را می توانید ای پی داخلی یا localhost در نظر بگیرید. برای آزمایش پورت فرضی 4000 را در نظر میگیریم و نرم افزار اصلی را روی این پورت اجرا میکنیم : $ ./server 4000 در این مرحله متوجه می شوید که نرم افزار اصلی با موفقیت اجرا شده است و همچنان اجرا مانده است. بله درست است... نرم افزار اصلی هر لحظه باید منتظر دستور کاربران باشد. اگر لحظه ای برای نرم افزار اصلی اختلالی پیش آید نخواهد توانست دستورات کاربران را انجام یا پاسخ دهد. بنابراین این پردازش را قطع نکنید و اجازه دهید تا نرم افزار اصلی اجرا بماند. در محیط دیگری نرم افزار سمت کاربر را نیز اجرا کنید. این نرم افزار را می توانید به تعداد دلخواه وارد کنید. (همانطور که ممکن است 6 نفر همزمان به سرور متصل باشند / یا ممکن است هیچ فردی به سرور متصل نشوند) ابتدا یک کاربری را به سرور با پورت 4000 و شبکه داخلی وصل می کنیم : $ ./client localhost 4000 first user: you can type message here... حال در محیط دیگری با کاربر جدیدی نیز وارد می شویم : $ ./client localhost 4000 second user: you can type message here... در این پروژه نمونه از کاربران نام کاربری یا نام نمی پرسیم.. و صرفا وقتی وارد محیط گفتگو می شوند... یا زمانی که به سرور متصل می شوند منتظر هستیم تا انها پیامی را بنویسند... هر پیامی را که بنویسند به سرور ارسال می شود و سرور وظیفه دارد تا آنرا برای تمام کاربران بفرستد. و این روند درون یک حلقه بی نهایت تکرار می شوند. پس این ارتباط دو طرفه خواهد بود و هم کاربران برای سرور اطلاعات ارسال می کنند و هم سرور برای کاربران اطلاعات ارسال خواهد کرد. در نظر داشته باشید که کاربر اول می تواند پیامی را بنویسد و به کاربران دیگر ارسال شود. ممکن است کاربر سومی اصلا تصمیمی به نوشتن پیام نداشته باشد و صرفا تمایل به خواندن پیام دیگران داشته باشند. و این کاملا اختیاری است. و ما کاربران را اجباری نمیکنیم. اگرچه شما می توانید با خلاقیت خودتان اینها را با متغییر های کمکی و دستورات شرطی پیاده کنید. کد ها برای پیام ها یک ساختار در نظر میگیریم و بصورت مشترک در هر دو نرم افزار استفاده خواهیم کرد... بنابراین اینرا در هدر پیاده خواهیم کرد. هدر پیام : (message.hpp) #ifndef message_HPP #define message_HPP #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; class message { public: enum { headerLength = 4 }; enum { maxBodyLength = 512 }; message() : bodyLength_(0) { } const char* data() const { return data_; } char* data() { return data_; } size_t length() const { return headerLength + bodyLength_; } const char* body() const { return data_ + headerLength; } char* body() { return data_ + headerLength; } size_t bodyLength() const { return bodyLength_; } void bodyLength(size_t new_length) { bodyLength_ = new_length; if(bodyLength_ > maxBodyLength) bodyLength_ = maxBodyLength; } bool decodeHeader() { char header[headerLength + 1] = ""; strncat(header, data_, headerLength); bodyLength_ = atoi(header); if(bodyLength_ > maxBodyLength) { bodyLength_ = 0; return false; } return true; } void encodeHeader() { char header[headerLength + 1] = ""; sprintf(header, "%4d", static_cast<int>(bodyLength_)); memcpy(data_, header, headerLength); } private: char data_[headerLength + maxBodyLength]; size_t bodyLength_; }; #endif نرم افزار اصلی و سرور : (server.cpp) #include <iostream> #include <cstdlib> #include <deque> #include <memory> #include <list> #include <set> #include <utility> #include <boost/asio.hpp> #include "message.hpp" using boost::asio::ip::tcp; using namespace std; typedef deque<message> messageQueue; class participant { public: virtual ~participant() {} virtual void deliver(const message& messageItem) = 0; }; typedef shared_ptr<participant> participantPointer; class room { public: void join(participantPointer participant) { participants.insert(participant); for(auto messageItem: messageRecents) participant->deliver(messageItem); } void deliver(const message& messageItem) { messageRecents.push_back(messageItem); while(messageRecents.size() > max) messageRecents.pop_front(); for(auto participant: participants) participant->deliver(messageItem); } void leave(participantPointer participant) { participants.erase(participant); } private: messageQueue messageRecents; enum { max = 200 }; set<participantPointer> participants; }; class session : public participant, public enable_shared_from_this<session> { public: session(tcp::socket socket, room& room) : socket(move(socket)), room_(room) { } void start() { room_.join(shared_from_this()); readHeader(); } void deliver(const message& messageItem) { bool write_in_progress = !Messages.empty(); Messages.push_back(messageItem); if(!write_in_progress) { write(); } } private: void readHeader() { auto self(shared_from_this()); boost::asio::async_read(socket, boost::asio::buffer(messageItem.data(), message::headerLength), [this, self](boost::system::error_code ec, size_t) { if(!ec && messageItem.decodeHeader()) { readBody(); } else { room_.leave(shared_from_this()); } }); } void readBody() { auto self(shared_from_this()); boost::asio::async_read(socket, boost::asio::buffer(messageItem.body(), messageItem.bodyLength()), [this, self](boost::system::error_code ec, size_t) { if(!ec) { room_.deliver(messageItem); readHeader(); } else { room_.leave(shared_from_this()); } }); } void write() { auto self(shared_from_this()); boost::asio::async_write(socket, boost::asio::buffer(Messages.front().data(), Messages.front().length()), [this, self](boost::system::error_code ec, size_t) { if(!ec) { Messages.pop_front(); if(!Messages.empty()) { write(); } } else { room_.leave(shared_from_this()); } }); } tcp::socket socket; room& room_; message messageItem; messageQueue Messages; }; class server { public: server(boost::asio::io_context& io_context, const tcp::endpoint& endpoint) : acceptor(io_context, endpoint) { do_accept(); } private: void do_accept() { acceptor.async_accept([this](boost::system::error_code ec, tcp::socket socket) { if(!ec) { make_shared<session>(move(socket), room_)->start(); } do_accept(); }); } tcp::acceptor acceptor; room room_; }; int main(int argc, char* argv[]) { try { if(argc < 2) { cerr << "Usage: server <port> [<port> ...]\n"; return 1; } boost::asio::io_context io_context; list<server> servers; for(int i = 1; i < argc; ++i) { tcp::endpoint endpoint(tcp::v4(), atoi(argv[i])); servers.emplace_back(io_context, endpoint); } io_context.run(); } catch (exception& e) { cerr << "Exception: " << e.what() << "\n"; } return 0; } نرم افزار دوم و سمت کاربر : (client.cpp) #include <iostream> #include <thread> #include <cstdlib> #include <deque> #include <boost/asio.hpp> #include "message.hpp" using boost::asio::ip::tcp; using namespace std; typedef deque<message> messageQueue; class client { public: client(boost::asio::io_context& context, const tcp::resolver::results_type& endpoints) : context(context), socket(context) { connect(endpoints); } void write(const message& messageItem) { boost::asio::post(context, [this, messageItem]() { bool write_in_progress = !writeMessage.empty(); writeMessage.push_back(messageItem); if(!write_in_progress) { write(); } }); } void close() { boost::asio::post(context, [this]() { socket.close(); }); } private: void connect(const tcp::resolver::results_type& endpoints) { boost::asio::async_connect(socket, endpoints, [this](boost::system::error_code ec, tcp::endpoint) { if(!ec) { readHeader(); } }); } void readHeader() { boost::asio::async_read(socket, boost::asio::buffer(readMessage.data(), message::headerLength), [this](boost::system::error_code ec, size_t) { if(!ec && readMessage.decodeHeader()) { readBody(); } else { socket.close(); } }); } void readBody() { boost::asio::async_read(socket, boost::asio::buffer(readMessage.body(), readMessage.bodyLength()), [this](boost::system::error_code ec, size_t) { if(!ec) { cout.write(readMessage.body(), readMessage.bodyLength()); cout << "\n"; readHeader(); } else { socket.close(); } }); } void write() { boost::asio::async_write(socket, boost::asio::buffer(writeMessage.front().data(), writeMessage.front().length()), [this](boost::system::error_code ec, size_t) { if(!ec) { writeMessage.pop_front(); if(!writeMessage.empty()) { write(); } } else { socket.close(); } }); } boost::asio::io_context& context; tcp::socket socket; message readMessage; messageQueue writeMessage; }; int main(int argc, char* argv[]) { try { if(argc != 3) { cerr << "Usage: client <host> <port>\n"; return 1; } boost::asio::io_context context; tcp::resolver resolver(context); auto endpoints = resolver.resolve(argv[1], argv[2]); client c(context, endpoints); thread t([&context](){ context.run(); }); char line[message::maxBodyLength + 1]; while(cin.getline(line, message::maxBodyLength + 1)) { message messageItem; messageItem.bodyLength(strlen(line)); memcpy(messageItem.body(), line, messageItem.bodyLength()); messageItem.encodeHeader(); c.write(messageItem); } c.close(); t.join(); } catch (exception& e) { cerr << "Exception: " << e.what() << "\n"; } return 0; } این پروژه آزمایشی بصورت رایگان و اوپن سورس در اینترنت بخصوص اینجا وجود دارد و می توانید آنرا مستقیما بصورت کامل دانلود کنید. با تشکر, Max Base / مکس بیس
-
1 امتیازبرنامهنویس تنها در این عنوان خلاصه نمیشود و لازم است بدانید که برنامهنویسان در چند دسته متفاوت وجود دارند که برخی از آن ها به صورت Back-End و برخی Front-End فعالیت میکنند. در کل به کسانی که توانایی برنامهنویس در بخش Back-End را دارند به آنها Back-End Developer میگویند. همچنین برنامهنویسانی که توانایی توسعه در بخش طراحی رابطکاربری و تجربهکاربری را با عنوان Front-End دارند Front-End Developer میگویند. در نظر داشته باشید که توسعهدهندگان و طراحان بخش تجربهکاربری (UX) و رابطکاربری (UI) خود وظایفی در سمت طراحی یک محصول را دارند که به خودی خود میتوانند به عنوان توسعهدهندهی فرانتاِند محسوب شوند اما ممکن است زمینهی اجرایی آنها با محیطهای توسعه که شامل کدنویسی هستند نباشد! بنابراین شاخهای از حوزهی توسعه در نرمافزار کامپیوتر وجود دارد که میتواند با ترکیب دانش طراحی و کدنویسی و تسلط کامل بر این دو حوزه به صورت ترکیبی با دانش و توانایی بسیار بالا عنوان شود که به آن فولاِستک میگویند. البته فولاِستک ابعاد مختلفِ خود را دارد، برای مثال ممکن است یک توسعهدهندهی فولاِستک تنها در پلتفرم اندروید توانایی طراحی و کدنویسی را به صورت همزمان و بدون نیاز به یار تیمی خود داشته باشد. اما در اصل توسعهدهندههای با تجربه با سابقهی بالا که توانایی مدیریتی پروژه و توسعهی آنها را دارند از نوع فولاِستک تمام عیار محسوب میشوند که در ادامه به ویژگیهای آنها اشاره شده است. یک برنامهنویس حرفهای یا همان فولاِستک میبایست مهارتهای زیر را داشته باشد: مسلط به زبانهای برنامهنویسی پایه آشنایی با UX و UI و مباحث مرتبط با هر یک از آنها مدیریت پروژه بر روی پلتفرمهای مختلف توانایی کنترل کیفیت محصول توانایی کار با انواع فناوریها و کتابخانهها توانایی کار با انواع دیتابیس و مدیریت آنها هک و امنیت بهینه سازی موتورهای جستجو آشنایی و توانایی درک و مدیریت کامپایلرها و مفسرها درک نیازهای کاربران در محصول (UX) آشنایی با سیستم عاملهای مختلف آشنایی و توانایی تولید محصول به صورت چند-سکویی (Cross-Platform) آشنایی با شبکه و پیکربندی آن برای محصول آشنایی با مدیریت سرور و هاستینگ آشنایی با سیستمهای مدیریتی و مجازی مانند VM آشنایی با سخت افزار آشنایی با رابط های برنامه نویسی APIها آشنایی با انواع محیطهای توسعه و موارد دیگر که در یک پروژه از صفر تا صد میتوان به آنها نیاز پیدا کرد. برنامهنویسان Full-Stack Developer به تنهایی میتواند درتولید و توسعه یک محصول موثر باشد و زمانی که با مشکلی مواجه شوند نمیگوید من آن را بلد نیستم، بلکه حتماً آن را حل خواهند کرد. به طور کلی کسب مهارت در سطح بالا در حد یک توسعه دهنده فولاِستک بسیار سخت است اما نباید بگوییم که غیر ممکن است، در صورتی که چنین تعریفی برای یک توسعهدهندهی فولاستک در نظر بگیریم، بدون اغراق باید گفت تعداد اندکی از این برنامهنویسان موجود است که بتوانیم چنین لقبی را به آنها اختصاص بدهیم بنابراین چنین برنامهنویسانی بسیار ارزشمند هستند لذا به خوبی میدانند یک نرم افزار چگونه طراحی میشود و توانایی این را دارند از صفر تا صد یک نرمافزار را طراحی و روانه بازار کنند. علاوه بر این توسعه دهنده Full-Stack کسی است که واژگانی مانند نبود، نمیشه، امکان نداره، نمیتوم، کار من نیست و ... را بر زبان نمیآورند و اگر هم چیزی را ندانند تمام تلاش خود را میکنند تا بدون نیاز به کمک شخصی دیگر آن را حل کنند. این نوع توسعهدهندهها بسیار با ارزش و مهم هستند، و نکته جالب اینجاست که آنها سالها تلاش کردهاند و مسلماً به تنهایی صاحب کسبوکار خود بوده و در انتخاب اول برای کسی کار نمیکنند. برای توسعه دهندهی فولاِستک فرقی نمیکند محصول تحت چه پلتفرمی باشد، او میتواند تحت دسکتاپ، وب، موبایل و دیگر پلتفرم ها آن را تولید کند.
-
1 امتیازکامپایلر Cling یک مترجم تعاملی برای سیپلاسپلاس است، این مترجم تحت بالاترین کتابخانههای Clang و LLVM ساخته شده است. در واقع از آنجایی که کامپایلر Clang از آخرین ویژگیها و استانداردهای زبان سیپلاسپلاس پشتیبانی میکند، Cling اجازه میدهد تا توسعهدهندگان اسکریپتهای خود را با استفاده از C و C++ بنویسند. اگر شما به طور مستقیم مترجم را اجرا کنید، یک محیط زنده برای آغاز برنامه نویسی با سیپلاسپلاس را خواهید داشت که به عنوان بخشی از استاندارد نحو سی و سیپلاسپلاس به شمار میآید. همچنین میتوانید دیگر دستورات را با نقطهی "." آغاز در اختیار داشته باشید. وقتی از مترجم تعاملی استفاده میکنید، میتوانید کد زیر را بنویسید: #include <stdio.h> printf("hello world\n"); همانطور که میبینید نیازی نیست تا در مورد حوزهی دامنهها نگران باشید؛ کافی است شما تابع مورد نظر خود را صدا بزنید. اگر قصد شما این است که از Cling به عنوان یک مترجم برای ساخت اسکریپتها استفاده کنید، باید همه چیز را در داخل یک تابع قرار دهید.چرا که نقطهی ورود به اسکریپت به طور پیشفرض همانند نام فایل میباشد. میتوان آن را برای صدا زدن دیگر توابع سفارشی سازی کرد. بنابراین مثال قبل میتوانید به شکل زیر تغییر کند: #include <stdio.h> void _01_hello_world() { printf("foo\n"); } یک نسخهی دیگر در قالب سیپلاسپلاس #include <iostream> void _02_hello_world() { std::cout << "Hello world" << std::endl; } مثالها کاملاً ساده هستند، اما آنها به شما نشان میدهند که چگونه باید شروع کنید. در مورد کیوت چطور؟ #include <QtWidgets/qapplication.h> #include <QtWidgets/qpushbutton.h> void _03_basic_qt() { int argc = 0; QApplication app(argc, nullptr); QPushButton button("Hello world"); QObject::connect(&button, &QPushButton::pressed, &app, &QApplication::quit); button.show(); app.exec(); } اما توجه داشته باشید که کد قبلی کار نخواهد کرد، شما باید برخی از پارامترهای سفارشی را در Cling مشخص کنید. cling -I/usr/include/x86_64-linux-gnu/qt5 -fPIC -lQt5Widgets 03_basic_qt.cpp شما میتوانید Cling را برای خودتان بر اساس آن چیزی که برای اسکریپت خود نیاز دارید سفارشی سازی کنید. همچنین شما میتوانید Cling را به عنوان یک کتابخانه در اپلیکیشنهای خود آورده و از سیپلاسپلاس به عنوان زبان برنامهنویسی استفاده کنید. این پُست در آینده ادامه خواهد داشت. ?