<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های آرش شاکری</title>
        <link>https://virgool.io/feed/@arash.shakery</link>
        <description>برنامه‌نویس و چپترلید فرانت‌اند در کافه‌بازار</description>
        <language>fa</language>
        <pubDate>2026-06-13 13:00:00</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/27491/avatar/tTh47f.png?height=120&amp;width=120</url>
            <title>آرش شاکری</title>
            <link>https://virgool.io/@arash.shakery</link>
        </image>

                    <item>
                <title>بازنویسی وب‌سایت کافه بازار</title>
                <link>https://virgool.io/cafebazaar/%D8%A8%D8%A7%D8%B2%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D9%88%D8%A8%D8%B3%D8%A7%DB%8C%D8%AA-%DA%A9%D8%A7%D9%81%D9%87%D8%A8%D8%A7%D8%B2%D8%A7%D8%B1-mr1gcwn9dzge</link>
                <description>در پاییز ۹۷ تصمیم گرفتیم وب‌سایت کافه‌بازار را باز‌نویسی کنیم تا اضافه کردن امکانات جدید به آن، ساده‌تر شود. انگیزه‌ی اصلی، اضافه کردن امکان تماشای ویدئو از طریق وب بود؛ ولی باید محتاطانه پیش می‌رفتیم تا متریک‌های فعلی (نظیر میزان دانلود اپ بازار) آسیب نبیند. نسخه‌ی قبلی legacy شده بود و توسعه روی آن راحت نبود. به مرور زمان امکانات جزئی زیادی اضافه شده بود که پشت هر کدام داستانی وجود داشت؛ از کد شامِد و دسترسی‌های برنامه گرفته تا لوگوی ای‌نماد و غیره. با بخش‌هایی سر‌و‌کار داشتیم که معلوم نبود چرا به آن شکل نوشته شده‌اند، یا متادیتاهایی که نمی‌دانستیم با چه هدفی اضافه شده‌اند. بخش‌هایی از کدها توسط کسانی نوشته شده بود که دیگر در شرکت حضور نداشتند و با مشکلاتی از این دست رو‌به‌رو بودیم.فارغ از وجود ریزه‌کاری‌ها، تعداد زیاد کاربران فعال، اعمال تغییرات را به شدت ترسناک می‌کرد. فضای کار محصول پروداکشن متفاوت از فضای یک پروژه‌ی استارتاپی است که هنوز کاربران چندانی ندارد و به تبع آن، اشتباهات هم هزینه‌ی چندانی نخواهند داشت. در فضای پروداکشن باید خیلی محتاطانه و محافظه‌کارانه حرکت کرد؛ هر تصمیمی باید کاملاً حساب شده گرفته شود و با برنامه‌ریزی، عملیاتی گردد.در این مسیر به چالش‌های زیادی برخورد کردیم. از مسائل مرتبط با معماری، لایه‌ی ارتباط با بکند، پشتیبانی از مرورگرها، SEO و SSR و PWA گرفته تا استراتژی انتشار و چالش‌های پرفرمنسی بعد از انتشار که در ادامه آن‌ها را بررسی می‌کنیم.تغییرات دیزاین ظاهری وب‌سایت از گذشته تا کنونگذشته‌ی Legacyدر گذشته‌های دور، بکند کافه‌بازار (شامل کدهای وب‌سایت)، یک سرویس یک‌پارچه (monolithic) به نام «کافه» بود که با جنگو نوشته شده بود. داخل همان کدبیس، کدهای وب‌سایت هم قرار داشته است (فولدر «پنجره»). بعدها به‌خاطر بزرگ شدن محصول بازار، تیم‌های متفاوتی تشکیل شدند که وظایف‌شان به فیچر خاصی محدود می‌شد. کد زدن روی یک کد‌بیس واحد دیگر راحت نبود و معماری بکند به سمت مایکروسرویس شدن پیش رفت. به مرور، هر تیمی قسمتی از کد «کافه» را برداشت و مایکرو‌سرویس‌های جدا بالا آورد و مسئول توسعه‌ی آنها شد. اما «پنجره» که همچنان به بخش زیادی از کدهای «کافه» وابستگی داشت، امکان جدا شدن کامل را نداشت.بنابراین از کد «کافه» یک کپی مجزا گرفته شد و «سرویس پنجره» نام گرفت. به مرور که در کد «کافه» تغییراتی داده می‌شده، در پنجره هم ـ تنها در صورت لزوم ـ همزمان اعمال می‌شده است. تغییرات وب‌سایت هم فقط در «سرویس پنجره» اعمال می‌شد. به دلایل امنیتی، «پنجره» امکان دسترسی مستقیم به دیتابیس اطلاعات کاربران را نداشت؛ بنابراین برخی صفحات وب‌سایت که به این اطلاعات نیاز داشتند، داخل «کافه» فولدر «پنجره» توسعه داده شدند. یک nginx با config بزرگ و نسبتاً پیچیده هم وجود داشت که تشخیص می‌داد برای هر urlی از چه سرویسی باید جواب بگیرد («سرویس پنجره» یا کافه؟).از سرویس یک‌پارچه به مایکروسرویس در گذر زمان - بخش اولپروتکل ارتباطی کلاینت با بکند در گذشته custom json-rpc بوده؛ در واقع همان JSON-RPC که رمزنگاری کلید عمومی به آن اضافه شده بود و مربوط به زمانی بود که به‌خاطر مشکلات تحریم امکان خرید ssl certificate وجود نداشت. سرویس‌های بکند هم در گذشته با همین پروتکل با هم ارتباط داشتند، اما بعدها تصمیم گرفته شد که به مرور زمان به سمت استفاده از grpc حرکت کنیم.امکان تغییرات سریع وجود نداشت؛ ممکن بود سرویسی grpc شود ولی یک سرویس قدیمی‌تر که با json-rpc کار می‌کرد به آن وابسته باشد. بنابراین یک gateway به اسم «دیلماج» (کلمه‌ی ترکی به معنی مترجم) توسعه داده شد که سرویس‌ها با پروتکل‌های مختلف (grpc یا json-rpc) در پشت آن قرار گیرند و کلاینت از طریق هر پروتکلی (json-rpc یا grpc یا rest) بتواند به دیلماج وصل شود. در عین حال زمانی که پیاده‌سازی وب‌سایت را شروع کردیم هنوز برخی سرویس‌ها پشت دیلماج نرفته بود و تنها راه ارتباطی با آن‌ها custom json-rpc بود که پیاده‌سازی آن سمت وب‌سایت پیچیده بود.مسیر آینده‌ی محصول این بود که اپ اندروید و وب‌سایت هر دو از طریق rest با بکند ارتباط برقرار کنند و برای کوتاه مدت تصمیم نداشتیم custom json-rpc را سمت وب‌سایت پیاده‌سازی کنیم؛ بنابراین سرویس جدیدی به اسم «کوشک» را کلید زدیم که در پشت آن دیلماج و سرویس‌های خاص قرار می‌گرفت. البته بعد‌ها که همه‌ی سرویس‌ها پشت دیلماج قرار گرفت، سرویس کوشک هم باید حذف می‌شد.از سرویس یک‌پارچه به مایکروسرویس در گذر زمان - بخش دومتصویر معماری خیلی خلاصه شده‌ است و تعداد سرویس‌های بکندی بیشتر از این است. این سرویس‌ها ممکن است مستقیماً یا به‌واسطه‌ی دیلماج به هم ریکوئست بزنند. در عین حال سرویس‌هایی که وب‌سایت با آن‌ها ارتباط مستقیم دارد این‌ها هستند:اکانت: امکانات مرتبط با احراز هویت که jwt برمی‌گرداند، refresh token می‌دهد و غیره.فهرست: لیست‌های اپ/ویدئو که صفحات اصلی و لیستی (تازه‌ها، برترین‌ها، بروزشده‌ها و …) را به کمک یک سری سرویس‌های دیگر تولید می‌کند و تحویل کلاینت می‌دهد.سرچ: جستجو در اپ‌ها و فیلم‌ها که ساختار خروجی شبیه به فهرست برمی‌گرداند؛ و امکان پیشگوی متن جستجو که وقتی کاربر در فیلد جستجو مشغول تایپ است یک سری موارد پیشنهادی ارائه می‌دهد.سجل: یا همان شناسنامه‌ی اپ که اطلاعات یک اپ خاص را به همراه اپ‌های مرتبط، لینک رسانه‌ها، تعداد نصب و هر چیز مرتبط با اپ جمع می‌کند و یک‌جا به کلاینت تحویل می‌دهد.ویدئو: فیچرهای مرتبط با ویدئو، صفحات فیلم یا اپیزود یک سریال، امکان پخش ویدئو و غیره.پرداخت: فیچرهای مرتبط با خرید محصول (از طریق وب‌سایت فقط می‌توان ویدئو خریداری کرد).ظهور یک باریستانام سرویس وب‌سایت جدید کافه‌بازار را «باریستا» گذاشتیم؛ بالاخره کافه نیاز به یک باریستا هم داشت. استک فرانت‌اند را بعد از بحث و بررسی vue/nuxt انتخاب کردیم. دلیل انتخاب vue یکپارچگی با بقیه‌ی پروژه‌های فرانت‌اندی محصول بازار بود تا در آینده که احتمالاً افراد دیگر هم درگیر می‌شوند، سربار یادگیری و جابجایی بین دو framework متفاوت را نداشته باشند. انتخاب nuxt هم با توجه به نیاز SSR بود که در بخش «دغدغه‌های SEO» به آن پرداخته خواهد شد.چالش جدی درون وب‌سایت نمایش لیست‌های فهرست بود. این لیست‌ها ساختار متفاوتی دارند که از سمت بکند مشخص می‌شود؛ می‌تواند سطری یا ستونی باشد، عناصر می‌توانند اپ، فیلم، سریال یا تبلیغات باشند و غیره. کامپوننت‌های فهرست را طوری نوشتیم که برای «نتایج جستجو» یا «لیست اپ‌های مرتبط» هم بتوانیم از آن‌ها استفاده کنیم. سرویس‌های «سرچ» و «فهرست» و «سجل» (بخش اپ‌های مرتبط) ساختار داده‌ی یکسانی نداشتند و باید این دیتاها همسان‌سازی می‌شد که در لایه‌ی api این کار را انجام دادیم (در بخش ارتباط با بکند بیشتر به این موضوع خواهیم پرداخت).همچنین ریکوئست زدن داخل کامپوننت‌های vue را تا جای ممکن به asyncData که nuxt روی کامپوننت‌های page ارائه می‌دهد محدود کردیم و wrapper نوشتیم تا در صورت بروز هر گونه خطا در برقراری ارتباط با سرور، خطای مناسبی به کاربر نمایش دهیم (انواع خطاها نیز در لایه‌ی api همسان‌سازی می‌شوند و همیشه ساختار یکسان و قابل پیش‌بینی‌ای دارند). بدین ترتیب لازم نبود هر بار سناریوی خطاهای مختلف را بصورت جداگانه بررسی کنیم.ارتباط با بکندزمانی که وب‌سایت جدید را کلید زدیم، وضعیت چندان جالب نبود. apiها و پروتکل ارتباطی در حال تغییر بودند، فهرست هنوز پشت دیلماج نبود و باید json-rpc ریکوئست میزدیم، فیچرهایی مثل اکانت هنوز در حال توسعه بود و مایکرو‌سرویس جدا نشده بود. علاوه بر مشکلات پروتکل ارتباطی، خود سرویس‌ها هم خروجی متفاوتی برای موضوعات مشترک می‌دادند. مثلاً «لیست اپ‌های مرتبط» یا «نتایج جستجو» که از نظر ظاهری قرار بود شبیه «لیست‌های فهرست» رندر شود، ولی ساختار داده‌ی متفاوتی را برمى‌گرداند و مواردی از این دست.تصمیم بر این بود که در آینده این مسائل سمت بکند اصلاح شود؛ ولی همیشه مسأله‌ی پشتیبانی از نسخه‌های قدیمی «کلاینت اندروید بازار» این مسیر را دشوار و سخت می‌کند. اگر ساختار داده‌ی خروجی یك api تغییر کند، باید همچنان مثل قبل به کلاینت‌های قدیمی ارسال شود؛ تا زمانی که آن نسخه از کلاینت اندروید منسوخ شود و اصطلاحاً force update دهيم تا کاربرها مجبور به آپدیت به نسخه‌ی جدید شوند. البته این force update دادن معمولاً پر‌هزینه است و آسان نیست (آخرین بار فکر می‌کنم سال‌ها پیش دادیم). علاوه بر این ‌minimum sdkی کلاینت اندروید بازار بالا رفته و بعضی نسخه‌های قدیمی اندروید را باید همچنان با نسخه‌های قدیمی کلاینت پشتیبانی کنیم.با توجه به این مسائل باید از ابتدا به فکر راهکاری می‌بودیم تا در آینده این سبک تغییرات api هزینه‌ی زیادی برای نگهداری وب‌سایت کافه‌بازار نداشته باشد و با هر تغییر api مجبور نباشیم تعداد زیادی کامپوننت را آپدیت کنیم. راهکاری که انتخاب کردیم این بود که داخل باریستا یك لایه‌ی api نوشتیم که بعد از ریکوئست زدن، کل دیتاها را normalize کند و با ساختار همسان به کامپوننت‌ها برگرداند؛ با اين روش کامپوننت‌ها دیگر وابستگی مستقیم به apiهای بکند نداشتند. این لایه‌ی api کاملاً مستقل از framework فرانت‌اندی نوشته شد تا در آینده در صورت نیاز reusable باشد. تمامی کدهایی که وظیفه normalize کردن دارند را هم wrap کردیم تا در صورت بروز خطا، صرفاً به sentry لاگ بفرستند و از قسمت مشکل‌دار داده (به دلیل تغییرات احتمالی بکند) صرف‌نظر کنند.همچنین به این لایه امکان cache اضافه کردیم تا در کامپوننت‌ها (تا جای ممکن) نیاز به store نداشته باشیم (سادگی پیاده‌سازی) و نگران بهینه‌سازی ریکوئست تکراری زدن هم نباشیم.لایه‌ی API: شکستن دیتای سرویس‌ها و همسان‌سازی برای استفاده در کامپوننت‌های فرانت‌اندپشتیبانی از مرورگرهابا توجه به تعداد زیاد کاربران کافه‌بازار، گستره‌ی مرورگرهای مورد استفاده هم خیلی وسیع است. بیشتر کاربرها موبایلی هستند و با هدف دانلود اپ بازار وارد وب‌سایت می‌شوند؛ در نتيجه صفحه‌ی دانلود اپ بازار مهم‌ترین قسمت وب‌سایت از دید محصولی است که تحت هر شرایطی باید درست کار كند.با توجه به این مسائل کاربران وب‌سایت را به دو دسته تقسیم کردیم: ۱. کاربری که از مرورگر مدرن استفاده می‌کند و می‌توانيم وب‌سایت را به او نشان دهيم. ۲. کاربری که از مرورگر قدیمی استفاده می‌کند و باید مستقیماً به صفحه‌ی دانلود هدایت شود.صفحه‌ی دانلود را بدون استفاده از library خاصی و به‌گونه‌ای که روی قدیمی‌ترین مرورگر‌ها هم درست کار کند نوشتیم. برای بقیه‌ی وب‌سایت، browserslist داخل پروژه را با توجه به گستره‌ی مرورگرهایی که تصمیم داشتیم پشتیبانی کنیم کانفیگ کردیم و از پلاگین eslint-plugin-compat استفاده کردیم تا مطمئن باشیم کدهایی که می‌نویسیم این مرورگر‌ها را پشتیبانی می‌کند. در ادامه سمت سرور و با استفاده از browserslist-useragent و شناسایی مرورگر کاربر، در صورتی که مرورگر در لیست پشتیبانی شده نبود، کاربر را به صفحه‌ی دانلود اپ بازار هدایت کردیم (هر دوی این libraryها از browserslist داخل پروژه استفاده می‌کنند).البته تحت شرایط دیگرى هم کاربر به صفحه‌ی دانلود هدایت می‌شود تا تشویق به نصب شود. اگر user-agent اندروید باشد و صفحه‌ی باز شده مرتبط به اپ‌های اندروید باشد، نسخه pwa را باز نکرده باشد، اگر خودش روی لینک «باز کردن وب‌سایت» در صفحه‌ی دانلود کلیک نکرده باشد و غیره. آیتم‌های صفحه‌ی دانلود بازار (لینک دانلود فایل apk) هم با توجه به user-agent و نسخه‌ی اندروید کاربر می‌تواند متفاوت باشد (یک فایل ejs با توجه به یک کانفیگ رندر می‌شود تا انتشار کلاینت نیاز به انتشار وب‌سایت نداشته باشد).اطمینان از پشتیبانی مرورگر به کمک linterدغدغه‌های SEOبعد از صفحه‌ی دانلود اپ بازار، مهم‌ترین کاربرد وب‌سایت، جذب کاربران از طریق موتور جستجو است. وب‌سایت‌هایی که SPA نوشته می‌شوند (سمت مرورگر رندر می‌شوند) احتمال دارد توسط برخی از crawlerها به درستی رندر نشوند (گوگل در سال ۲۰۱۵ اعلام کرده كه جاواسکریپت رندر می‌کند اما بعداً در سال ۲۰۱۹ پیشنهاد داده كه به هر حال بهتر است رندر سمت سرور هم داشته باشیم). علاوه بر موتور جستجو، سرویس‌های دیگرى (همچون شبکه‌های مجازی) هم هستند که از متادیتاها (همچون پروتکل opengraph) برای نمایش بهتر لینک‌ها استفاده می‌کنند.بنابراین لازم است که صفحات سایت سمت سرور هم رندر شوند و html خالی به کلاینت ارسال نشود. این رندر کردن می‌تواند به روش‌های مختلفی اتفاق بیافتد. یک راه حل ساده استفاده از ابزارهایی مثل puppeteer و rendertron و prerender و غیره است که به عنوان سرور جدا بالا باشند و بر اساس user-agent تصمیم بگیریم که صفحه‌ی pre-render شده را برگردانيم یا نسخه SPA را.فلوچارت کلی جهت پیاده‌سازی راهکار CSRمزیت این راهکار سادگی پیاده‌سازی است. اما CPU بیشتری مصرف می‌کند و مهم‌تر اینکه امکان ارائه‌ی این html رندر شده به کاربر مرورگر معمولی نیست؛ چرا که امکان rehydration این html با DOM که سمت کلاینت تولید می‌شود وجود ندارد. در نتیجه سرعت بارگذاری محتوای اولیه (اولین لحظه‌اى که کاربر می‌تواند محتوای معنادار ببیند) در مرورگر معمولی کندتر می‌شود و همچنین امکان رندر برخی متاتگ‌های وابسته به دیتا هم نیست. مورد بعدی اینکه لاجیک رندر کردن با توجه به اینکه رندر کدام سمت اتفاق افتاده نمی‌تواند متفاوت باشد؛ مثلاً تگ img یا برخی کامپوننت‌ها سمت سرور کامل رندر می‌شوند، اما سمت کلاینت به دلایل پرفرمنسی lazy-load هستند (در بخش «چالش‌های پرفرمنسی» توضیح داده شده است).راهکار دوم SSR است. با لحاظ کردن تفاوت‌های مرورگر و nodejs می‌توانيم این امکان را فراهم کنیم تا رندر شدن در یک سرور nodejs و مشابه مرورگر اتفاق بیافتد. با توجه به اینکه پیاده‌سازی SSR چالش‌ها و edge-caseهای زیادی دارد تصمیم گرفتیم از nuxt استفاده کنیم تا سرعت توسعه‌ی بالاتری برايمان به ارمغان بیاورد. به علاوه دیگر لازم نبود درگیر کارهای زیرساختی شويم (می‌خواستیم سریع‌تر به نتیجه برسیم و فرانت‌اند توسط یک نفر نوشته میشد).ساز و کار پیاده‌سازی راهکار SSRچالش دیگر، url structure سایت بود که در نسخه‌ی قدیمی چندان search engine friendly نبود، از طرفی هم وابستگی deep-linkهای کلاینت اندروید قدیم امکان تغییرات این url structure را سخت می‌کرد. با توجه به اینکه نسخه‌ی جدید اپ اندروید هم در حال بازنویسی بود، تصمیم گرفتیم سمت وب چند مدل url structure را هم‌زمان پشتیبانی کنیم و همچنان مدل قدیم را به عنوان canonical ست کنیم تا لینک‌های گوگل همچنان امکان باز شدن توسط کلاینت اندروید را داشته باشند. به این ترتیب نسخه جدید اپ می‌تواند از url structure جدید پشتیبانی کند و در آینده که نسخه‌ی قدیمی اپ منسوخ شد (force-update دادیم) آدرس canonicalها را هم اصلاح کنیم.با توجه به اینکه nuxt ساختار url را از روی فولدرها می‌سازد، یک فایل routes.json جدا شامل انواع routeها ساختیم و از روی آن روتر nuxt را extend کردیم. یک تابع کمکی هم برای تولید لینک‌های داخل کامپوننت‌ها نوشتیم که اسم و پارامترهای یک route را می‌گیرد و با توجه به routes.json و با استفاده از path-to-regexp آدرس لینک را تولید می‌کند.نسخه PWAبا توجه به اضافه‌شدن امکان تماشای ویدئو، تمایل داشتیم کاربران iOS را هم جذب کنیم و تصمیم گرفتیم نسخه‌ی PWA را با کیفیت قابل قبولی ارائه دهیم. کیفیت قابل قبول به این معنا که هم Progressive باشد و هم Responsive، جابجایی بین صفحات سریع باشد (SPA)، سایت بدون دسترسی به اینترنت قابل نمایش باشد (Offline Mode)، لینک دادن به صفحات مختلف سایت ممکن باشد، قابلیت نصب توسط مرورگر به کاربر اعلام شود و ...پیشرو (Progressive)پیشرو بودن به این معنی است که گستره‌ی مرورگرهای قدیمی مورد استفاده توسط کاربران، نباید باعث شود از امکانات جدید مرورگرها استفاده نکنیم و کدبیس legacy تولید کنیم. اصل کد با syntax مدرن نوشته شود اما برای پشتیبانی مرورگرهای قدیمی transpile شود و apiهای جدید تا جای ممکن polyfill شوند. اگر در مواردی امکانش نبود (برخی امکانات css)، سایت همچنان قابل استفاده باشد و اصطلاحاً downgrade شود. البته حداقل را روی مرورگرهایی گذاشتیم که flex-box را پشتیبانی می‌کنند.پاسخگو (Responsive)برای سایز موبایل، تبلت و دسکتاپ تجربه کاربری متناسبی ارائه دهیم. نمونه‌ی آن کامپوننت دراور موبایلی است که در سایز کوچک جایگزین navbar بالای سایت می‌شود. یا دکمه‌ی back گوشی که باعث بسته شدن مودال‌ها می‌شود. یا صفحات اپ/ویدئو و غیره که با توجه به سایز مرورگر، خودشان را تطبیق می‌دهند.قابل کشف (Discoverable)برای اینکه مرورگر امکان نصب نسخه PWA را به کاربر نمایش دهد، یک روش هندل کردن رویداد beforeinstallprompt توسط برنامه‌نویس است که پیاده‌سازی اصولی آن نیازمند تحقیق و بررسی بیشتر بوده و هنوز این راهکار را پیاده‌سازی نکرده‌ایم.راه دیگر، تنها ارائه‌ی فایل manifest.json است که اپلیکیشن بودن سایت را اعلام می‌کند. با توجه به اینکه چندین نسخه از وب‌سایت همواره فعال است (استیجینگ برای تست داخلی، بتا تست بیرونی و نسخه پروداکشن)، این فایل با توجه به نسخه باید متفاوت باشد تا لوگو/عنوان نسخه‌های PWA متفاوت باشد.یک راهکار این بود که این فایل در پایپلاین CI و با توجه به یک متغیر env متفاوت تولید شود، راه دیگر این بود که توسط سرور node و به‌صورت داینامیک (با توجه به hostname) تولید شود. با توجه به استراتژی انتشار، راه دوم را انتخاب کردیم که در ادامه بیشتر آن را توضیح خواهیم داد.قابل پیوند (Linkable)تمامی صفحات سایت لینک داشته باشند و بتوان لینک‌ها را به اشتراک گذاشت. لازمه‌‌ی این کار آن است که تا جای ممکن از store یا state داخل کامپوننت استفاده نشود. حتی زبان سایت از طریق url مشخص می‌شود تا لینک دادن به زبانی خاص از یک صفحه ممکن باشد (در این مورد توانایی پشتیبانی از hreflang هم حائز اهمیت بود).مستقل از اتصال به شبکه (Offline-Mode)در صورت عدم اتصال اینترنت، نسخه‌ی PWA باید به‌صورت مینیمال باز شود و شبیه اپ واقعی رفتار کند (دایناسور معروف دیده نشود). لیست assetها در پایپلاین build تولید شده و داخل فایلی ذخیره شوند تا بعد از اولین بارگذاری pre-cache شود و در صورت نبود اینترنت سایت بالا بیاید.همچنین نمی‌توانستیم تمامی صفحات و routeها را pre-cache کنیم؛ nuxt هم بعد از رندر SSR، سمت کلاینت و بر اساس url رندر مجدد انجام نمی‌دهد. با توجه به این مسأله لازم بود که یک آدرس مصنوعی dummy وجود داشته باشد که نسخه‌ی SPA است و SSR روی آن همواره غیر فعال است (سمت مرورگر و بر اساس آدرس رندر می‌شود). این آدرس به عنوان navigation route برای workbox رجیستر و pre-cache می‌شود. بدین ترتیب برای تمامی navigationهای سمت کلاینت همین آدرس رندر می‌شود و وقتی دسترسی به اینترنت وجود ندارد، تمامی صفحات می‌توانند تشخیص دهند و پیغام خطای مناسب را در قالب اپلیکیشن نمایش دهند.ریلود خودکاریک مسأله‌ی مهم در ارتباط با service worker، مشکلات عملکردی دکمه ریلود مرورگر است. مایل بودیم بعد از هر انتشار، حتی اگر چندین تب از وب‌سایت فعال است همگی ریلود شوند و نسخه‌ی جدید را نمایش دهند. برای حل این موضوع زمانی که مرورگر، service worker جدید را تشخیص می‌دهد، از طریق service worker به همه‌ی تب‌های باز دستور ریلود شدن ارسال می‌کنیم.همچنین برای مواقع ضروری یک api روی سرور node اضافه کردیم که شماره نسخه فعلی باریستا را برمی‌گرداند، و سمت فرانت بصورت دوره‌ای (هر ۱۰ دقیقه یک بار) این api را فراخوانی می‌کنیم تا در صورتی که قسمت minor یا major در نسخه تغییر کرده بود، cache و localStorage پاک و صفحه ریلود کامل شود. این مساله برای مواقعی است که ساختار داده‌ای که در cache یا localStorage ذخیره می‌شود در نسخه‌ی جدید عوض شده (مثلا داده‌ای که به صورت عددی ذخیره شده، باید آرایه باشد) و به خطا می‌خوریم.ارتباطات کلاینت/سرور باریستا برای پیاده‌سازی PWAاستراتژی انتشاراستراتژی انتشار نهایی هم بدون چالش نبود. تصمیم داشتیم همواره یک انتشار جدا برای تست انسانی قبل از انتشارهای نهایی داشته باشیم و بعد از اطمینان از اینکه همه چیز به درستی پیاده‌سازی شده (فیچر، ui و غیره) همین نسخه را به پروداکشن انتقال دهیم. کاربر فعال وب‌سایت در لحظه چیزی بین ۳ تا ۱۲ هزار نفر است و با توجه به اینکه مدام روی وب‌سایت تغییرات داریم، به دنبال راهکاری بودیم تا در لحظه‌ی انتشار down-time نداشته باشیم و هیچ کاربری به مشکل برنخورد.استراتژی متداول انتشار سرویس‌های بکندی روی کوبرنتیز Rolling Deployment است. به این ترتیب که podهای نسخه‌ی قدیم کم‌کم با نسخه‌ی جدید جایگزین می‌شوند و طی مدتی محدود نسخه‌ی قدیم و جدید همزمان فعال است. این استراتژی برای وب‌سایت این مشکل را ایجاد می‌کرد که ممکن بود مثلا ریکوئست یک صفحه‌ html و ریکوئست assetهای آن به podهای نسخه‌های مختلف ارسال شود و در نتیجه برخی assetها خطای ۴۰۴ بگیرد (نام فایل‌ها content-hash است و احتمال دریافت فایل اشتباه وجود ندارد).این مسأله بعداً از طریق آپلود فایل‌های استاتیک روی CDN هم قابل حل بود (هم‌زمان assetهای چندین نسخه می‌تواند در یک bucket موجود باشد)، اما باز هم مشکل برای فایل service worker وجود داشت (باید از مسیری دریافت شود که قرار است ریکوئست‌هایش را کنترل کند و نمی‌تواند روی CDN ریخته شود) و ممکن بود انتشار جدید، از service worker مربوط به انتشار قدیم استفاده کند و لیست فایل‌هایی که باید pre-cache شوند اشتباه باشد.در نتیجه بهترین راهکار، پیاده‌سازی استراتژی انتشار آبی/سبز بود. به این شکل که در لحظه دو نسخه به‌صورت موازی بالا است و بعد از trigger توسط gitlab-ci با هم جابه‌جا می‌شوند. یکی از نسخه‌ها (آبی یا سبز) به عنوان نسخه‌ی پروداکشن (با چند replica) و دیگری به عنوان نسخه‌ی استیجینگ (یک replica) کاربرد خواهد داشت.استراتژی دپلویمنت آبی/سبز برای انتشار آنی و Zero-Downtimeاین استراتژی (جابجایی آنی deployment) روی باقی تصمیمات معماری هم تاثیرگذار است. مهم‌ترین تاثیر آن این است که همواره فقط یک build واحد می‌تواند وجود داشته باشد و نمی‌شود با توجه به متغیرهای env خروجی‌های متفاوتی تولید کرد. اگر جایی لازم باشد، باید خروجی به‌صورت داینامیک و بر اساس hostname که ریکوئست می‌آید تولید شود. مواردی از جمله:مقدار ua-id که برای google analytics استفاده می‌شودعنوان نسخه‌ی PWA که می‌توان روی گوشی نصب کردهدر X-Robots-Tag که ارسال می‌شود و مجوز crawl شدن را برای نسخه‌های بتا و استیجینگ به موتور‌های جستجو نمی‌دهدو غیره.چالش‌های پرفرمنسبعد از انتشار وب‌سایت متوجه یک سری مشکلات پرفرمنسی در مرورگر و همچنین سمت سرور شدیم که برای هر کدام باید چاره‌ای می‌اندیشیدیم. سمت مرورگر اینترنت مصرفی بالا بود و بارگذاری کامل صفحات نسبتاً زمان‌بر بود. سمت سرور هم به‌خاطر رندر SSR مصرف CPU خیلی بالا بود و هر از چندی podها توسط کوبرنتیز کُشته و منجر به downtime می‌شد. برای هر کدام از موارد فوق راهکارهایی در نظر گرفتیم.استراتژی باندلینگحجم باندل js تولید شده بزرگ بود و تقریباً نیمی از آن مربوط به video-js بود که فقط برای صفحات ویدئو استفاده کرده بودیم. برای حل این مسأله، فایل‌های js بزرگ را Dynamic Import کردیم تا تنها در زمان نیاز دانلود شوند، webpack را هم کانفیگ کردیم (از طریق nuxt) تا کدهای vendors و common به‌صورت باندل‌های جداگانه ساخته شوند و سمت مرورگر بهتر cache شوند. با توجه به اینکه صفحات مختلف سایت از کامپوننت‌های عموماً یکسانی استفاده می‌کنند، جدا کردن chunk صفحات آورده‌ی چندانی نداشت و همه را در یک فایل build کردیم.تصاویر Responsive و Lazyاکثریت صفحات وب‌سایت دارای تصاویر زیادی هستند. در بکند چندین سایز از تصاویر اپ‌ها موجود است، سمت فرانت باید از امکانات جدید html5 برای نمایش responsive تصاویر استفاده می‌کردیم تا کاربر با توجه به سایز صفحه، کوچکترین تصویری که با کیفیت خوب نمایش داده می‌شود را دریافت کند. همچنین تصاویر باید lazy-load می‌شد تا فقط در صورتی که در صفحه دیده می‌شوند از سرور دریافت شوند.برای حل این موضوع یک کامپوننت LazyImg نوشتیم که سایز پیش‌فرض را به عنوان پارامتر می‌گیرد و تا وقتی دیده نمی‌شود، به عنوان تصویر پیش‌فرض یک مربع خاکستری رندر می‌کند (یک data-uri که از روی svg string تولید شده است). بعد از اینکه تصویر دیده شد (احتمالاً بعد از اسکرول)، تگ picture با سایزهای responsive رندر می‌شود.وجود تصویر پیش‌فرضی که نیاز به ارتباط با سرور ندارد و به عنوان src ست می‌شود، باعث می‌شود مرورگر تا لحظه‌ای که تصویر اصلی کاملاً لود نشده، همان پیش‌فرض را نشان دهد و در نتیجه در حین لود شدن تصویر، لایوت صفحه جابجا نشود و حس بدی را به کاربر منتقل نکند.در این کامپوننت همچنین امکان auto-reload را هم گذاشتیم که اگر بارگذاری تصویر به دلیل اختلالات شبکه/اینترنت به خطا خورد، پس از وقفه‌ای کوتاه خودش تلاش مجدد را انجام دهد و نیاز به ریلود صفحه توسط کاربر نباشد. برای همه‌ی تصاویر داخل وب‌سایت از این کامپوننت استفاده کردیم که حجم اینترنت مصرفی را به میزان قابل توجهی کاهش داد.تصاویر lazy-load، یک راهکار بهینه‌سازی پرفرمنس در مرورگرانتقال Assetها به CDNغیر از تصاویر اپ‌ها که توسط سرویس‌های دیگری نگهداری و به CDN منتقل می‌شود، تعداد assetهای تولید شده‌ی باریستا کم نبود. از فونت‌ها و تصاویر لوگو و غیره گرفته تا فایل‌های js/css که در فرایند build تولید می‌شوند. قبلاً این فایل‌ها توسط nginx که داخل pod باریستا بود serve می‌شد. اوایل که باریستا را منتشر کردیم، service worker را غیرفعال کرده بودیم و مشکل حادی نداشتیم. اما بعداً که تصمیم گرفتیم service worker را هم فعال کنیم، بخاطر pre-cache شدن assetها تعداد ریکوئست‌هایی که به pod می‌آمد تا حدود ۲ برابر زیاد شد.بنابراین تصمیم گرفتیم در فرایند build تمامی فایل‌های static تولید شده را به CDN کپی کنیم که در نهایت باعث کاهش ۳۰درصدی مصرف CPU روی pod باریستا شد.ماژول Cache برای رندرهای SSRبرخی صفحات خاص (مثل اپ‌هایی که کاربران زیادی از سایت‌شان به بازار می‌آیند، یا صفحه‌ی اصلی بازار، یا صفحاتی که روی آن‌ها کمپین تبلیغاتی می‌رفتیم)، تعداد ریکوئست زیادی داشتند و هر بار رندر SSR هزینه‌ی زیادی داشت. بنابراین برای nuxt یک ماژول cache نوشتیم که صفحات رندر شده را داخل redis به مدت یک ساعت نگه می‌دارد و ریکوئست‌های بعدی از این cache استفاده می‌کنند.رندرهای SSR هوشمندبا وجود همه‌ی راهکارهای فوق، همچنان بار روی سرور باریستا زیاد بود. هر از چندی که ریکوئست‌ها peak می‌زد (به صفحات متنوع، نه یکسان)، مصرف CPU بعضی podها بالا می‌رفت و کوبرنتیز pod مربوطه را می‌کُشت و تا pod دوباره بالا برگردد، بار روی باقی podها تقسیم می‌شد؛ در نتیجه قبل از بالا اومدنِ pod کشته شده، باقی podها مثل دومینو یکی بعد از دیگری کُشته می‌شد و بعد از چند بار کُشته شدن در CrashLoopBackOff می‌افتاد و وب‌سایت کاملاً down می‌شد.برای حل این مسأله یک دقیقه زمان warmup تعیین کردیم که پس از بالا آمدن pod، در این بازه رندر SSR انجام ندهد. به این ترتیب بعد از بالا آمدن مجدد، این فرصت فراهم بود که تا زمانی که باقی podها هم بالا بیاید، مصرف کمتری داشته باشد و کُشته نشود.در ادامه rate-limit روی رندرهای SSR گذاشتیم که تعداد رندرهای SSR برای هر IP در دقیقه را محدود کنیم. همچنین podها مصرف CPU خودشان را مانیتور کنند و در صورتی که مصرف CPU در یک ثانیه گذشته آن‌ها بیشتر از ۸۰ درصد شد، SSR ارائه ندهند.روند کلی و ساده‌شده‌ی رندرهای SSR هوشمندنتیجه نهاییوقتی یک محصول با کیفیت مناسب پیاده‌سازی و اجرا شده باشد، در بهترین شرایط هم نباید توقع تمجید را از سوی کاربر داشته باشیم. درست کار کردنِ یک سیستم انتظار طبیعی هر کاربری است، اما اگر کوچکترین اشتباهی رخ دهد باید منتظر انتقاد و نارضایتی باشیم. خوشبختانه در مورد وب‌سایت جدید بازار (با وجود کاربران زیاد) اعلام نارضایتی ناچیز بود و آمار دانلودی که در نظر داشتیم آسیبی نبیند، حتی برای مدتی رشد ۱۰-۱۵ درصدی داشت. (البته این آمار بعداً به روال معمول قدیم برگشت).پایداری سرویس‌هایی که روی کوبرنتیز هستند، نسبتاً بالاست. هر سرویس چندین replica دارد و درصورتی که هر کدام از آن‌ها به مشکل بربخورند، باقی podها پاسخگو هستند تا اینکه کوبر pod جدیدی بالا بیاورد. بزرگترین مسأله‌ی باریستا محدودیت منابع بود که هر از چندی منجر به down شدن می‌شد و بعد از پیاده‌سازی cache و warmup و rate-limit به‌طور کامل برطرف شد. پایداری بالایی که آخر هفته‌ی آرام و بدون استرسی را برایمان به ارمغان آورد.در عین حال شاید بتوان گفت که مهمترین موفقیت حاصل از بازنویسی وب‌سایت، خلاصی از یک سیستم legacy بود که امکان توسعه‌ی بیشتر را واقعاً سخت کرده بود.در کافه‌بازار هنوز راهی طولانی در پیش داریم و روز به روز با چالش‌های جدیدتری روبه‌رو می‌شویم. سرویس‌های فرانت‌اندی زیادی هستند که یا هنوز نوشته نشده‌اند و یا نیاز به بازنویسی دارند. اگر به زمینه‌ی فرانت‌اند علاقه‌مند هستید، برای همراهی ما در این مسیر به ما بپیوندید.</description>
                <category>آرش شاکری</category>
                <author>آرش شاکری</author>
                <pubDate>Sun, 29 Dec 2019 18:23:03 +0330</pubDate>
            </item>
                    <item>
                <title>بیش از یک سال در کافه‌بازار</title>
                <link>https://virgool.io/@arash.shakery/%D8%A8%DB%8C%D8%B4-%D8%A7%D8%B2-%DB%8C%DA%A9-%D8%B3%D8%A7%D9%84-%D8%AF%D8%B1-%DA%A9%D8%A7%D9%81%D9%87%D8%A8%D8%A7%D8%B2%D8%A7%D8%B1-sdlnubljqtia</link>
                <description>توی این بلاگ می‌خوام راجع به تجربه‌ی یک سال گذشته‌م توی کافه‌بازار بنویسم. بخش اول خاطرات و چگونگی ورودم هست، بخش‌های بعدی هم کلیاتی راجع به فرایند‌های داخل شرکت می‌نویسم. این نوشته صرفا دیدگاه و تجربه شخصی خودم هست و ممکنه دقیق نباشه.مقدمهمن یه برنامه‌نویسم. از حدود ۸ سالگی (۲۲ سال پیش) شروع کردم که پدرم یه commodore 64 خرید. از دوران ماقبل ms-dos رو دیدم و win3.1 و ۹۵ و ۹۸ گرفته تا زمانی که اینترنت dial-up اومد با اون صدای جیغ معروفش. با gw-basic شروع کردم و پاسکال و دلفی و php و دات‌نت و بعدها نود رو هم قورت دادم. دورانی که gmail اومد رو یادمه، یاهو مسنجر که دیگه دوران مدرن بود، orkut رو هم یادمه و خیلی خاطرات دیگه. هیچوقت اهل درس و مدرسه نبودم و کلا سرم توی کامپیوتر و مجلات کامپیوتر اون زمان بود.آخرین بار سال ۹۲ تا ۹۴ بود که برای ارشدم تهران بودم و بعدش برگشتم شهرستان و حتی یه مدتی هم برای ریکاوری رفتم یه روستایی تنهایی زندگی کنم و برای دل خودم کد بزنم. دفعه اولم هم نبود، قبل از کارشناسی هم یک سالی رفتم روستا تنهایی زندگی کنم. همیشه با شهرنشینی بخصوص از نوع شلوغ و پر از دودش مشکل داشتم، مترویی که همه در حال دویدن هستن، ترافیک‌هایی که برای رفتن به هر جایی باید ۲ ساعت تو راه باشی و …همین ۱۳ سال پیش در حال حل کردن چالش‌های HackThisSiteاز مصاحبه تا آنبوردینگنزدیک عید سال ۹۷ تصمیم گرفتم برای کار برگردم تهران و دوباره تو فضای کار باشم بلکه تجربه عملی بیشتری کسب کنم. بعد از مدت‌ها فاصله گرفتن کلاً توی باغ نبودم، از طریق جابینجا یه چند تا شرکت نوپا اپلای کردم و مصاحبه رفتم. به غیر از یه مورد همگی اوکی دادن ولی با فضای کاریشون نمی‌تونستم کنار بیام و خودم قبول نکردم. تا اینکه یکی از دوستام کافه‌بازار رو پیشنهاد داد اپلای کنم. تنها چیزی که به ذهنم می‌رسید یه لوگوی فندق مانند بود :دی. دوستم تعریف کرد که شرکت خوبیه، رفتم توی سایتش و اپلای کردم.بعد از مدتی منیره برای ست کردن مصاحبه تلفنی زنگ زد، تصویر آخرین مصاحبه‌ی حضوری که رفته بودم اومد جلو چشمم: یه سری میز مدیریتی مشکی، صندلی‌های چرمی قهوه‌ای، یه اتاق که چند تا برنامه‌نویس پای یه میز رو به دیوار نشستن، یه اتاق که یه مدیر از خود راضی داخلش تنهایی نشسته با یه منشی که بیرون اتاقش نشسته و تلفن دستشه.خلاصه مصاحبه تلفنی با مهتدی ست شد. تازه خونه‌م رو تحویل گرفته بودم (تهران‌پارس) و مهمون اومده بود که مهتدی زنگ زد و صحبت کردیم (جزییاتش دقیق یادم نیست، بیشتر سوالات فنی بود). بعد از چند وقت دوباره منیره تماس گرفت که برای مصاحبه حضوری برم و اوکی دادم. شب قبل مصاحبه خونه یکی از دوستام بودم و تا صبح بیدار بودیم، روز بعد خسته بودم حوصله مصاحبه رفتن نداشتم و نرفتم (خبر هم ندادم). منیره زنگ زد که چرا نیومدی؟ مکالمه دقیق یادم نیست، ولی یه بهونه آوردم که خونه‌م دوره و فلان (بعد از مدتی زندگی توی روستا واقعا خیلی برام سخت و دور بود)، قرار شد فکر کنم اگه نظرم قطعی شد خبر بدم که بالاخره میرم یا نه؟ گفت الکی مصاحبه برام ست نشه (فکر کنم از دستم عصبانی هم شده بودن :دی). بعدش یکم فکر کردم دوباره زنگ زدم گفتم یه مصاحبه دیگه ست بشه.مصاحبه بعدی با ارسطو بود. رفتم محل حدودی شرکت رسیدم، یه ساختمان بزرگ بود. با خودم گفتم بعیده این باشه، اون دور و بر رو نگاه کردم یه ساختمون دیگه دیدم که به اندازه وب‌سایت کافه داغون بود :دی حدس زدم اونه ولی ورودیش معلوم نبود. آخرش دوباره زنگ زدم منیره پلاک رو پرسیدم که فهمیدم همون ساختمون بزرگه‌س. وقتی وارد شدم همچنان شک داشتم، با خودم گفتم لابود ساختمون تجاریه و داخلش چند تا شرکت مختلف هستن. صندلی‌های رنگی، فضای شاد، آدم‌هایی که همه تی‌شرت پوشیدن و … تو همین فکرا بودم که بالاخره ارسطو اومد رفتیم اتاق مصاحبه. یه سری اتاق شیشه‌ای بود که هر کدوم یه میز کوچیک و چند تا صندلی رنگی فانتزی داشت. یکم سوالات فنی، یکم سوالات غیر فنی، خفن‌ترین کاری که کردی چی بوده و فلان. ارسطو هم شخصیت خوش‌برخورد و نسبتا پرانرژی داشت و حس مثبت گرفته بودم. در انتهای مصاحبه بهش گفتم ترجیح میدم برای بکند مصاحبه بدم (رزومه هم سافتور فرستاده بودم) گفت میتونه با بچه‌ها صحبت کنه یه مصاحبه بکند برام ست بشه و خلاصه تموم شد رفتم خونه.چند وقت بعد دوباره منیره زنگ زد، استرس و نگرانی مشکلات شخصی (داستانش طولانیه) همچنان توی ذهنم بود، زیاد دقت نکردم چی میگه و صرفاً تاریخ و ساعت مصاحبه بعدی یادم موند. این بار شب قبل مصاحبه چند تا فریمورک بکندی nodejs نگاه انداختم که آماده باشم اگه پروژه‌ای چیزی دادن دستم سریع باشه. با مهتدی و هاشم بود، وسط مصاحبه مهتدی یهو یه سؤال cssی ازم پرسید، با تعجب پرسیدم مگه مصاحبه فرانته؟؟ گفت آره این مرحله دومشه! (بعدها ایمیلم رو چک کردم دیدم گویا عنوانش هم فرانت‌اند بوده که نخونده بودم :دی). خلاصه در حدی که یادم بود جواب دادم، در نهایت یه پروژه هم دادن که با ری‌اکت زدم. هاشم میپرسید چرا با vue نمیزنی؟ (توی رزومه فکر کنم اونو حرفه‌ای‌تر زده بودم) گفتم تازگی یه پروژه react nativeی انجام دادم و بیشتر آمادگی دارم. آخر مصاحبه راجع به حقوق درخواستی هم پرسیدن. گفتم نمیدونم، رنج پرداختی شما تقریباً چجوریه؟ هاشم گفت فلان تومن، منم گفتم اوکی و خداحافظی کردیم رفتم. یه مدت کوتاهی بعدش زنگ زدن که اکسپت شدی و جلسه آفر ست شد، این بار با وحید بود. اومد یکم از ارزش‌های شرکت گفت (اون لحظه با خودم فکر می‌کردم در حد شعار باشه) و یه توضیحات کلی داد. راجع به تیمی که قرار بود برم گفت و اینکه توقع زیادی ازم دارن که بتونم خوب پیش ببرم. یه مبلغ آفر گفت که از چیزی که هاشم گفته بود بیشتر بود و خلاصه قبول کردم. پرسید از کی میتونی بیای؟ گفتم هفته بعد، شروع به کارم خورد ۱۶ تیر که روز تولدم هم بود.تا اینجاش کلاً جدی نمیگرفتم، فرضم این بود که فوقش میخوام ۳ ماه اینجا بمونم، هیچوقت نمی‌تونستم با زندگی کارمندی کنار بیام. روز آنبوردینگ رفتم شرکت. توی لابی منتظر بودم که مهرناز (یه شخصیت فوق خوش‌برخورد و خوش‌خنده) اومد و با چند نفر دیگه که اونا هم تازه استخدام شده بودن کل شرکت رو نشونمون داد. اتاق‌های جلسات که شیشه‌ای بود و از بیرون داخلش دیده می‌شد با همون صندلی رنگی‌های فانتزی، هر طبقه یه اتاق استراحت که دو تا تخت داشت، آشپزخونه و کمد وسایل تحریر و سیم و کابل و غیره. غیر از راهروها جایی دوربین نداشت، همه چیز کلا آزاد بود و هیچ کنترل و نظارتی حس نمی‌کردی. فضا کاملا دوستانه و بر مبنای اعتماد بود، خبری از اون میزهای مدیریتی و آدم‌های کت و شلواری نبود، شبیه به چیزی بود که معمولا از فضای کار شرکت‌هایی مثل گوگل می‌بینی. مهرناز یه دوربین عکس فوری هم داشت که عکس می‌گرفتیم و بعدا با اون عکس‌ها استوجیت بازی کردیم.در انتها باید میرفتم پیش منیره که کارهای قراردادم رو انجام بده، برخورد اول که دیدمش بازم پیش‌فرض ذهنیم بهم ریخت. مشخصات و تاریخ تولد رو گفتم که تبریک گفت یه سری فرم پر کردم و تموم شد. برعکس خیلی از شرکت‌های دیگه حتی چک و سفته و تضمین و از این چیزا هم کسی ازم نخواست. خلاصه این بود فرایند استخدام تا آنبوردینگ.امیرحسین (تیم امکانات)، احتمالا داره نقشه می‌کشه چجوری اتاق‌ها رو بیشتر کنه و تیم‌ها رو جابجا کنه :دیتیم هندیتیم اولی که داخلش رفتم اکثریت هندی بودن و ریموت کار می‌کردن. داخل شرکت یه نیرو بکند بود که یه هفته بعد از اومدن من رفت، یه تیم‌لیدر، یه اسکرام‌مستر، یه دیزاینر و من که فرانت‌اند بودم و قرار بود روی نسخه‌ی وب‌اپ کار کنم. کدی که زده شده بود ری‌اکتی بود اما به معنای واقعی کلمه کثیف بود، البته وحید هم تو جلسه آفر یه چیزایی گفته بود که هندیا زدن و کدش کثیفه، ولی عظمت ماجرا رو تا وقتی کد رو ندیده بودم درک نمی‌کردم. از ابتدا پروژه بدون redux استارت زده شده بوده، بعدا redux اضافه شده و یه ریفاکتور جزئی هم شده بود. با اینکه ریداکس بود، همچنان توی خیلی از کامپوننت‌ها پراپرتی پاس‌کاری میشد. یه جاهایی نمی‌فهمیدی جریان داده چیه؟ چی از کجا میاد و کجا میره؟خلاصه بیشتر کارم اونجا به ریفاکتور و بعدش هم باگ‌فیکس گذشت. یه سری daily call داشتیم که هر روز همه‌ی تیم با اسکایپ جلسه داشتن. هر بار که daily call داشتیم یاد تک تک courseهایی می‌افتادم که به خاطر لهجه هندی بیخیال میشدم و نگاه نمیکردم. تیم هندی جدای از لهجه و سبک کدنویسی‌شون (که خودشون با هیچ‌کدوم مشکلی نداشتن :دی) آدمای دوست داشتنی و خوبی بودن و بعد از مدتی باهاشون صمیمی شده بودم.حدودا یک ماه و نیم توی این تیم بودم. توی این دوره زیاد با بقیه بچه‌های شرکت ارتباط نداشتم. یه دوره‌ی منتورشیپ هم همزمان با ورودم شروع شده بود که منتورم هاشم بود. یه سری داکیومنت فنی آموزشی که باید می‌خوندم و تمرین‌ها رو انجام میدادم که فکر کنم مجموعا یکی دو هفته‌ای تموم شد. یه بار هم مهتدی اومد خبرمو گرفت که وضعیت چجوریه و اینا. بعد از یه ماه و نیم این تیم دیسش خورد (مطمئن نیستم این «دیس» از چی میاد یا مخفف چیه، بین بچه‌ها به این معنیه که ترکید و اینا).توی این تیم که بودم یکی دو جلسه هم با حسام (آرمندهی) داشتیم. اون زمان توی تیم کناری می‌نشست. با همون سبک میز و صندلی که همه‌ی بچه‌ها داشتن، هیچ تفاوتی نداشت. یه شخصیت آروم و خونسرد و معمولی مثل بقیه.تیم رسیدتیم بعدی که رفتم «رسید» یه اپ انتقال پول بود. روی یه کدبیس react native باید کار می‌کردیم. این بار همه چیز تمیز و نسبتا مرتب بود، کل این پروژه رو مهتدی نوشته بود و خودش هم owner بود. بک‌اند و نسخه اندروید بچه‌های دیگه بودن. این تیم کلا یک ماه بودم، ولی جزو بهترین تیم‌هایی بود که داخلش بودم. بچه‌ها خیلی صمیمی بودیم، طنز و شوخی‌های دوستانه هم زیاد بود. توی این یک ماهی که بودم روی یه فیچر «دعوت از دوستان» کار می‌کردیم. کارهایی که انجام میدادم همیشه branch جدا بود و به مهتدی merge request می‌دادم، قسمت‌های زیادی رو می‌گفت اصلاح می‌کردم. روی تمیزی کد وسواس شدیدی داشت و کلا توی مباحث فنی شوخی نداشت. هر بار سر یه چالشی کسی غر می‌زد مهتدی یه جمله معروف داشت که «پول می‌گیریم همین کارهای سخت رو انجام بدیم» (نمی‌دونم جدی می‌گه یا شوخی، ولی جمله مورد علاقه‌م شده هر جا بخاطر چالشی بودن کار کسی غر بزنه منم می‌گم).بعد از یک ماه گفتن تیم ویدیو نیاز به نیروی فرانت‌اند داره، وحید اومد با باقر (تیم‌لیدر رسید) صحبت کردیم گفتن چون تازه جابجا شدی اوکیه اگه خودت دوست نداری دوباره جابجا بشی. واقعا هم حس خوبی نداشتم که برم چون تازه با بچه‌ها صمیمی شده بودم. گفتم باشه یکم فکر کنم با بچه‌ها هم مشورت کنم بعدا نتیجه قطعی‌ش رو میگم. بعدا با مهتدی و باقر صحبت کردم، مهتدی می‌گفت اگه بری برای رشد خودت بهتره چون روی یه محصول جدا و تازه کار می‌کنی کارِت بهتر دیده می‌شه، اما خوب اینجا فقط همون صمیمیت هست. خلاصه قبول کردم و با بقیه بچه‌ها صحبت کردم و یه وداع پرسوز کردیم رفتم به سفر قندهار.. نه چیز، رفتم تیم ویدیو که طبقه پایینی بود.یک هفته بعد از رفتنم خبرش اومد که دیسِ رسید هم رسید! ماجرا این بود که به اندازه کافی سود‌آوری نداشت و رقابت با رقبایی که بعضا با رابطه و ضابطه جلوی فعالیت ما رو می‌گرفتن سخت بود. باقی بچه‌ها هم جابجا شدن به «بلد» و «دیوار» و …همه می‌رفتن تیم‌سازی با هم صمیمی بشن، رسید که ترکید ما رفتیم تیم‌نابودسازی :دیتیم ویدیو (وب بازار)قرار بود محتوای ویدیویی توی اپ «بازار» اضافه بشه. بخش زیادی از بک‌اند جلو رفته بود و اندروید هم فکر کنم (دقیق یادم نیست) نسخه‌های اولیه‌ش رو داده بودن. قرار بود توی وب‌سایت کافه‌بازار هم امکان تماشای ویدیو اضافه بشه. چالش ماجرا اینجا بود که نسخه‌ی فعلی وب‌سایت در اون زمان فوق‌العاده legacy بود (پایتون و جانگو و اینا). دو تا راه جلومون بود یکی اینکه توی همون کد‌بیس امکان تماشای ویدیو رو اضافه کنیم یا اینکه کلا بکوبیم از اول بالا بیاریم. منم که قطعا راه دوم رو ترجیح می‌دادم (با توجه به حسی که به وب‌سایت اون زمان داشتم).معمولا چهارشنبه‌ی آخر هر ماه یه مراسم دورهمی کل شرکت هست به اسم چهارشنبگان. همه‌ی بچه‌ها میان پایین و یه سری سوال جواب با حسام داریم و بعدش هم پذیرایی و جوجه و بازی و غیره. سوال‌جواب‌ها معمولا حول مسائل محصولیه، چی شد رسید رو ترکوندیم؟ چرا ویدیو توی بازار که مخصوص اپ اندروید هست؟ به کاربر فعلی ضربه نمیزنه؟ مسئولیت‌های اجتماعی شرکت چیه؟ اینکه حقوق بالا می‌دیم به استارتاپ‌ها ضربه نمی‌زنه؟ و اینجور مسائل. بازی‌ها هم کنسول و بوردگیم و غیره.قبل از ورودم به تیم ویدیو توی یکی از همین مراسم چهارشنبگان بود که با هاشم قدم زدیم و کلی صحبت کردیم. راجع به آینده‌ی وب بازار و کارهایی که میشه انجام داد، فریم‌ورکی که خوبه باهاش پیش بریم و اینجور مسائل. نظر خودم این بود که با ری‌اکت باشه، اما هاشم می‌گفت توی بازار باقی محصولات vue هستن و بهتره یکپارچگی داشته باشیم. از طرف دیگه یادگیریش برای بچه‌های بکند راحت‌تره و کارهای جزئی رو خودشون میتونن پیش ببرن. راجع به seo و اهمیت ssr هم حرف زدیم، در نهایت قرار شد خودم تحقیق کنم بازم با نظر خودم باشه. رفتم یکم research کردم، برای ssr دو تا فریم‌ورک بود یکی next.js بر پایه ری‌اکت و یکی هم nuxt.js بر پایه vue. داکیومنت هر دو رو کامل خوندم، چیزی که حس کردم nuxt خیلی کامل‌تر بود و از طرفی هم حرف هاشم درست بود و vue برای یک‌پارچگی محصولی بهتر بود. در نتیجه با همین سیستم جلو رفتم.یه چالش اصلی سر راه این بود که بکند rest نداشتیم و اگه قرار بود ری‌رایت وبسایت spa باشه باید بکند rest هم نوشته میشد که اوایل مشکلات زیاد بود و کارش کند پیش می‌رفت، زیاد pend میشدم و بیکار موندن اذیت داشت. در عین حال بعد از یکی دو ماه یه نسخه اولیه ساده در‌آوردم که دیتا رو mock کرده بودم. با هاشم صحبت کردم و برای اینکه بیکار نمونم پیشنهاد داد همزمان وارد فرایند مصاحبه هم بشم.این وب‌سایت جدید تقریبا یکی دو ماه پیش ریلیز شد، اگرچه همچنان کار زیاد داره و ویدیو هم هر از چندی فیچرهای جدید میخواد و اضافه می‌کنیم.تولد ملیکا بود، دیتای تیم ویدیوالان تقریبا نزدیک به یک سال میشه که توی تیم ویدیو و با بچه‌های بازار هستم. صادقانه بخوام بگم شاید به اندازه «رسید» صمیمیت و اون شوخی‌های دوستانه نباشه، ولی شبیه به خانواده دومم شده. الان بعد از این همه مدت دیگه واقعا برام سخته بخوام روزی به رفتن فکر کنم. همین‌جوریش هم چند روز بچه‌ها رو نمی‌بینم دلم تنگ میشه و شنبه جزو بهترین روزهاست برای من.یه زمانی برام سخت بود بخوام حتی یک مزیت برای زندگی توی شهر بزرگ نام ببرم، ولی الان همکاری با آدمهایی که هر کدوم توی یه حوزه‌ای واقعا حرفه‌ای هستن چیزی بیش از لذت‌بخشه. اینکه آدم‌هایی باشن که با اطمینان بتونم بگم توی یه زمینه‌ای از من بهترن و میتونم ازشون چیزی یاد بگیرم. تیم‌های مختلف، تخصص‌های مختلف و … هر جایی یه موضوع جدید برای یاد گرفتن و تجربه کردن هست. و این‌همه مزایا بدون اینکه حتی یک بار حس کنم کارمند ساده‌ای هستم که قراره یه آقابالاسر بهم دستور بده، چیزی که همیشه ازش فراری بودم.پی‌نوشت: محتوای ویدیویی که داخل کافه‌بازار قرار داده می‌شه بصورت قانونی هست و حق تولید‌کننده‌ی اون محتوا پرداخت میشه. شرکت‌هایی که باهاشون قرارداد داریم، با یه سری شرکت‌های توزیع و پخش محتوا قرارداد دارن و اونا هم با تولیدکننده قرارداد دارن. حتی محتوایی که به کاربر بصورت رایگان ارائه می‌دیم، هزینه‌ی تماشای اون پرداخت می‌شه.آنسوی فرایند مصاحبهتقریبا هفته‌ای ۱۰-۱۵ تا رزومه برای پوزیشن فرانت‌اند میاد. اوایل فقط مصاحبه‌های تلفنی بود و دو نفره می‌رفتیم (با هاشم یا مهتدی) که اگه مساله‌ای رو رعایت نمی‌کردم بهم فیدبک بدن. چطور خودمونو معرفی کنیم؟ به سوالات مختلف مصاحبه‌شونده چه جواب‌هایی باید بدیم؟ بعد از مصاحبه به چه سبکی کامنت بنویسیم؟ از قبل بپرسیم مصاحبه‌شونده شرایط مصاحبه رو داره یا نه؟ و خیلی مسائل این سبکی که برای هر موردی معمولا تجربه‌ای بوده که باعث شده چنین تصمیماتی گرفته بشه. بعدا مصاحبه‌های مرحله یک حضوری رو دو نفره رفتیم و بعد هم مرحله دو اضافه شد. یه دوره‌ای رزومه خیلی زیاد شد و دیگه مرحله یک رو یک نفره کردیم.پلتفرم مصاحبه سایت workable هست. یه بکند داره، داخلش یه سری پوزیشن هست که هر کدوم یه پایپلاین مشخصی داره. وقتی کسی رزومه ارسال می‌کنه وارد مرحله اول پایپ‌لاین می‌شه، یه نفر مسئول بررسی رزومه هست. در صورت تایید مرحله بعد میره و تو صف می‌مونه تا مصاحبه تلفنی ست بشه (پوزیشن‌های دیگه ممکنه متفاوت باشن و مثلا تلفنی نداشته باشن). بچه‌هایی که مصاحبه میرن قبلا توی google calendar تایم‌های خالی خودشون رو می‌ذارن و زحمت هماهنگی با مصاحبه شونده رو بچه‌های hr می‌کشن. علت اینکه گاهی مصاحبه دیر ست میشه پر بودن تایم بچه‌هاست.بعد از ارسال رزومه، ورکبل لینک شبکه‌های اجتماعی رو از داخل رزومه در میاره و یه سری لینک‌های دیگه هم تا جای ممکن از داخل همین شبکه‌ها استخراج می‌کنه. از پروفایل‌های تخصصی مثل github و stackoverflow گرفته تا پروفایل‌های شخصی اینستاگرام و فیسبوک و غیره. شخصی که رزومه‌ها رو می‌بینه معمولا همه‌ی فعالیت‌های فنی اون شخص رو بررسی می‌کنه، نمونه کارها، کدهای اوپن سورس، سوال‌ها و جواب‌هایی که توی stackoverflow داده و reputation فرد و غیره. معمولا باید یک نقطه درخشان پیدا بشه که فرد برای مصاحبه تایید بشه، حالا یا تو شبکه‌های اجتماعی حرفه‌ای یا سوابق کاری فرد توی شرکت‌های مطرح یا نمونه‌کارهایی که قابل رویت باشه و کیفیتش خوب باشه، یا رتبه خوب در مسابقات معتبر (حداقل پوزیشن فرانت به همین شکل بررسی می‌شه).بعد از هر مرحله از مصاحبه، یه کامنت هم می‌نویسیم که تلاش می‌شه عین صحبت‌ها و سوال جواب‌ها رو تا جای ممکن بدون پیش‌قضاوت بنویسیم. خود سوالات الزاما فیکس نیستن و با توجه به مواردی که در رزومه اومده پرسیده می‌شه (نه تخصص مصاحبه‌کننده). بعدا این کامنت‌ها توی یه جلسه کمیته فنی بررسی می‌شه که تعدادی از بچه‌های فرانت هستن و نظر می‌دن خوب بوده یا نه؟ اگه روزی درگیر مصاحبه شدین، پیشنهاد می‌کنم حتما این لینک رو بخونید و به انواع بایاس آگاهی داشته باشین.توی این مدتی که درگیر این فرایند مصاحبه‌ها بودم تجربه‌ها و داستان‌ها و اتفاقات مختلفی دیدم و شنیدم. مشکلاتی که مصاحبه‌شونده‌ها داشتن و بخاطرشون شرکت قبلی رو ترک می‌کنن یا مشکلات شخصی که تعریف می‌کنند. یکی همه کارها رو تنهایی می‌کرده و در نهایت بی‌احترامی هم شده، یکی حقوقش رو ندادن دنبال شکایته، یکی استارتاپ قبلی مشکلات قانونی پیدا کرده تعطیل شده، یکی مشکلات خانوادگی داشته و افسردگی گرفته. هزار جور داستان و آدم مختلف که واقعا سخته بی‌اهمیت از کنارشون رد بشی و حس هم‌دردی نداشته باشی. قسمت سخت‌ترش وقتیه که توی کمیته بخاطر ضعف دانش ریجکت کنیم. اوایل که وارد پروسه شدم، بعد از هر مصاحبه فکرم اونقدر درگیر بود که دیگه نمی‌تونستم یه خط کد بنویسم. بعدا به پیشنهاد هاشم مصاحبه‌هام رو در انتهای روز گذاشتم که بعدش برم خونه. در نهایت هم برای کسی که ضعف دانش فنی داره، جز یه آرزوی موفقیت نمیشه کاری کرد.مواردی هم واقعا توی مصاحبه به آدم انرژی میدن. یه آدم جا افتاده یا خوش برخورد، یه جوون پر انرژی و پر انگیزه و … این موارد رو قضاوت کردن گاهی سخت‌‌تر میشه، هنوز چند مورد از آدمهایی که مصاحبه کردیم و در نهایت به خاطر ضعف فنی ریجکت کردیم رو فراموش نکردیم. صحبتش که می‌شه هنوزم می‌گیم ولی کاش فلانی رو می‌گرفتیم.چپترسازی بچه‌های فرانت بعلاوه یکیه شایعه که زیاد توی لینکدین یا شبکه‌های دیگه شنیدم اینه که سن پایین می‌گیریم یا بخاطر درخواست حقوق بالا ریجکت می‌کنیم. ماجرا اینه که از کسی که تجربه کمتری داره توقع کمتری هم داریم، اما کسی که تجربه بالایی داره (سالهایی که کار کرده) و احتمالا حقوق درخواستی بالایی گفته توقع بیشتری داریم. در مورد حقوق درخواستی بالا باز هم فرایند مصاحبه ادامه پیدا می‌کنه و فوقش توی مرحله آفر مبلغ کمتری پیشنهاد داده می‌شه که یا قبول می‌کنه یا نمی‌کنه (البته بخاطر درخواست حقوق بالا ممکنه سوالات سخت‌تر و بیشتر بپرسیم که در نهایت بتونیم تصمیم بگیریم چقدر میشه آفر داد؟). اما کسی که تجربه بالایی داره ولی توی بعضی مفاهیم پایه ضعف داشته باشه واقعا نمی‌شه انتظار داشت در آینده بتونه رفع کنه.یا مورد دیگه اینکه که مصاحبه‌شونده مشکلی داشته ولی از نگرانی اینکه ما ناراحت بشیم یا احساس بی‌احترامی کنیم کنسل نکرده و با وجود مشکلات اومده مصاحبه. والا بخدا برای مایی که آدم فنی هستیم و دوست داریم پشت مانیتور و سیستم بمونیم، یکی از بهترین خبرها وقتیه که یک مصاحبه کنسل بشه. برای ما صرفا یه تسک هست که یا کنسل شده یا عقب افتاده. در عین حال چیزی که توصیه می‌کنم اینه که حتما قبلش خبر داده بشه و کاری که خودم یه زمانی کردم رو کسی نکنه :دیمورد بعدی هم نتیجه دقیق مصاحبه و فیدبک دادن هست که ضعف اون فرد چی بود و چرا ریجکت شد؟ واقعیت اینه که تعداد آدمهایی که در هفته مصاحبه می‌کنیم خیلی زیاد هستن، همینجوریش تا کامنت رو بنویسیم کلی خستگی فکری داره، فیدبک نوشتنی که بخوایم به صورت پیش‌فرض به همه بدیم دیگه واقعا طاقت‌فرساست. چجوری بنویسیم به طرف بر نخوره، چجوری بنویسیم که ضعف طرف رو بگیم و غیره. در عین حال مواردی که درخواست کنن فیدبک می‌دیم. موردی که همیشه گفته می‌شه اینه که برای فیدبک خواستن یا هر جور ارتباط باید به ایمیل ورکبل ریپلای زده بشه و همونجا جواب بدیم. (یه مورد رو اوایل نمی‌دونستم و توی تلگرام جواب دادم داستان شد! شانس آوردم اون زمان عین محتوای حرفاش رو توی ورکبل گذاشته بودم و لااقل داخل شرکت شبهه‌ای باقی نموند!!)از موارد دیگه که بچه‌ها شدیدا حساس هستن وقتی هست که مصاحبه‌شونده سعی می‌کنه با کاناال زدن و آشنایی دادن یا گاهی پاچه‌خواری و اینجور کارها نظر مصاحبه‌کننده رو جلب کنن! همه‌ی اینجور رفتارها هم دقیقا توی کامنت می‌نویسیم به یه چند تا علامت تعجب در انتها ختم می‌کنیم!!! اگرچه باز هم ریجکتی معمولا بخاطر ضعف فنی هست. کسی که واقعا دانش فنی بالایی داره، اون قدر اعتماد به نفس داره که احساس نیاز به چنین رفتارهایی نداشته باشه.در کل با توجه به زیاد بودن رزومه و مصاحبه هدف اینه که فرایند تا جای ممکن بهینه باشه و وقت کمتری گرفته بشه. اینکه مصاحبه تلفنی انجام میشه هم با هدف فیلتر سریعتر هست. هدف‌مون این نیست هر کسی که خفن بود رو بگیریم، هدف اینه آدم غیرخفن رو نگیریم. اینو می‌دونیم که با سیستم فعلی امکان ریجکت اشتباه هست، ولی مطمئنیم که امکان اکسپت اشتباه خیلی کم و ناچیزه.استخدام و منتورشیپبعد از مدتی که توی فرایند مصاحبه بودم چند تا نیرو گرفته بودیم و دیگه منتور کم آورده بودیم که وارد فرایند منتورشیپ هم شدم. دوره‌ی منتورشیپ از یک هفته تا ۳ ماه متغیر هست. توی این دوره یه سری محتوای آموزشی داده می‌شه که فرد باید مطالعه کنه و یه سری تمرینات رو انجام بده. محتوای آموزشی شامل مفاهیم پایه هستن و با شرایطی که استخدام می‌کنیم معمولا بخش زیادیش رو افراد خودشون بلدن یا کار کردن. هدف اینه اون ریزه‌کاری‌هایی که کار نکردن هم مطمئن بشیم یاد گرفتن.وظیفه منتور شامل پیگیری این فرایند می‌شه که فرد چیزی رو ignore نکنه یا از روی اون رد نشه. همچنین اوایل که وارد شرکت می‌شی فضا بزرگه و طول می‌کشه تا جا بیافتی یا با همه آشنا بشی. اوایل برای ناهار هم با نیروی تازه‌وارد می‌ریم که زیاد حس تنهایی نداشته باشه. یه سری جلسات یک‌به‌یک هم همیشه داریم که اگه مشکلی کمبودی ناراحتی چیزی بود راحت بگه و برطرف کنیم. باصطلاح فاز طرف رو بگیریم.در انتهای دوره منتورشیپ هم یه پروژه‌ آموزشی می‌دیم انجام بده و طی پروژه کیفیت کد رو بسنجیم و best practiceها رو بگیم و استایل‌گاید‌هایی که توی همه پروژه‌های شرکت رعایت می‌کنیم رو آموزش بدیم. وقتی دوره منتورشیپ تموم شد فرد وارد تیم خودش می‌شه و از اونجا به بعد ممکنه مسئول رشد و ارتقاء شخص دیگه‌ای باشه.ساختار Flatقدیم یه سری محصولات کوچیک مثل رسید بود که کلا یک تیم بیشتر نبود. در حال حاضر «بازار» و «دیوار» و «بلد» محصولات اصلی شرکت هستن که هر کدوم شامل چندین تیم می‌شن. مثلا بخش‌های مختلف اپ بازار از صفحات «جزییات برنامه» و «پرداخت» و «فهرست برنامه‌ها» گرفته تا تیم «جستجو» و «تبلیغات در جستجو» و … هر کدوم از این‌ها، تیم‌های جدا دارن که میکروسرویس‌های خودشون رو توسعه می‌دن. به تیم‌های محصول «بازار» اصطلاحا «قبیله‌ی بازار» می‌گیم. و تیم‌هایی که به این شکل جدا می‌شن هم Feature Team محسوب می‌شن.توی کافه‌بازار به قول خودمون ساختار flat داریم و اونجور ساختار سازمانی و hierarchy نداریم. اینکه بخوام دقیقش رو توضیح بدم واقعا سخت هست چون توی هر محصول و هر تیم ممکنه متفاوت باشه. سعی‌ام رو می‌کنم یه توضیح کلی بدم ولی احتمال اینکه جایی اشتباه کنم یا قانون کلی صادر کنم که در حالات خاص برقرار نباشه زیاده. چیزی که مهمه اینه که باید روحیه پیگیری داشته باشی و هر جا لازم شد با چندین نفر صحبت کنی تا خودت کار رو جلو ببری. من هم فقط بچه‌های فنی رو در جریان هستم و بچه‌های غیر فنی (پشتیبانی، محتوا، برندینگ، حقوقی، مالی، امکانات، تامینات، آشپزخانه و …) رو زیاد در جریان نیستم.معمولا توی همه‌ی تیم‌ها (فنی و غیرفنی) یک نفر تیم‌لیدر هست که هفته یا دو هفته یک بار با اعضای تیم جلسه داره. این تیم‌لیدر مسائل و مشکلات انسانی افراد رو باهاشون صحبت می‌کنه و راهنمایی می‌کنه. غیر از مسائل فردی، هماهنگی‌های گروهی رو هم انجام می‌ده، از رزرو اتاق جلسات گرفته تا رهبری جلسات دیلی و پلنینگ و رترو و …یه رول Tech Lead هم داریم (که ممکنه توی تیم‌لیدر جمع بشه) که داخل تیم در مورد تصمیمات فنی نظر می‌ده، اینکه چه لایبرری استفاده بشه، دیزاین چجوری باشه و غیره که البته برای این مسائل جلسات تشکیل می‌شه و همه‌ی اعضای تیم نظر می‌دن اما نظر نهایی با Tech Lead هست.فرایند رشد و ارتقاء اعضای هر تیم به عهده‌ی تیم‌لیدر هست. اینکه بچه‌ها رو راهنمایی کنه به چه سمتی برن و چه چیزایی میتونن بخونن یادگیری داشته باشن تا بعدا بتونن ارتقا بگیرن. در عین حال از اونجا که معمولا تیم‌لیدرها خودشون ممکنه مثلا بکندی باشن، در مورد بچه‌های غیر بکندی ماجرا چیز دیگه‌س.مثلا توی یه محصولی ۷-۸ تا تیم هست، اکثریت این تیم‌ها بکندی هستن اما داخل هر کدوم یا بعضیاشون ممکنه یک نیروی فرانت هم داشته باشن. همه‌ی فرانت‌اندهای این تیم‌ها با همدیگه یک چپتر رو تشکیل می‌دن و یک نفر رول Chapter Leader داره که تصمیمات فنی کلی رو هدایت می‌کنه و همچنین راهنمایی فرایند رشد و ارتقاء رو هم با اعضای چپتر جلو می‌ره و باهاشون جلسات یک‌به‌یک داره. (مسائل انسانی همچنان به عهده‌ی تیم‌لیدر خودشون هست)هر تیم یه رول مدیر محصول هم داریم که راجع به فیچرهایی که باید پیاده‌سازی بشه و سمتشون بریم نظر می‌ده. مدیرمحصول‌ها خودشون جلسات استراتژی و غیره دارن که هماهنگ باشن کل محصول به یک جهت حرکت کنه. جلسات با تیم‌های مارکتینگ و محتوا و حسام و غیره هم دارن. ساختار بچه‌های مدیر محصول از باقی بچه‌های فنی معمولا جداست، همگی سابقه کار فنی دارن و بحث‌های فنی رو کامل شرکت می‌کنن اما به عنوان مدیر محصول فعالیت فنی کمتری دارن (مگر مواردی که ماهیت محصول زیرساختی باشه که مدیر محصول ممکنه همون تیم‌لیدر یا Tech Lead باشه).شب ریلیز وب جدید و بازار ۸ارزیابی و ارتقاءسالی دو بار فرایند ارزیابی عملکرد داریم. به این شکل که فاز اول هر کسی کارهایی که توی ۶ ماه گذشته انجام داده و چالش‌هایی که برای انجامشون برخورد کرده رو می‌نویسه و تا ۷ نفر از افرادی که در جریان این فعالیت‌ها بودن و می‌تونن نظر بدن رو mention می‌کنه (سامانه مخصوص اینکار داریم). فاز بعدی ارزیابی همکار هست که هر کسی راجع به کارهایی که mention شده نظرشو می‌نویسه و راجع به کار اونها نظر می‌ده. در فاز سوم یه سری کمیته‌های کالیبریشن تشکیل میشه (تیم‌لیدرها، چپترلیدرها، vpها و …) که این ارزیابی‌ها رو می‌خونن و راجع به افراد نظر می‌دن که الان توی چه سطحی هست و ارتقاء می‌گیره یا نه؟سطح‌بندی افراد عددی هست و پوزیشن‌های مختلف متفاوته، مثلا فرانت‌اند ۳ سطح صفر و یک و دو داریم، بین این سطوح هم یه سری پله‌های بین‌سطحی داریم. هر پله که بالاتر می‌ری شامل افزایش حقوق یا سهام تشویقی هم ممکنه بشه، ضمن اینکه هر سطحی تعاریف و مصداق‌های خاص خودش رو داره. اینکه چه توانایی‌ها و فعالیت‌هایی باید داشته باشی تا به اون سطح برسی. در عین حال با توجه به پیچیده بودن ماجرا، برای استخدام یه پوزیشن سنیور باز کردیم و اگرچه داخل شرکت کسی رسما از این القاب نمی‌گیره اما کسی که بتونه به عنوان سنیور وارد بشه احتمالا از سطوح بالاتر شروع می‌کنه. سطح افراد هم محرمانه هست و غیر از خود افراد فقط شخص درگیر روند رشدشون از سطح اونها خبر داره.این کلیات روند ارزیابی و ارتقاء بود، در عین حال جزییات زیاد داره.این عکس هیچ ربطی به ارزیابی و ارتقاء نداره :دیحرف مردم ...یه سری شایعات هست همیشه راجع به کافه‌بازار زیاد می‌بینیم و می‌خونیم. معروف‌ترینشون ویروسی بودن بازار هست. این مورد اونقدر بین مردم جا افتاده که حتی بچه‌هایی که میان داخل کافه هم بعضا ممکنه شک داشته باشن که درسته یا نه؟ یه مورد جالبش یکی از بچه‌ها می‌گفت که وقتی اومده شروع کرده توی همه‌ی کدها رو خوندن و زیر و رو کردن (دسترسی همه‌چی برای همه بازه) ببینه واقعا کدی برای جاسوسی هست یا نه؟ اصل ماجرا به خیلی سال پیش برمیگرده زمانی که بچه‌ها تصمیم می‌گیرن اپ‌های داخل گوگل رو دانلود کنن و توی بازار ارائه بدن. یه سوتی که میدن google services به ازای هر اندرویدی باید نسخه متفاوتی می‌بوده اما نسخه یکسانی رو برای همه میزاریم. همین اشتباه باعث می‌شه خیلی از گوشی‌هایی که بازار داشتن و google services رو آپدیت کردن به مشکل بخورن. بعدها هم که فروشنده‌های موبایل برای منافع خودشون به این شایعه دامن زدن تا در قبال دریافت مبلغ اضافی، خودشون برای مشتری یه سری برنامه نصب کنن.یه مورد دیگه وقتی هست که آپدیت یه برنامه‌ی خارجی توی بازار زودتر از google play میاد. یه امکانی که برنامه‌نویس‌ها دارن امکان stage rollout یا soft release هست که نسخه جدید برنامه‌شون رو به گروه خاصی ارائه می‌دن یا کم‌کم ریلیز می‌کنن که بتونن جلوی باگ‌های احتمالی رو بگیرن. توی این موارد احتمالش هست که بازار اون نسخه جدید رو زودتر به همه ارائه بده. (تازگی یه سوتی دیگه داده بودیم که آپدیت تکراری می‌دادیم و اصلاح شد)یه سری شایعات مربوط به جاسوسی کردن بازار می‌شه، اینو مطمئن نیستم از کی و چرا شروع شده، حدس میزنم تحت تاثیر بی‌اعتمادی رایج مردم باشه. در عین حال گرفتن یه سری از دسترسی‌ها از کاربر باعث سوءظن بیشتر میشه. مثلا دسترسی دوربین که برای اسکن بارکد برنامه از وب گرفته می‌شده، یا دسترسی لوکیشن که برای پیشنهاد برنامه بر مبنای موقعیت مکانی گرفته می‌شده، دسترسی خوندن پیام‌ها که برای خوندن کد فعالسازی (بعد از لاگین) گرفته می‌شده (جدیدا به اندروید یه امکانی اضافه شده که بدون نیاز به این دسترسی بتونیم فقط پیام‌هایی که خودمون می‌فرستیم رو بخونیم. احتمالا اون کد عجیب انتهای پیام رو دیده باشین).حرف آخرتازه یک سال و خورده‌ای هست که اومدم کافه‌بازار. خیلی تجربیات جذاب و متفاوتی داشتم، با بهترین آدم‌هایی که توی زندگیم دیدم همکار بودم، روزهای خوب زیاد داشتیم. نمی‌گم کافه‌بازار ایده‌آل و مدینه‌ی فاضله برای همه‌س، ممکنه یکی با این کالچر و فرهنگ سازگار باشه و یکی خوشش نیاد. ممکنه ضعف‌هایی هم داشته باشیم، اما به قول یکی از بچه‌ها هیچ مشکلی نیست که بیان کنی و قبل از تو کسی بهش فکر نکرده باشه. اینکه هر روز می‌بینی یه مشکلی حل میشه خودش بهترین حسّی هست که توی فضای کاریت می‌تونی داشته باشی.گاهی روزهای سخت هم داریم، شب ریلیز که تا دیروقت ممکنه سر کار بمونیم، یا بعضی وقت‌ها که یه سرویسی down می‌شه یهو استرس و نگرانی رو توی چشم چند نفر می‌بینی که لپ‌تاپ به دست از اتاق جلسه به سمت میزشون میرن. تا حالا زیاد شده کسی سوتی بدی بده، ولی مورد نداشتیم کسی بخاطر اشتباهش مثلا توبیخ بشه، توی این یک سال یک مورد هم ندیدم کسی حتی دنبال مقصر بگرده. جمله‌ی «از اشتباهاتمون درس می‌گیریم» واقعا در حد شعار نبود، در عمل می‌شه حسّش کرد.چیزی هم که اینجا نوشتم بیشتر فرایندهای استخدام و رشد و ارتقاء بود برای کسی که از بیرون این نگرانی‌ها رو داره، ولی در عمل خیلی کم پیش میاد ذهنت درگیر اینجور مسائل بشه یا دغدغه داشته باشی. همیشه خیالت راحته که اگه کارِت رو خوب انجام بدی بالاخره دیده می‌شه و رشد می‌کنی. همه‌ی همکارانت (فنی و غیرفنی) آدم‌های باسواد و با فرهنگی هستن.کافه‌بازار برای من بیشتر از محل کار، یه فضای زندگی کردن شده. فعالیت‌های تفریحی بین بچه‌ها خیلی زیاده، نه در حدی که زمان‌مون به بطالت بگذره و حس کنی داری عمرت رو هدر می‌دی، ولی در حد نرمال که هر از چندی با بچه‌ها بیرون بریم و تفریح کنیم و بالانس خیلی خوبی بین کار و زندگی برقرار باشه. چالش‌های فنی و جذاب خیلی زیاد هست و خارج از حوزه کاری خودت هم همیشه چیز جدید می‌بینی و یاد بگیری.یه مساله‌ای که زیاد بهش برمیخوری وقتی هست که چند چیز کوچیک یه اتفاق بزرگ رو رقم میزنه، وقتی در قالب کل یه حرکت منظم و متحد رو می‌بینی. اگه منظورم رو متوجه نمی‌شین پیشنهاد می‌کنم کارتون پاکوچولو رو حتما ببینین. توی وبسایت جدید بازار هم ببینین :دی. اینقدر هم شایعه‌سازی نکنید، ما اون هیولاهای وحشتناکی که خیلی‌ها می‌گن نیستیم :دیعکس‌های بیشتر در پیج اینستاگرام | موقعیت‌های شغلی</description>
                <category>آرش شاکری</category>
                <author>آرش شاکری</author>
                <pubDate>Wed, 11 Sep 2019 12:33:54 +0430</pubDate>
            </item>
            </channel>
</rss>