Node Master – Telegram
Node Master
1.03K subscribers
24 photos
2 files
156 links
Group Chat: @nodemastergp
Admin: @napoleon_n1
Download Telegram
Node Master
قرار بر این بود که درمورد تمام موضوعات BackEnd صحبت کنیم. ولی خب تا به امروز فقط درمورد Runtime های مربوط به js بیشتر NodeJS صحبت کردیم. امروز نگاهی به یکی از ویژگی های بسیار خوب #postgres اشاره میکنیم. شما میتونید یک فیلد با تایپ JSON تعریف کنید و دیتا رو…
خب بریم سراغ مسئله واقعی که ممکنه براتون روی پروژه هاتون خیلی پیش بیاد و استفاده از این تکنیک میتونه کارتون رو راحت تر کنه.
یک فروشگاه آنلاین مثل دیجیکالا رو در نظر بگیرید که محصولات زیادی برای فروش از دسته بندی های مختلف دارد. حالا شما قصد دارید ویژگی های خاص برای هر دسته از محصول رو ذخیره کنید و این هم در نظر بگیرید که ویژگی هایی که برای موبایل ذخیره میشود کاملا با ويژگی هایی که برای دفتر نقاشی ذخیره میشود متفاوت است.
حالا از شما میخواهند که دیتابیسی طراحی کنید که در قبال هر محصول خاص ویژگی های خاص خودش با مقادیر خاصش رو ذخیره کنید. مثال‌:
موبایل :
- صفحه نمایش
- شبکه ارتباطی
- پردازنده

دفتر
- نوع کاغذ
- تعداد برگ
دو روش برای انجام دادن این کار وجود داره. اولین روش رو که بالاتر اشاره کردیم. دومین روش که روش سخت تری هست و در دیتابیس های SQL استفاده میشه چالش داره و سوال مصاحبه ای هست.
سعی کنید روش SQL رو پیدا کنید و زیر این پست کامنت بزارید.

راهنمایی : یک پترن خیلی پر استفاده در SQL هست با نام مشخص.
#challenge
👍4
یک بلاگ پست زیبا از github که درمورد استفاده از MySql به عنوان یک دیتابیس اصلی در اون حجم توضیح میده.

باتوجه به این که scale کردن دیتابیس هایی مثل postgres و mysql چالش های زیادی دارن این بلاگ پست ارزش خیلی زیاده داره
https://github.blog/2023-12-07-upgrading-github-com-to-mysql-8-0/
(متاسفانه وقت ندارم با جزیات باهم برسیش کنیم ولی خب خودتون بخونید واقعا خوبه)
👍4
Node Master
Photo
برای این سوال ساده ترین روشی که سریع به ذهن آدم میرسه این هست که برای هر دسته بندی یک table درست کنیم یعنی ۱۰۰۰ دسته بندی برابر است با ۱۰۰۰ table که یکم فکر کنیم میبینیم منطقی نیست! پس باید یک روش دیگه باشه.
اینجا هست که پترن Entity attributes value میاد به نجات ما. البته دوستان برای دونستن دقیق این که چرا به همچین پترنی میرسیم این هست که باید relational database design بلد باشید. فارغ از این موضوع که من nosql میزنم من mongo استفاده میکنم. database design واجب است و باید بلد باشید چون حتی در دنیای nosql هم برای مدل سازی بهتون کمک میکنه. حالا بریم این پترن رو بیشتر توضیح بدیم با مثال
اول entity های ما همون دسته بندی ها هستن مثل موبایل
دوم attributes ها همان ویژگی های موبایل هست مثل صفحه نمایش و cpu
سوم value ها همان مقادیر attributes های ما هستند یعنی 3 inch و snapdragon.
حالا اگر بخوایم relational به مسله نگاه کنیم میگیم که هر دسته بندی n تا attr دارد و هر attr هم n تا value دارد ( اگر این قسمت رو متوجه نشدید database design بهتون کمک میکنه )
اینجا اگر دقت کنیم یک رابطه n to m تشکیل شده و داخل عکس میتونید مشاهده کنید این موضوع رو.
اینطور که یک جدول دسته بندی داریم و یک جدول attr و value ها را در کنار table واسط استفاده میکنیم ( برای دونستن این که چرا table واسط استفاده میکنیم دوباره میرسیم به database design )
این روش یک سری محدودیت هایی داره که صحبت درموردشون خیلی طولانی میشه و درکل نکته جالب اینجاس که میتونیم این مسله رو با mongodb یا postgres json type خیلی راحت تر حل کنیم.
به این صورت که یک داکیومنت embed کنیم و attr ها به عنوان key و value ها به عنوان value در json doc در نظر بگیریم و key ها رو به هیچ عنوان مقدار concrete در نظر نگیریم.
بیشتر عمیق شدن رو بزاریم برای بعد و یک جمع بندی کنیم که دوستان به عنوان back-end dev شما باید اصول طراحی دیتابیس حداقل پایه رو خیلی خیلی خوب بلد باشید. این روزا متاسفانه orm ها بلایی سر برنامه نویس ها اورده که معمولا این نکات رو درنظر نمیگیرن و این نکات روی سیستم ها در scale خیلی خیلی تاثیر گذار هست و شما وظیفه دارید این ها رو بدونید.
من دوره فارسی معمولا معرفی نمیکنم به کسی ولی دیتابیس دیزاین این دوره رو حتما ببینید و بعد در postgres یا mysql تمرین کنید:
https://faradars.org/courses/fvsft105-database
این رو از من داشته باشید که ابزار مهم نیست ( postgres , mysql ,mongodb, cassandra ) و مهم نحوه استفاده از این ابزار ها هست ( Database design , system design, design patterns ) که شما رو از بقیه متفاوت میکنه یاد گرفتن ابزار خیلی راحته ولی نحوه استفاده درست و صحیح زمان بر و تمرین زیاد میخواد.
#tip
👍6
به تازگی Deno به صورت Beta ویژگی Deno.cron رو اضافه کرده که میتونید بدون 3rd party یک cron job با runtime داشته باشید. برای یک پروژه نیاز به cron job داشتم و تصمیم گرفتم از این قابلیت استفاده کنم. تجربه ای که داشتم واقعا خوب و راحت بود و حالا در آینده جزیات بیشتری به اشتراک خواهم گذاشت.

برای ایجاد cron job با در Deno میتونید این کار رو کنید
Deno.cron("Sample cron job", "*/10 * * * *", () => {
console.log("This will run every 10 minutes");
});

و بعد به دلیل بتا بودن این قابلیت میتونید با فلگ زیر کد رو اجرا کنید.
deno run -A --unstable-cron jobs.ts

#tip #deno
👍1
طبق عادت همیشگی داشتم پروژه Node روی گیتهاب چک میکردم و آخرین کامیت که ۳ ساعت پیش خورده خیلی جالب بود برام.
اینطور که شاهده کم کم باید شاهد اومدن http3 روی std برای #NodeJS باشیم باتوجه به این commit که دارن پروتکل quic رو جلو میبرن!

https://github.com/nodejs/node/commit/fc102f2180dfc8e1654ce672185f5bf97ec21b53

#Update
Forwarded from Programmer Jokes
👍7
یکی از نکاتی که میتونه ما رو برنامه نویس بهتری کنه اینه که از اکوسیستم های دیگه هم خبر داشته باشیم و صرفا در حباب stack خودمون نمونیم. حتی در حد بیسیک هم خوبه نیاز نیست چنتا تکنولوژی رو استاد باشید.
در بلاگ رسمی #golang یک پست خیلی با ارزش منتشر شده از Survey رسمی خودشون روی اکوسیستم #golang
خیلی طولانی و کامل هست.
بنظرم نگاهی بندازید من خودم هم اگر نکته ای دیدم اینجا میگم.
https://go.dev/blog/survey2023-h2-results
👍2
#استخدام برنامه نویس

Senior Backend NodeJs

تجربه حداقل ۳ سال در توسعه و پیاده‌سازی برنامه‌های وب با استفاده از Node.js
تسلط کامل بر مفاهیم اساسی JavaScript و فریم‌ورک Express.js
تجربه در طراحی و پیاده‌سازی API‌ها با استفاده از RESTful یا GraphQL
تجربه در کار با پایگاه‌های داده مانند MongoDB یا MySQL

شرایط شغلی
حضوری - شنبه تا چهارشنبه ساعت 9 الی 17
موقعیت مکانی شرکت
تهران خ شیراز جنوبی
حقوق؛ توافقی - باتوجه به میزان توانایی
و تجربه
@fatemekia_1375
#Work
Forwarded from Geeking Around
تفاوت Symbolic reference و Direct reference توی JVM

داشتم یه مطالعه‌ای راجب اینکه JVM چطور کار میکنه میکردم، که دیدم توی یه یه قسمتی از کار JVM میاد Symbolic reference هارو به Direct reference تبدیل میکنه (توی Class Loader > Linking > Resolution این اتفاق میوفته). که باعث شد یکم رفتم خوندم ببینم تفاوت‌شون چیه.

داستان از این قراره، Symbolic reference در واقع یک String هست که میشه باهاش هر field، method یا class ای رو uniquely پیدا کرد باهاش. تشکیل شده از اسم، دیسکریپتور اون field، method یا class.
وقتی JVM داره Byte code رو execute میکنه و به یک Symbolic reference برخورد میکنه (اینطور تصور کنین که شما یک پکیجی نصب کردین روی اپ‌تون و دارید یکی از method هاشو import میکنین توی class خودتون و ازش استفاده میکنین) JVM میره اون field، method یا class رو پیدا میکنه (اگر نیاز باشه Loadش میکنه) و به جای اون Symbolic reference یک Direct reference میزاره. حالا این Direct reference چیه؟ آدرس یا پوینتر اون field، method یا class توی مموری! به همین سادگی‌:))

سری بعدی که JVM به همون Symbolic reference بخوره، دیگه این فرایند رو تکرار نمیکنه، از همون Direct refernceای که قبلاً پیدا کرده بود استفاده میکنه.

اگر میخواین کل فرایند اینکه JVM چطور کار میکنه رو بخونین این پست خیلی خوب توضیح داده.
https://www.freecodecamp.org/news/jvm-tutorial-java-virtual-machine-architecture-explained-for-beginners/
Geeking Around
تفاوت Symbolic reference و Direct reference توی JVM داشتم یه مطالعه‌ای راجب اینکه JVM چطور کار میکنه میکردم، که دیدم توی یه یه قسمتی از کار JVM میاد Symbolic reference هارو به Direct reference تبدیل میکنه (توی Class Loader > Linking > Resolution این اتفاق…
دوستان این چنل یکی از نزدیک ترین دوستانم هست (همکارم که کنارم میشینه).
چیزای عمیقی رو برسی میکنه و کلا باهم همیشه خیلی چیزا رو برسی میکنیم و از هم خیلی چیزا یاد گرفتیم.
این چنلش تازگی پابلیک کرده دوست داشتید جوین بشید.
👍1
Node Master
#include <iostream> int main() { std::cout << "Let The Performance Begin!\n"; return 0; } به عنوان برنامه نویس BackEnd شما صرفا نباید یک framework developer باشید. باید به درجه ای برسید که بیت به بیت دیتایی که دارید کار باهاش انجام میدید رو بشمارید.…
class BuggyCls {
#age;
set age(value) {
this.#age = value;
}

get age() {
return this.#age;
}

sum2() {
return this.#age + 2;
}
}

این تیکه کد ساده یک باگ ترسناک داره که ممکنه به راحتی به چشم نیاد.
اینجور باگ ها روی پروداکشن یکم سخته پیدا کردنشون ولی با مطالعه درموردشون چشمتون رو میتونید عادت بدید که این مدل باگ ها رو قبل از production ببینید.
راجع بهش فکر کنید.

نکته : مربوط به یکی از مباحثی هست که من قبلا اینجا اشاره ای کرده بودم

#Think #Tip
👍2
Node Master
class BuggyCls { #age; set age(value) { this.#age = value; } get age() { return this.#age; } sum2() { return this.#age + 2; } } این تیکه کد ساده یک باگ ترسناک داره که ممکنه به راحتی به چشم نیاد. اینجور باگ ها روی پروداکشن یکم سخته…
بزارید قبل از توضیح باگ اول راجع به #age توضیح بدم.
وقتی شما در یک کلاس قبل از هر attribute اگر # بزارید اون تبدیل به private میشه. این نوع private کردن با استفاده از کلمه private در typenoscript متفاوت هست.
شما وقتی با # یک فیلد رو private کنید در حقیقت خود انجین تضمین میکنه private بودن رو ولی در typenoscript صرفا فقط یک syntax در زمان compile و قبل از transpile میباشد. بزارید با مثال توضیح بدم.
class Simple {
private age = 24;
}

const obj = new Simple();

console.log("age" in obj);

خط سوم با استفاده از in ما چک میکنیم که آیا obj یک attr با نام age دارد یا خیر. اگر زبانی مثل جاوا بود قطعا جواب false بود ولی اینجا true برمیگردونه. شما حتی میتونید type cast کنید و مستقیم دسترسی به age داشته باشید!
ولی اگر خط بالا رو با #age بنویسید جواب false میگیرید که منطقی هست چون خود js engine این تضمین رو بهمون میده که private هست ( حالا که چطور این تضمین رو بهمون میده خودش یک بحث طولانی دیگ هست که اینجا مورد نظر ما نیست)

حالا سوال پیش میاد از کدوم استفاده کنیم برای private کردن فیلد ها؟
جواب خیلی بستگی داره و باتوجه به تحقیقی که من کردم خیلی دو دستگی و سلیقه ای هست این بخش. البته در آینده قطعا آدما بیشتری سمت این ویژگی خواند رفت و چون این داخل ES2022 اضافه شده و خیلی جدیده کلا طول میکیشه تا همه استفاده کنن چون که ویژگی جدیده هست و داخل آموزش ها معمولا نمیگن.

نکته بعدی این که وقتی داشتم سوال بالا رو طراحی میکردم قصد داشتم یک باگ خیلی معروف رو برسی کنیم ولی بیشتر که رو سوال دقت کردم رسیدم به جمله معروف "javanoscript is garbage" چون اون سوال حتی من که طراحیش کردم یک باگی داشت که خودم دوباره بهش دقت نکرده بودم. البته برمیگرده به ساختار و فلسفه زبان که بنظرم فرصت خیلی خوبی هست عمیق تر بشیم
#Tip
👍5
NodeMaster.ir
Coming Soon!
👍11
همکاری در پوزیشن توسعه دهنده بک اند
ما یک‌شرکت فناور مستقر در پارک علم و فناوری دانشگاه تهران و بازوی فناوری هلدینگ معدنی سنگ آهن هستیم. ما به دنبال یک همکار توسعه دهنده در پوزیشن بک اند با استک nest هستیم و توانایی های مورد انتطارمون:
تسلط بر typenoscript و فریمورک nest
توانایی کار با git
توانایی تست نویسی
توانایی داکیومنتیشن
توانایی کار گروهی و حل مساله
حقوق و دستمزد را به صورت توافقی و بر  اساس نوع همکاری تعیین میکنیم.
ضمنا محصول یک وب اپلیکیشن تخصصی در زمینه هوشمندسازی معادن است.
Naghshtech@gmail.com
@Ali_ramez

#Work
👍2
رشته پست مربوطه :‌ https://news.1rj.ru/str/NodeMaster/81

خب بریم سراغ باگی که قرار بود راجع بهش صحبت کنیم. بزارید یکم راجع تاریخچه باحال این باگ صحبت کنیم.
Null References: The Billion Dollar Mistake
اولین بار این null رو در زبان ALGOL در سال 1965 درست کرد فقط به دلیل این که پیاده سازیش خیلی راحت بود براش. کلا درمورد null ها همیشه همه جا بحث زیاده و به این دلیل بهش میگن billion doller mistake که یهویی داخل runtime یچیزی میبینی که نباید و برنامه کرش میکنه. مقالات زیادی راجع بهش هست که میتونید مطالعه عمیق تری داشته باشید راجع بهش و یک تایم دیگه خود این موضوع رو عمیق تر صحبت میکنیم.
توضیح باگ‌: شما اگر قبل از set کردن مقدار age با استفاده از setter متد sum2 رو invoke کنید به دلیل این که مقدار #age تعریف نشده و undefined (یا همون null‌) هست و وقتی یک عدد رو با undefined جمع کنید مقدار NaN رو میگیرید که همین خودش یک موضوع دیگس.
بزارید اول این رو بگم که یکی از دلایلی که میگن "js is garbage" همین Billion Dollar Mistake به دلیل این که نه تنها یک مقدار بلکه دو مقدار برای نشان دادن null داریم یعنی خود null و undefined و هرچی راجع به جک این موضوع صحبت کنیم واقعا کمه!
این باگ رو شما اگر از #typenoscript استفاده کنید در زمان compile میتونید جلوگیری کنید به دلیل این که ts اگر strictnullcheck در ts فعال باشه شما رو مجبور میکنه که این رو درنظر بگیرید.
class BuggyCls {
#age?: number;
set age(value) {
this.#age = value;
}

get age() {
return this.#age;
}

sum2() {
if (this.#age === undefined || this.#age === null) {
return this.#age + 2;
}
throw new TypeError("Please set a number value for age");
}
}

شما در خط دوم به ts میگید که این مقدار میتواند undifiend هم باشد و در متد sum شما رو مجبور میکنه که از guard استفاده کنید تا کدتون رو امن کنید. به این موضوع میگن null safety. یک روش دیگ هم برای تعریف فیلدی که میتواند null هم باشد هست که من معمولا از اون روش استفاده میکنم.
#age: number | null = null;

هر دو روش تفاوتی در نهایت ندارن و سلیقه هست من به این دلیل از این استفاده میکنم چون خیلی explicit تر هست و معمولا میگن از undifiend مستقیم استفاده نکنید و برای جاهایی بزاریدش که خود js engine اون رو برمیگردونه.
این موضوع هم البته صرفا یک practise هست و شما باید در نهایت استایل خودتون رو داشته باشید.

مطلب بعدی راجع به NaN خیلی صحبت میکنیم این همون موضعی بود که حتی من هم وقتی داشتم سوال طرح میکردم حواسم بهش نبود. مطلب بعدی جالبه چون که به زبان های دیگ مثل پایتون نگاهی میندازیم تا درک بهتری از دلیل این موضوع داشته باشیم.

#Tip
👍9
Node Master
رشته پست مربوطه :‌ https://news.1rj.ru/str/NodeMaster/81 خب بریم سراغ باگی که قرار بود راجع بهش صحبت کنیم. بزارید یکم راجع تاریخچه باحال این باگ صحبت کنیم. Null References: The Billion Dollar Mistake اولین بار این null رو در زبان ALGOL در سال 1965 درست کرد فقط به دلیل…
در پست قبلی راجع به اصل باگ توضیحاتی دادیم ولی رسیدم سروقت این که چرا ما NaN میگیریم. بزارید با یک مثال در #python و #javanoscript رو کنار هم بزاریم و اونجا میتونیم بهتر متوجه بشیم.
>>> 2 + "text"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

> 2 + "text"
'2text'

این دو خط خیلی شبیه به هم هستند هردو یک مقدار string رو با یک مقدار integer جمع کردیم ولی جواب نهایی خیلی متفاوت هست. دقیقا همین رفتار باعث میشه که زبان ها رو به دو دسته تقسیم کنیم
- weakly typed
- strong type
قبل از این که توضیح بدم راجع به این دو این رو در نظر بگیرد که #python یک زبان strong type و #javanoscript یک زبان weak type هست و حالا با دونستن این فکت میتونیم توضیحات رو کامل تر کنیم.
به عنوان مثل در زبان های strong type اگر دو expresion از type های مختلف بخواد پردازشی روشون انجام بشه خود compiler یا interpreter جلوگیری میکنه از این کار مثل کد پایتون بالا که به صراحت میگه هردو باید یک type باشند و فرایند این تبدیل باید به صورت explicit توسط برنامه نویس انجام شود ولی در زبان های weakly type نتیجه میشه تکه کد js که این به نوعی خیلی میتونه ترسناک باشه! حالا اگر بخوایم نتیجه شبیه به کد js داشته باشیم منظور از explicit بودن در مثال پایین میبینید.
>>> str(2) + "text"
'2text

اینجا میبینید که برنامه نویس از فانکشن str برای تبدیل integer به string به صراحت ( explicitly ) استفاده کرده و منظور از explicit بودن این هست.
تفاوت زبان های strong و weak type به همینجا خطم نمیشه و ساعت ها میشه راجع بهش صحبت کرد ولی خب در همین حد فعلا کافی هست چون موضوعات دیگه ای هم هست که باید اشاره کنیم.

بزارید من اینجا یکبار دیگ تاکید کنم که "زبان های Weakly type میتوانند خیلی ترسناک باشند." بزارید این رو یکم بازتر کنم براتون با مثال
> null + 2
2
> undefined + 2
NaN

>>> None + 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

داخل سوالی که بالا طرح کرده بودم دقیقا امکان داشت این اتفاق تک کد بالا پیش بیاد که مقدار undefined با 2 جمع بشه و اینجا javanoscript هیچ اروری به شما نمیده و برنامه روند عادی خودش رو طی میکنه و خدا فقط میدونه کی و کجا یک validation از این جلوگیری کنه. حتی امکان داره ماه ها این باگ ها داخل کدتون بمونه و شما خبر نداشته باشید و از اون بدتر امکان ایجاد record های خراب داخل database هم هست. نکته جالب اینجا بود که وقتی integer رو با null جمع کردم و عدد 2 رو گرفتم خودم سوپرایز شدم. کلا weakly type ها همیشه میتونن شما رو سوپرایز کنن.
ولی خب به عنوان مثال در زبان strong type به صراحت interperter گیر میده و حتی ممکنه برنامه crash کنه.

این نکته خیلی مهم رو توجه کنید که این به معنی بد بودن weakly type lang ها یا خوب بودن strong type lang ها نیست هرکدوم مزایا و معایب خودشون رو دارن و این ما هستیم که باید از اینها درست استفاده کنیم. فقط باید این رو درنظر بگیرید که در زبان ها weakly type باید خیلی خیلی دقت بیشتری کنیم.

نظر شخصی :‌
- در اینجور مواقع من ترجیح میدم برنامه crash کنه تا در سکوت به کار خودش ادامه بده چون crash کردن خیلی خسارت کمتری وارد میکنه تا دیتای خراب روی دیتابیس

سخن پایانی این که این بحث خیلی بزرگتر هست و من سعی کردم به صورت کوتاه اشاره کنیم. یکم طولانی شد این پست هم و این که امیدوارم براتون مفید باشه.

فکر میکردین پشت پرده یک NaN گرفتن اینقدر داستان باشه؟ کامنت کنید😂
#Tip
👍8