Node Master – Telegram
Node Master
1.03K subscribers
24 photos
2 files
156 links
Group Chat: @nodemastergp
Admin: @napoleon_n1
Download Telegram
یک بخش جدید به داکیومنت #NodeJS از ورژن 22 اضافه شده برای TypeScript.
خودش پیشنهاد میکنه از tsx استفاده کنیم برای NodeJS.

به صورت کلی فاصله زیادی داریم تا #NodeJS هم مثل #Bun و #Deno به صورت کامل و Stable از #TypeScript ساپورت کنه. داخل این داکیومنت در این مورد توضیحات مربوطه داده شده.
درکل برای پروژه Production درکل tsx یا ts-node گزینه منطقی تری هست.
https://nodejs.org/docs/latest-v22.x/api/typenoscript.html
#Update
👍11
درود خدمت شما دوستان.
const lst = []
lst.map()

موضوعی که امروز در این ویدیو میخواهیم عمیق درموردش صحبت کنیم این هست که چرا همین یک خط کد کوچک در بالا باعث میشه سرور #NodeJS نابود بشه و کلا نتونه هیچ Response رو به کاربر بده.
در این مسیر نگاهی میکنیم به یکی خفن ترین ویژگی های #NodeJS یعنی Readable استریم ها و یاد میگیریم که چطور با استفاده از اون ها یعنی
Readable.from()

یک برنامه بسیار Optimize تری داشته باشیم.
https://youtu.be/N0akLbvhShE?si=f623-vxXz-brA4ag
👍13
درود دوستان ارادت.
امیدوارم حالتون خوب باشه.
// lib code
func doSomething() <-chan int {
ch := make(chan int)

go func() {
defer close(ch)
time.Sleep(2 * time.Second)
ch <- 102

}()

return ch
}

// main code
func main() {
result := <-doSomething()
fmt.Println(result)
}

همیشه مفهوم Concurrency برای ما Developer ها مثل یک Super Power هست و البته به دست آوردن این Super Power هم کار راحتی نیست.
قبلا کتاب Learning Go رو من مطالعه میکردم و یک پاراگراف از این کتاب برای من خیلی جذاب بود چون نگرش من درمورد این موضوع و این Super Power تا حد خیلی زیادی تغییر داد.
در این ویدیو سعی میکنیم یک طرز تفکر و یک رویکرد رو برسی کنیم که بتونیم در آینده زیر ساخت مناسبی برای شنا کردن در دریای عمیق Concurrency ها در آینده داشته باشیم.
نکته اصلی این ویدیو مفهوم و طرز تفکری هست که از اون پاراگراف در کتاب یاد گرفتم و امیدوارم تونسته باشم به خوبی اون رو منتقل کنم.

https://youtu.be/fbh_r9CKmMU
👍14
درود دوستان ارادتتتت.
خیلی وقت بود میخواستم این ویدیو رو بگیرم. روزی که من #Python گذاشتم کنار و حرفه ای شروع به کد زدن #JavaScript و #NodeJS کردم همیشه هروقت باکسی بحث برنامه نویسی میشد من این رو میگفتم که جای یک چیزی مثل Context Manager مثل پایتون در اکوسیستم #JavaScript واقعا خالی هست. وقتی #TypeScript ورژن 5.2 منتشر شد و این syntax رو برای بار اول دیدم واقعا خوشحال شدم
async function main() {
using resource1 = getResource()
await using resource2 = await getResource()
}

در این ویدیو به Explicit Resource Management در زبان های برنامه نویسی #python , #golang و #cpp میکنیم. با یک پترن خیلی قدیمی به اسم RAII پترن آشنا میشیم و در نهایت میرسیم به ارتباط RAII پترن در C++ در #Typenoscript .
این ویدیو قرار هست در دو پارت منتشر بشه و پارت دوم رو کامل درمورد مثال های عملی #Typenoscript گذاشتیم و تمرکز ویدیو اول هم بیشتر نگاه به زبان های دیگر و برسی این موضوع که چرا به "using" نیاز داریم.

https://youtu.be/0CG_WA6Yu9o?si=QYunevpiEyWp6gWW
👍13
چند روزی هست #NodeJS نسخه 22.12 LTS منتشر شده و شاهد یکی از بزرگترین قدم های #NodeJS برای آینده هستیم.
در این ورژن میشه ماژول های ESM رو در CJS بدون استفاده از --experimental-require-module فلگ استفاده کرد. این موضوع باعث میشه که اکوسیستم بیشتر سمت ESM بره و استفاده از CJS کمتر بشه.

https://nodejs.org/en/blog/release/v22.12.0

#Update
👍11
یکی از بچه های فعال تو گروه خودمون داخل شرکتشون دنبال یک همکار جدید میگردن.

دوست داشتین رزومه خودتون بفرستین.

https://jobinja.ir/companies/concept-x/jobs/AT2K?_gl=1*z5obhf*_ga*MTU2MzU0NzAzOC4xNzEzMDkxOTU2*_ga_T8HC2S1534*MTczNDQ2MDE1MC41LjEuMTczNDQ2MTMyNS4yNS4wLjA.

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

جدا از این مسائل ولی هروقت اگر حس کردید من میتونم بهتون کمک کنم pv به من پیام بدین قطعا جواب میدم.

امیدوارم موفق باشین❤️
👍42
Node Master
دلیل این که این کد جذابه این موضوع هست که بعضی قسمت های #NodeJS دسترسی هایی خیلی نزدیک به زبانی مثل C بهت میده. و اون Api نزدیک به Api های low level داخل C هست. نمونه دیگ از این موضوع میتونه وقتی باشه که یک فایل یا سوکت به صورت خام باز میکنید و یکدونه file…
syscall-nodemaster.png
36.2 KB
قبلا در این مثال اشاره کوچکی به File Denoscriptor ها باهم کردیم. امروز با هم یکم عمیق تر میشیم. قبل از هرچیزی بهتر است این موضوع را درک کنیم که وقتی از "File" در اینجا صحبت میکنیم منظور از فایل های ویدیویی و موسیقی و عکس و باینری به تنهایی نیست. در اینجا باید از زاویه دید سیستم عامل به کلمه "File" و معنی اون نگاه کنیم تا بتونیم درک مناسبی داشته باشیم. از زاویه دید OS هر File میتونه یک Directory یا نمونه های بالا که گفتم یا حتی انواع IO Device های مختلف مثل Mouse و Keyboard و البته socket رو نباید فراموش کرد.
شاید گیج شده باشید یا براتون سوال پیش اومده باشه که چرا باید یک File از زاویه دید OS معادل همچین چیز هایی باشه؟ جواب خیلی ساده هست داشتن یک Abstraction خوب با یک Interface یکسان برای کار کردن با انواع مختلف IO Device ها قدرت خیلی زیادی میده و البته توسعه رو خیلی آسون تر میکنه. البته ما به عنوان Backend developer مستقیما با این sys call ها کار نمیکنیم و زبان های برنامه نویسی سطح بلاتر این موضوع رو هنوز Abstract تر کردن و یک Interface ساده تری به ما دادن. درواقع این موضوع کار توسعه دهنده زبان های برنامه نویسی دیگ رو راحت تر کرده تا برای ما بتونن راحت تر یک Interface تمیز و خوب توسعه بدن.

حالا میرسیم به این که FD چیست؟
- یک عدد postive int کوچک میباشد که برای هر Process این عدد ها Unique هستن و Process ما با استفاده از این آیدی هایی که از Kernal اومده میتونه با IO Device های مختلف صحبت کنه. به عنوان مثال FD 123 در یک Process با یک سوکت اشاره داره و در یک Process دیگ به یک text file.

- به صورت کلی File Denoscriptor ها بخشی از POSIX Api هستن و سیستم عامل های UNIX-like دارن.
- روی ویندوز داستان ظاهرا متفاوت هست و یک مفهومی به اسم Handle دارن که جزیاتش رو زیاد نمیدونم و در آینده باهم یادمیگیرم.

اگر هنوز یکم درک موضوع Abstraction که بالاتر اشاره کردم براتون سخته. مثال جذاب زیر براتون روشن میکنه داستان رو.
package main

import (
"fmt"
"net"
"os"
)

const MY_TXT = "NodeMaster Is Alive!"
const WRITE_NET = "WRITE TO TCP SOCKET"
const WRITE_FILE = "WRITE TO FILE"

func main() {
fd, _ := os.OpenFile("myTest.txt", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
nt, _ := net.Dial("tcp", "localhost:3000")
fmt.Println(WRITE_NET)
nt.Write([]byte(MY_TXT))
fmt.Println(WRITE_FILE)
fd.Write([]byte(MY_TXT))
fmt.Println(nt)
fmt.Println(fd)
}

اینجا یک برنامه #Golang خیلی ساده داریم که یک فایل معمولی باز میکنیم و یک tcp socket و MY_TXT رو داخل هردو این ها Write میکنیم و چندتا لاگ ساده داریم که کارمون راحت تر باشه برای پیدا کردن syscall ها برنامه رو build بگیرید و با command زیر برنامه رو اجرا کنید.
در حقیقت وقتی سوکت و یک فایل متنی روی دیسک باز میکنیم اون پشت syscall مربوطه به ما یک File Denoscriptor میده که میتونیم با اون کار هامون رو انجام بدیم.
strace ./main

این strace به ما کمک میکنه که syscall هایی که برنامه ما انجام میده رو trace کنیم. در عکس بالا ما چندین write syscall رو میبینیم که به عنوان arg اول یک File Denoscriptor میگیره و به عنوان arg دوم یک بافر دیتایی که ما میخوایم داخلش بنویسیم.
در شماره یک که ما عدد 6 رو میبینیم این 6 در حقیقت به یک tcp socket اشاره داره و در شماره دو داخل عکس عدد 3 به File denoscriptor مربوط به text file ما روی دیسک اشاره داره. همینطور که میبینید حتی داخل عکس هم بدون دونستن این موضوع اگر نگاه فقط به singture فاکنکشن write کنید از روی file denoscriptor ها به هیچ عنوان متوجه نمیشید که مقصدی که داخلش write میکنیم آیا یک socket هست یا یک فایل روی دیسک یا هر IO Device دیگه ای و دقیقا همین موضوع اون چیزی هست که ما میخوایم و میشه همون Abstraction که بالاتر درموردش صحبت کردیم.

یک نکته این که درسته در #Golang و #Java ما Writer و Reader اینترفیس داریم و حتی اگر سیستم عامل همچین قابلیتی به ما نمیداد دوباره همچین interface هایی وجود داشت ولی کار توسعه دهنده های این زبان ها بسیار سخت تر بود برای ایجاد این interface ها.
حالا دوتا نکته که دوست دارم داخل گروه نظرتون رو بگید و درموردشون صحبت کنیم.
1. داخل عکس بالا چندتا write دیگ هم داریم که عدد 1 رو به عنوان File denoscriptor استفاده کردن. حالا این عدد 1 چی هست؟ داخل گروه خوشحال میشم درموردش صحبت کنیم.
2. چرا از #Golang استفاده کردیم برای مثال؟

بعد از مدت ها این اولین پست من هست امیدوارم براتون مفید باشه و خیلی خیلی ممنونم که همیشه همراه من بودید و امیدوارم همگی موفق باشید رفقا.
👍14
Iman Hosseini Pour
syscall-nodemaster.png
یه فکت درمورد لینوکس هست که میگه:
"همه چیز در لینوکس File هست"
همین یک جمله کافی هست که متوجه بشیم تقریبا وقتی میخوایم با هرچیزی کار کنیم به نوعی با File Denoscriptor ها سرکار داریم. داخل پست قبل داخل عکس بالا یک نکته ای اشاره کرده بودم که File Denoscriptor عدد 1 چی هست؟ باهم جوابش رو اینجا برسی میکنیم.
وقتی یک Process جدید در سیستم عامل ساخته میشه File Denoscriptor های 1,2,3 به صورت رزرو شده هستن و به به Process اختصاص داده میشوند.

0 = stdin
1 = stdout
2 = stderr
داخل عکس پست قبل هرجا از
fmt.Println()

استفاده کرده بودیم در حقیقت داشتیم روی FD 1 مینوشتیم. به صورت خلاصه هروقت console.log میزنیم داریم روی FD 1 مینویسیم. یعنی کنسول هم یک فایل هست. این موضوع منطقی هم هست چون وقتی یک ترمینال باز میکنید اگر
tty

بزنید بهتون آدرس terminal باز شده رو بهتون میده که وقتی Process روش باز میکنید از طریق FD 1 و 2 شما به برنامتون input و output میفرستید و میبینید.
با این تفاسیر وقتی Terminal ما یک file هست پس میتونیم با node:fs داخلش بنویسیم.
import fs from "node:fs";
fs.writeSync(1, Buffer.from("Hello NodeMaster\n"));
👍14
Iman Hosseini Pour
یه فکت درمورد لینوکس هست که میگه: "همه چیز در لینوکس File هست" همین یک جمله کافی هست که متوجه بشیم تقریبا وقتی میخوایم با هرچیزی کار کنیم به نوعی با File Denoscriptor ها سرکار داریم. داخل پست قبل داخل عکس بالا یک نکته ای اشاره کرده بودم که File Denoscriptor عدد…
داشتم داکیومنت مربوط به #Docker میخوندم یک چیزی نظرم رو خیلی جلب کرد و توضیح مربوط به "-i" بود.
https://docs.docker.com/reference/compose-file/services/#stdin_open
من همیشه فکر میکردم برای این که دوتا Process بتونن باهم از طریق چنل های stdin و stdout ارتباط بگیرن نیاز دارن که رابطه Parrent and Child باهم داشته باشند که خب اشتباه میکردم. اشتباه به این بزرگی که اصلا دقت نمیکردم که pipe ها در #Linux اصلا ارتباط Parrent و Child ندارند ولی روی stdin و stdout دارن با هم ارتباط میگیرن.

بزارید این موضوع رو با مثال ببینیم یک کنجکاوی جدید هم برای آینده ایجاد کنیم.
یک ترمینال باز کنید و "ps" رو بزنید که PID مربوط بهش رو دریافت کنید. همونطور که میدونید هر Process هم 3 تا FD به صورت استاندارد برای stdout, stdin, stderr داره. حالا اگر ما یطوری PID مربوط به terminal رو داشته باشیم باید بتونیم روی چنل stdin اون Process دیتا ارسال کنیم و روی ترمینال ببینیمش.
اینجا هست که در لینوکس "/proc" میاد وسط
در این دایرکتوری میتونیم اطلاعات زیادی درمورد وضعیت کرنل بگیریم و یکی از کاراش این هست که میتونیم اطلاعات درمورد Process ها درموردش ببینیم با استفاده از فرمت زیر.
/proc/PID


قبل تر باهم PID مربوط به ترمینالی که باز داریم رو گرفتیم حالا اگر بخوایم میتونیم از اینجا به stdin اون Process دسترسی داشته باشیم باتوجه به این که fd استاندارد stdin برای تمام proccess ها 0 هست.
/proc/4561/fd/0"

خب حالا به عنوان مثال اگر برنامه زیر رو اجرا کنید میبینید که داخل stdin ترمینال شما بدون ارتباط Child and parrent از طریق stdin channel تونستید دیتا ارسال کنید.
import fs from "node:fs";

const stdinFd = fs.openSync("/proc/4561/fd/0", fs.constants.O_WRONLY);

fs.writeSync(stdinFd, Buffer.from("echo Write To stdin - NodeMaster"));

fs.closeSync(stdinFd);

نکته این هست که Sky is the limit. به عنوان مثال میتونید کار سم کنید که http request از طریق stdin بفرستید و response رو از stdout بخونید.
البته رابطه child and parrent همونطوری که تقریبا داخل docker هم میبینیم میتونه بهمون دسترسی بده که این چنل ها رو در دسترس بزاریم یا نه همونطوری که اگر "-i" استفاده نکنیم این چنل در دسترس نیست از طریق داکر. یک طوری مثل عوارضی بزرگ راه در نظر بگیرد.

این کار همینطور که میدونید به نوعی IPC هست اما اینجا یک سوال پیش میاد.
- وقتی نیاز نیست که دوتا Process رابطه Child and parrent داشته باشند تا روی stdin و stdout باهم ارتباط بگیرن. پس کجا محدودیت ایجاد میشه که این دوتا Process نتونن با هم روی این چنل ها ارتباط برقرار کنند؟
اینجا هست که یک ویژگی در کرنل لینوکس به اسم Namespace به ما کمک میکنه که مجموعه های مختلف از Process های ایزوله داشته باشیم و Process که در یک Namespace وجود دارند، نمیتواند با یک Process دیگر که در Namespace دیگر وجود دارد ارتباط روی stdout , stdin چنل بگیرد ( مگر socket )
منطقی هم هست چون namespace رو میشه دوتا machine مختلف در نظر گرفت تقریبا.( این موضوع درست مطلق نیست و بیشتر برای تصویر سازی هست )

حالا میخوام برگردم به مثال بالا اگر دقت کنید من مثل یک فایل رفتار کردم با fd/0. حالا با وجود این فکت که تمام IO device ها به نوعی فایل هستن میتونیم "lsusb" بزنیم فایل مربوط به کیبورد خودمون رو پیدا کنیم و براش درایور بنویسیم. که یک Process دیتا رو از روی کیبورد وقتی تایپ میکنیم بگیره و از طریق stdin مربوط به ترمینال تایپ کردن ما رو بفرسته برای TTY. این یکی رو واقعا دقیق نمیدونم چطور کار میکنه. حتی شاید این جمله یکم اشتباهات هم داشته باشه. ولی در کلیات حس میکنم اون پشت همچین اتفاقی داره میافته. که قطعا یک روز باهم دقیق برسیش میکنیم.
👍20
درود به همگی دوستان.
براتون سال خوش و پر از موفقیتی رو آرزو میکنم.
امیدوارم موفق باشید.🔥
👍30
یک مفهمومی در یادگیری مفاهیم عمیق وجود داره به اسم First principles thinking. خیلی خالصه میشه شکستن یک مسئله پیچیده به مسائل کوچک تر و برسی اون ها از طریق مفاهیم Fundamental. روز به روز که جلوتر میریم این موضوع کم رنگ تر و کم رنگ تر شده تا الان که باتوجه به پیشرفت LLM ها خیلی ها دیگه علاقه ای به داشتن کسب دانش عمیق درمورد یک موضوعی ندارند.
جدا از این موضوع خیلی ها از قدرتی که دانش Fundamental در هر موردی بهشون میده ( در اینجا برنامه نویسی ) خبر ندارن یا علاقه ای بهش ندارن و همین باعث میشه گاهی اوقات در یک Loop ناقص از LLM های مختلف درخواست فیکس کردن باگشون رو کنن یا در فورم های مختلف به دنبال چرایی مشکلشون بگردن و هیچ وقت ممکنه به این موضوع دقت نکنن که چقدر Fundamental میتونه راه گشا باشه براشون و اگر در این مورد خوب بودن خیلی موفق تر بودن.
به عنوان مثال در این سال ها کلی دوره آموزشی، مقاله، بلاگ پست، ویدیو یوتیوب، درمورد Event loop تهیه شده و همه دیدم ولی هیچکس نیومد تو این ویدیو ها به ما بگه که کل Event loop رو به صورت خیلی ساده میتونیم در همین چند خط کد #Clang ببینیم.
حجم چیز هایی که میشه از این man page و این تکه کد یاد گرفت درمورد مفاهیم AsyncIO و کلا IO واقعا مثال زدنی نیست و البته همین موضوع میتونه اهمیت یادگیری مفاهیم سیستم عامل رو دوباره به ما نشون بده.

گاهی اوقات بهتره وقتی یک مسئله ای داریم یک قدم عقب تر بریم و از یک زاویه دیگه بهش نگاه کنیم.

حالا سوال پیش میاد خب ایمان من میخوام Fundamental قوی بشم از کجا شروع کنم؟
فرقی نداره که Frontend dev هستین یا Backend.

سیستم عامل، شبکه، الگوریتم و البته برای FrontDev ها Web Api هم میشه در نظر گرفت.
https://man7.org/linux/man-pages/man7/epoll.7.html
👍20👎1
درود و وقت بخیر دوستان. امیدوارم حالتون خوب باشه.
اخیر یک ویدیو دیدم درمورد این که چطور در Netflix از #Java استفاده میکنن. سوال پیش میاد چرا این ویدیو باید برای ما جالب باشه و اهمیت بدیم؟
باتوجه به این که این روزا به شدت تکنولوژی در حال پیشرفت هست و هر روز ابزارها و فریمورک های جدید رو شاهد هستیم. این حس رو به ما القا میکنه که باید سریع باشیم و این تکنولوژی های جدید رو یاد بگیریم و اگر یاد نگیریم عقب میافتیم و در بازار کار جایی نخواهیم داشت!

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

نکته جالبی که در این ویدیو میبینیم جدا از زاویه دید فنی. زاویه دید بیزینسی هم رو میبینیم که چطور تیم فنی #Netflix رو تحت تاثیر خودش گذاشته که به عنوان مثال درمورد مهاجرت کدبیس ها از #Java 8 به #Java 17 صحبت میکنه که در چندسال پیش انجام شده و این رو به عنوان یک نکته مهم بیان میکنه و درموردش و تاثیراتش صحبت میکنه. دوباره با این حال بعد از این همه تلاشی که کردن روی ورژن های مثل 21 یا 24 که جدیدتر هستن نیومدن و قطعا تا سال چند سال آینده روی همین java 17 خواهند موند.

نکته بعدی خود #Java هست؟ چرا باوجود چیزایی مثل #Golang #Rust از زبانی که برای boomer ها بوده استفاده میکنن؟
خب جواب این هست چرا اصلا استفاده نکنن؟ اکوسیستم خوبی داره سرعت بالایی داره و از همه مهم تر خیلی خیلی Stable هست و از نظر هزینه براشون به صرفه نیست که مهاجرت کنن روی تکنولوژی های دیگه.

این صحبت ها به این معنی نیست که #Java خوب هست یا #Golang یا بقیه زبان ها بد یا خوب هستند. هدف صحبت امروز بیشتر این هست که لزوما برای موفق بودن همیشه نیازی نیست آخرین فریمورک آخرین تکنولوژی Backend خفن رو بلد باشیم. هنوز هم کدبیس های #COBOL هست و #CLang و #C++ به این زودی ها جایی نمیرن و البته چقدر شرکت هایی وجود داره که روی Java 8 و .NET 3.5 هستن و البته #PHP هم هنوز نمرده و نشانه هایی از مردن هم نداره جز در ویدیو های Tech influencer ها.

https://www.youtube.com/watch?v=XpunFFS-n8I
👍18
یکی از ابزار هایی که وقتی با #Postgres کار میکنید و کمتر استفاده میشه ولی خیلی کاربردی هست Window function ها هستن.
به صورت کلی Window function ها این قابلیت رو میدن که دسترسی داشته باشین به مجموعه row های قبل یا بعد از record که در حال حاظر در حال برسی هست.

به عنوان مثال سناریویی رو در نظر بگیرد که نیاز دارید یک سطر X رو با سطر های X+N یا X-N برسی کنید ( row های قبل یا بعد ). یکی از کاربرد هایی که ممکنه براتون داشته باشه داخل کار کردن سناریو هایی است که با Timeseries دیتا ها سرکار دارید.

سینتکس مربوط به استفاده از window function ها به صورت کلی به این صورت هستن.

window_function(arg1, arg2,..) OVER (
[PARTITION BY partition_expression]
[ORDER BY sort_expression [ASC | DESC] [NULLS {FIRST | LAST }])


- منظور از window_function در اینجا اون فانکشنی هست که میخوایم استفاده کنیم به عنوان مثال LAG function
- قسمت PARTITION BY به صورت کلی شباهت هایی به Group by دارد ولی در حال حاظر کاری بهشون نداریم.
- قسمت Order by هم ترتیب مقایسه Row ها رو با سطر بعد یا قبلش مشخص میکنه. دقیقا مثل Order by در حالت معمولی کار میکنه.

به صورت کلی window function های مختلفی داریم ولی برای درک بهتر و این که یک مثال ساده داشته باشیم LAG function هم کاربردی هست هم ساده.
فرض کنید یک table دارید که تعداد فروش محصولات رو برای هر سال دارد.
"year","sales_amount"
"2018","100"
"2019","120"
"2020","150"
"2021","180"

حالا سناریویی رو تصور کنید که میخواید در هر سطر برسی کنید که نسبت به سال قبل چقدر محصول بیشتر فروش داشتین؟ اینجا LAG function به داد شما میرسه
SELECT 
year,
sales_amount,
sales_amount - LAG(sales_amount , 1) OVER (ORDER BY year) AS sales_diff
FROM
sales;

در اینجا ما نیاز داریم که مقدار sales_amount سطر جاری رو از sales_amount سطر قبل که مربوط به سال قبل هست کم کنیم که تفاوت این دو رو بتونیم به دست بیاریم.
حالا Lag 3 تا arg میگیره که به این ترتیب هستن
- نام فیلدی که دیتا مربوط به سطر قبل یا بعدش رو لازم داریم.
- مقدار offset که میتوان عدد منفی به عنوان مثل -1 هم داشت. به صورت پیش فرض عدد 1 هست
- مقدار سوم که در اینجا نداریم default value هست که به صورت پیش فرض Null هست وقتی معمولا پیش میاد که در سطر اول یا اخر در هرکدوم از این سناریو ها ممکنه سطر بعدی یا قبلی وجود نداشته باشه پس در نتیجه یک مقداری باید قرار بگیره که پیش فرض Null هست

حالا وقتی Query رو اجرا کنید همچین نتیجه ای میبینید.
year,sales_amount,sales_diff
2018,100,
2019,120,20
2020,150,30
2021,180,30

جمع بندی:
کلا Window function ها ابزار های قدرتمندی هستن که بهمون خیلی کمک میکنن Query های پیچیده ای بزنیم که ممکنه در بیزینس لاجیک های خاص مخصوصا وقتی با timeseries دیتا کار داریم انجام بدیم.
موضوع بعدی این که ترکیبشون با Subquery یک ترکیب قدرتمند هست که رسما میشه Query هایی رو نوشت که در حالت عادی باتوجه به Data model که داریم ممکنه بدست آوردن اون دیتا غیرممکن باشه و قبل از هرچیزی برای رسیدن به نتیجه وقتی نیاز داریم که دیتا رو یک تغییرات بدیم و بعد از روی اون به اطلاعات برسیم; سناریو خوبی هست برای استفاده از این دو مفهوم.
👍19
Node Master
قرار بر این بود که درمورد تمام موضوعات BackEnd صحبت کنیم. ولی خب تا به امروز فقط درمورد Runtime های مربوط به js بیشتر NodeJS صحبت کردیم. امروز نگاهی به یکی از ویژگی های بسیار خوب #postgres اشاره میکنیم. شما میتونید یک فیلد با تایپ JSON تعریف کنید و دیتا رو…
قبلا در مورد استفاده از jsonb در #postgres صحبت کردیم و به صورت خلاصه اشاره کردیم چرا میتونه خوب باشه. امروز دوباره قراره یک نکته دیگ که خیلی خیلی میتونه مفید باشه یاد بگیرم. این که چطور اطلاعات یک جدول رو تبدیل کنیم به json ؟
حالا سوالی که برامون پیش میاد اصلا چرا باید همچین کاری کنیم؟ به صورت کلی گاهی اوقات نیاز دارید در هنگام Query زدن اطلاعات مربوط به polymorphic table ها رو همه و همه با جزیات در یک Query ببینید. در #MySQL ظاهرا راه حل های Native برای این گونه مسائل وجود داره که در آینده باهم یاد خواهیم گرفت ولی در Postgres با کمک Json ها که آزادی عمل زیادی بهتون میده میتونید هر کاری کنید از جمله حل کردن این گونه مسائل.

فرض کنید یک users table داریم با column های id, name , email. حالا میخواهیم تمام اطلاعات مربوط به هر row رو داخل یک column به اسم user_data داشته باشیم
SELECT to_json(users) AS user_data FROM users;

خب در اینجا ما از فانکشن کمکی to_json کمک گرفتیم که هر row در جدول users رو به json تبدیل کنیم که سطون های جدول users به عنوان key و مقادیر هر row به عنوان value در نظر گرفته میشود. این فانکشن کمکی به صورت کلی یکم محدود هست به این که کل سطون ها رو تبدیل به json میکنه. حالا اگر بخوایم قبل از json شدن روی دیتا مربوط به اون column های خاص یک کاری انجام بدیم مثلا type cast انجام بدیم چکار باید کنیم؟
اینجا json_build_object به نجات ما میاد.
SELECT
json_build_object(
'id',
u.id :: TEXT,
'base_mail_name',
split_part(u.email, '@', 1),
'fqdn',
split_part(u.email, '@', 2)
) AS users_data
FROM
users AS u;

اینجا رسما دیتا مربوط هر row رو میگیرم و دستی به شکلی که میخوایم در Result set نهایی داشته باشیم شکل میدیم. فانکشن json_build_object تعداد زوج از param ها رو میگیره که param های فرد به عنوان Key و param های زوج به عنوان Value نهایی ما در json هستن. فانکشن split_part هم مثل اینجا صرفا برای split کردن یک string هست مثل متد split در #JavaScript عمل میکنه.

به صورت کلی فانکشن های کمکی خیلی زیادی برای کار کردن با json ها در #Postgres هستن ولی این دوتا بین اون ها خیلی کاربردی تر هستن. بقیه خیلی خیلی خاص تر هستن. کلا استفاده از همین ها هم خیلی نمیبینیم چون به صورت روزمره کاربردی نیستن ولی داخل سناریو های خاصی که بالا به یکیش اشاره کردم این ها کمک خیلی بزرگی میکنند. یا حتی در استفاده از Union برای ایجاد یک interface یکسان برای Table های مربوط در Query.

نکته بعدی این که هردو فانکشن بالا ورژن jsonb هم دارند.
to_jsonb
jsonb_build_object

درمورد Performance اطلاعات دقیق ندارم و بیشتر نظر شخصی خودم هست.
- قطعا تاثیر منفی در Performance دارن ولی اونقدر کمک بزرگی میکنند که به هیچ عنوان این تاثیر منفی به چشم نمیاد برای مشکلاتی که از این روش ها استفاده میکنید.
- معمولا مشکلاتی که بالا اشاره کردم شخصا در کدبیس ها دیدم که به هردلیلی سناریو های مختلف که از این طریق میشه رفت جلو رو، در سطح application هندل کردن که خب اونجا قطعا هم دردسر خیلی بیشتری داره برای توسعه هم نگهداری و هم البته وب سرور رو درگیر کاری میکنه که لزوما براش ساخته و بهینه نشده. در نتیجه اینجا اگر تمام این موضوعات در نظر بگیری فدا کردن یک کوچولو Performance دیتابیس خیلی منطقی به نظر میاد.
👍10👎2
درود و وقت همگی بخیر امیدوارم حالتون خوب باشه.
بچه هایی که تازه کار هستن و #Backend رو مدت کمی هست کار میکنن ممکنه یکم براشون سوال باشه که به صورت کلی یک سیستم چه چیزهایی رو دارد و چطور این ها باهم کار میکنند. به جواب رسیدن برای هرکدوم از این سوال ها زمان زیادی ممکنه از ادم بگیره اگر راهنما خوبی هم وجود نداشته باشه.
پیشنهاد میکنم این دوره رو حتما ببینید.
https://downloadly.ir/elearning/video-tutorials/system-design-for-beginners/
بهتون دید خیلی خوبی میده که چه چیزایی رو حداقل باید بدونید و میتونه به عنوان یک Roadmap هم بهش نگاه کنید که در آینده در هرکدوم از بخش های مختلف این آموزش عمیق تر بشید.

اگر باتجربه تر هم هستید و سیستم دیزاین نیاز به refresher دارید یا کلا تا حالا کار نکردین شروع خوبی میتونه باشه.
👍22
درود و خسته نباشید دوستان امیدوارم حالتون خوب باشه.
اگر با lib هایی مثل #jest و #vitest برای پروژه هاتون تست نوشته باشید و البته بعد تلاش کرده باشین که سوییچ کنید روی std test runner خود #NodeJS که خیلی هم از Stable شدنش نمیگذره.
یکی از بزرگترین مشکلاتی که این Test runner داشت و تست نوشتن رو در یک سناریو واقعا آزار دهنده میکرد در آپدیت 22.17 LTS فیکس شده.
assert.partialDeepStrictEqual()

گاهی اوقات پیش میاد که میخواید یک subset از یک object رو assert کنید و نمیخواید کل اون attr های اون object رو assert کنید. تا قبل از این آپدیت این سناریو در STD test runner غیرممکن بود. شخصا واقعا خوشحالم که این رو خیلی سریع متوجه شدن و اضاف کردن چون همه چیزش خیلی خوب شده و فقط همین یدونه کم بود.
👍11
امیدوارم حالتون خوب باشه دوستان.
داخل آپدیت ES2025 یک static method جدید برای به اسم Promise.try اضافه شده و در این پست باهم برسیش میکنیم.
https://telegra.ph/%D9%85%D8%AA%D8%AF-%D8%AC%D8%AF%DB%8C%D8%AF-Promisetry-%D8%AF%D8%B1-ES2025-07-21

البته به صورت تستی با استفاده از telegra.ph شاید بهتر باشه
👍13