🔵proposal: runtime: change mutex profile to scale contention by number of blocked goroutines
🔴https://github.com/golang/go/issues/61015
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
🔴https://github.com/golang/go/issues/61015
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
👍3
🔵Can I convert a []T to an []interface{}?
🔴Not directly.
🟢It is disallowed by the language specification because the two types do not have the same representation in memory. It is necessary to copy the elements individually to the destination slice. This example converts a slice of int to a slice of interface{}:
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
🔴Not directly.
🟢It is disallowed by the language specification because the two types do not have the same representation in memory. It is necessary to copy the elements individually to the destination slice. This example converts a slice of int to a slice of interface{}:
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
👍4👎1🔥1🐳1
✅ Top software engineering principles
1. SOLID: An acronym for five design principles that improve code maintainability and readability:
- *Single Responsibility Principle (SRP)*: Each class or module should have only one reason to change, meaning it should have a single responsibility.
- *Open/Closed Principle (OCP)*: Software entities should be open for extension but closed for modification, promoting the use of inheritance and interfaces.
- *Liskov Substitution Principle (LSP)*: Subtypes must be substitutable for their base types, ensuring that derived classes follow the same contracts as their base classes.
- *Interface Segregation Principle (ISP)*: Clients should not be forced to depend on interfaces they do not use. Instead, create smaller, more focused interfaces.
- *Dependency Inversion Principle (DIP)*: High-level modules should not depend on low-level modules; both should depend on abstractions. Abstractions should not depend on details; details should depend on abstractions.
2. DRY (Don't Repeat Yourself): This principle states that developers should avoid duplicating code and logic. Reusing code through abstraction and modularization increases maintainability and reduces the potential for bugs.
3. KISS (Keep It Simple, Stupid): KISS emphasizes simplicity in software design. Developers should aim for solutions that are easy to understand and maintain, avoiding unnecessary complexity.
Here are a few more software engineering principles to consider:
4. YAGNI (You Aren't Gonna Need It): This principle encourages developers to avoid adding functionality until it is absolutely necessary. Over-engineering and adding features "just in case" can lead to bloated, hard-to-maintain code.
5. Separation of Concerns (SoC): This principle involves organizing code into distinct sections, each with a specific responsibility. Separation of concerns promotes modularity and maintainability.
6. Composition over Inheritance: Favor object composition over class inheritance when designing your code. Composition provides greater flexibility and promotes code reuse without the tight coupling often associated with inheritance.
7. Law of Demeter (LoD) or Principle of Least Knowledge: An object should only communicate with its immediate neighbors and should not have knowledge of the inner workings of other objects. This principle helps create loosely coupled systems.
8. Fail Fast: Design your software to fail as soon as possible when an error occurs, making it easier to identify and fix issues during development.
9. Encapsulate What Varies: Identify the parts of your code that are likely to change and encapsulate them to minimize the impact of future modifications.
These principles, along with SOLID, DRY, and KISS, can help guide you in creating well-designed, maintainable software systems. Keep in mind that these are guidelines, not strict rules, and should be applied with consideration for your specific project and its requirements.
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
1. SOLID: An acronym for five design principles that improve code maintainability and readability:
- *Single Responsibility Principle (SRP)*: Each class or module should have only one reason to change, meaning it should have a single responsibility.
- *Open/Closed Principle (OCP)*: Software entities should be open for extension but closed for modification, promoting the use of inheritance and interfaces.
- *Liskov Substitution Principle (LSP)*: Subtypes must be substitutable for their base types, ensuring that derived classes follow the same contracts as their base classes.
- *Interface Segregation Principle (ISP)*: Clients should not be forced to depend on interfaces they do not use. Instead, create smaller, more focused interfaces.
- *Dependency Inversion Principle (DIP)*: High-level modules should not depend on low-level modules; both should depend on abstractions. Abstractions should not depend on details; details should depend on abstractions.
2. DRY (Don't Repeat Yourself): This principle states that developers should avoid duplicating code and logic. Reusing code through abstraction and modularization increases maintainability and reduces the potential for bugs.
3. KISS (Keep It Simple, Stupid): KISS emphasizes simplicity in software design. Developers should aim for solutions that are easy to understand and maintain, avoiding unnecessary complexity.
Here are a few more software engineering principles to consider:
4. YAGNI (You Aren't Gonna Need It): This principle encourages developers to avoid adding functionality until it is absolutely necessary. Over-engineering and adding features "just in case" can lead to bloated, hard-to-maintain code.
5. Separation of Concerns (SoC): This principle involves organizing code into distinct sections, each with a specific responsibility. Separation of concerns promotes modularity and maintainability.
6. Composition over Inheritance: Favor object composition over class inheritance when designing your code. Composition provides greater flexibility and promotes code reuse without the tight coupling often associated with inheritance.
7. Law of Demeter (LoD) or Principle of Least Knowledge: An object should only communicate with its immediate neighbors and should not have knowledge of the inner workings of other objects. This principle helps create loosely coupled systems.
8. Fail Fast: Design your software to fail as soon as possible when an error occurs, making it easier to identify and fix issues during development.
9. Encapsulate What Varies: Identify the parts of your code that are likely to change and encapsulate them to minimize the impact of future modifications.
These principles, along with SOLID, DRY, and KISS, can help guide you in creating well-designed, maintainable software systems. Keep in mind that these are guidelines, not strict rules, and should be applied with consideration for your specific project and its requirements.
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
👍4🕊3🗿2💊1
✅ What is it Pitfalls in software engineering?
In software engineering, a pitfall refers to a common mistake or problem that developers may encounter during the development process. These pitfalls can lead to issues such as increased development time, poor code quality, difficult maintenance, or reduced performance. Being aware of these pitfalls can help developers avoid them and create better software.
Here are some common pitfalls in software engineering:
1. Insufficient planning and requirements analysis: Skipping or rushing through the planning and requirements gathering phase can lead to misaligned expectations, feature creep, and wasted development effort.
2. Poor communication: Inadequate communication among team members, stakeholders, or clients can lead to misunderstandings, incorrect implementation, and project delays.
3. Ignoring best practices: Neglecting established best practices, such as coding standards, design patterns, and architectural principles, can result in code that is difficult to understand, maintain, and scale.
4. Lack of testing: Failing to implement proper testing procedures can lead to undetected bugs and issues in the software, which can result in poor user experiences and increased maintenance costs.
5. Not handling errors and exceptions: Ignoring or improperly handling errors and exceptions can cause software to fail unexpectedly and make it difficult to diagnose and fix issues.
6. Over-engineering: Implementing overly complex solutions or adding unnecessary features can make the software harder to maintain and understand, and can increase the risk of bugs.
7. Tight coupling: Writing code with high levels of dependency between components can make it harder to modify, extend, or reuse parts of the software.
8. Not considering performance: Focusing solely on functionality without considering the performance implications can lead to software that runs slowly or consumes excessive resources.
9. Ignoring user feedback: Neglecting user feedback during the development process can result in software that does not meet user needs or is difficult to use.
10. Inadequate documentation: Failing to create and maintain proper documentation can make it difficult for developers to understand and maintain the software, especially as the team grows or changes.
By being aware of these common pitfalls, software engineers can take proactive steps to avoid them and create higher-quality software that meets the needs of users and stakeholders. It is important to continuously learn from past experiences, share knowledge with team members, and stay up-to-date with best practices to minimize the impact of these pitfalls on your software projects.
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
In software engineering, a pitfall refers to a common mistake or problem that developers may encounter during the development process. These pitfalls can lead to issues such as increased development time, poor code quality, difficult maintenance, or reduced performance. Being aware of these pitfalls can help developers avoid them and create better software.
Here are some common pitfalls in software engineering:
1. Insufficient planning and requirements analysis: Skipping or rushing through the planning and requirements gathering phase can lead to misaligned expectations, feature creep, and wasted development effort.
2. Poor communication: Inadequate communication among team members, stakeholders, or clients can lead to misunderstandings, incorrect implementation, and project delays.
3. Ignoring best practices: Neglecting established best practices, such as coding standards, design patterns, and architectural principles, can result in code that is difficult to understand, maintain, and scale.
4. Lack of testing: Failing to implement proper testing procedures can lead to undetected bugs and issues in the software, which can result in poor user experiences and increased maintenance costs.
5. Not handling errors and exceptions: Ignoring or improperly handling errors and exceptions can cause software to fail unexpectedly and make it difficult to diagnose and fix issues.
6. Over-engineering: Implementing overly complex solutions or adding unnecessary features can make the software harder to maintain and understand, and can increase the risk of bugs.
7. Tight coupling: Writing code with high levels of dependency between components can make it harder to modify, extend, or reuse parts of the software.
8. Not considering performance: Focusing solely on functionality without considering the performance implications can lead to software that runs slowly or consumes excessive resources.
9. Ignoring user feedback: Neglecting user feedback during the development process can result in software that does not meet user needs or is difficult to use.
10. Inadequate documentation: Failing to create and maintain proper documentation can make it difficult for developers to understand and maintain the software, especially as the team grows or changes.
By being aware of these common pitfalls, software engineers can take proactive steps to avoid them and create higher-quality software that meets the needs of users and stakeholders. It is important to continuously learn from past experiences, share knowledge with team members, and stay up-to-date with best practices to minimize the impact of these pitfalls on your software projects.
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
👍7👏2🗿1
✅ When choosing a database engine for your software project? type of database engine?
1. SQL (Relational) Databases:
- Structured data model with a schema: Relational databases use tables with predefined columns and relationships between tables, making them suitable for structured data.
- ACID transactions: SQL databases provide strong consistency guarantees with Atomicity, Consistency, Isolation, and Durability (ACID) properties.
- Powerful query language: SQL allows for complex queries and data manipulations.
- Wide adoption and ecosystem: SQL databases have been around for a long time and have a mature ecosystem with numerous tools, libraries, and resources.
Examples: PostgreSQL, MySQL, Microsoft SQL Server, Oracle Database
2. NoSQL Databases:
- Flexible data model: NoSQL databases do not require a predefined schema, allowing for greater flexibility in data organization. They can handle unstructured or semi-structured data.
- Scalability: NoSQL databases are typically designed to scale horizontally, making them a good choice for large-scale, distributed systems.
- Varied data storage models: NoSQL databases encompass several data models, such as key-value, document, column-family, and graph, which can be more suitable for specific use cases.
Examples: MongoDB (Document), Cassandra (Column-family), Redis (Key-value), Neo4j (Graph)
3. Time Series Databases:
- Time-based data: Time series databases are designed for handling time-stamped data, such as sensor readings, stock prices, or server metrics.
- High write and query performance: These databases are optimized for ingesting large volumes of time-based data and querying it efficiently.
- Data aggregation and downsampling: Time series databases often provide built-in functions for aggregating and downsampling data, which is useful for analyzing trends over time.
Examples: InfluxDB, TimescaleDB, OpenTSDB
4. NewSQL Databases:
- Combination of SQL and NoSQL: NewSQL databases aim to combine the benefits of relational databases (ACID transactions, SQL query language) with the scalability and performance of NoSQL databases.
- Distributed architecture: NewSQL databases are designed for distributed environments, providing high availability and fault tolerance.
Examples: CockroachDB, Google Spanner, TiDB
When choosing a database engine, consider the following factors:
- Data model and schema flexibility
- Query patterns and access requirements
- Consistency and transaction guarantees
- Scalability and performance needs
- Operational complexity and management
Evaluate your project's specific requirements and use cases to determine the best database engine for your needs. It's also worth noting that some projects may benefit from using a combination of database engines to address different aspects of the application.
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
1. SQL (Relational) Databases:
- Structured data model with a schema: Relational databases use tables with predefined columns and relationships between tables, making them suitable for structured data.
- ACID transactions: SQL databases provide strong consistency guarantees with Atomicity, Consistency, Isolation, and Durability (ACID) properties.
- Powerful query language: SQL allows for complex queries and data manipulations.
- Wide adoption and ecosystem: SQL databases have been around for a long time and have a mature ecosystem with numerous tools, libraries, and resources.
Examples: PostgreSQL, MySQL, Microsoft SQL Server, Oracle Database
2. NoSQL Databases:
- Flexible data model: NoSQL databases do not require a predefined schema, allowing for greater flexibility in data organization. They can handle unstructured or semi-structured data.
- Scalability: NoSQL databases are typically designed to scale horizontally, making them a good choice for large-scale, distributed systems.
- Varied data storage models: NoSQL databases encompass several data models, such as key-value, document, column-family, and graph, which can be more suitable for specific use cases.
Examples: MongoDB (Document), Cassandra (Column-family), Redis (Key-value), Neo4j (Graph)
3. Time Series Databases:
- Time-based data: Time series databases are designed for handling time-stamped data, such as sensor readings, stock prices, or server metrics.
- High write and query performance: These databases are optimized for ingesting large volumes of time-based data and querying it efficiently.
- Data aggregation and downsampling: Time series databases often provide built-in functions for aggregating and downsampling data, which is useful for analyzing trends over time.
Examples: InfluxDB, TimescaleDB, OpenTSDB
4. NewSQL Databases:
- Combination of SQL and NoSQL: NewSQL databases aim to combine the benefits of relational databases (ACID transactions, SQL query language) with the scalability and performance of NoSQL databases.
- Distributed architecture: NewSQL databases are designed for distributed environments, providing high availability and fault tolerance.
Examples: CockroachDB, Google Spanner, TiDB
When choosing a database engine, consider the following factors:
- Data model and schema flexibility
- Query patterns and access requirements
- Consistency and transaction guarantees
- Scalability and performance needs
- Operational complexity and management
Evaluate your project's specific requirements and use cases to determine the best database engine for your needs. It's also worth noting that some projects may benefit from using a combination of database engines to address different aspects of the application.
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
🔥4🤔3👍2👏1
✅ List of relations in SQL and NOSQL database
1. One-to-One (1:1):
- SQL: Use a foreign key constraint in one table referencing the primary key of another table.
- NoSQL: Embed the related document within the parent document (e.g., in MongoDB) or store the related key-value pair in the same record (e.g., in a column-family database like Cassandra).
2. One-to-Many (1:N):
- SQL: Use a foreign key constraint in the child table referencing the primary key of the parent table.
- NoSQL: Embed the child documents within the parent document (e.g., in MongoDB) or store the related key-value pairs in the same record (e.g., in a column-family database like Cassandra).
3. Many-to-One (N:1):
- SQL: Similar to one-to-many, use a foreign key constraint in the child table referencing the primary key of the parent table.
- NoSQL: Store a reference to the parent document in the child document (e.g., in MongoDB) or store the parent key in the child record (e.g., in a column-family database like Cassandra).
4. Many-to-Many (N:M):
- SQL: Create a junction table with foreign key constraints referencing the primary keys of both related tables.
- NoSQL: Store an array of references to the related documents in each document (e.g., in MongoDB) or store the related keys in a separate record (e.g., in a column-family database like Cassandra).
5. Self-referencing (recursive):
- SQL: Use a foreign key constraint in the table referencing its own primary key.
- NoSQL: Embed the related documents within the same document (e.g., in MongoDB) or store the related key-value pairs in the same record (e.g., in a column-family database like Cassandra).
6. Hierarchical:
- SQL: Use a foreign key constraint in the table referencing its own primary key (similar to self-referencing) or use a closure table to represent the hierarchy.
- NoSQL: Use a recursive document embedding (e.g., in MongoDB) or a recursive key-value storage (e.g., in a column-family database like Cassandra).
7. Graph relationships:
- SQL: Model graph relationships using adjacency lists, path enumeration, or closure tables.
- NoSQL: Use a dedicated graph database (e.g., Neo4j) or store the relationships as edges in a document or column-family database (e.g., MongoDB or Cassandra).
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
1. One-to-One (1:1):
- SQL: Use a foreign key constraint in one table referencing the primary key of another table.
- NoSQL: Embed the related document within the parent document (e.g., in MongoDB) or store the related key-value pair in the same record (e.g., in a column-family database like Cassandra).
2. One-to-Many (1:N):
- SQL: Use a foreign key constraint in the child table referencing the primary key of the parent table.
- NoSQL: Embed the child documents within the parent document (e.g., in MongoDB) or store the related key-value pairs in the same record (e.g., in a column-family database like Cassandra).
3. Many-to-One (N:1):
- SQL: Similar to one-to-many, use a foreign key constraint in the child table referencing the primary key of the parent table.
- NoSQL: Store a reference to the parent document in the child document (e.g., in MongoDB) or store the parent key in the child record (e.g., in a column-family database like Cassandra).
4. Many-to-Many (N:M):
- SQL: Create a junction table with foreign key constraints referencing the primary keys of both related tables.
- NoSQL: Store an array of references to the related documents in each document (e.g., in MongoDB) or store the related keys in a separate record (e.g., in a column-family database like Cassandra).
5. Self-referencing (recursive):
- SQL: Use a foreign key constraint in the table referencing its own primary key.
- NoSQL: Embed the related documents within the same document (e.g., in MongoDB) or store the related key-value pairs in the same record (e.g., in a column-family database like Cassandra).
6. Hierarchical:
- SQL: Use a foreign key constraint in the table referencing its own primary key (similar to self-referencing) or use a closure table to represent the hierarchy.
- NoSQL: Use a recursive document embedding (e.g., in MongoDB) or a recursive key-value storage (e.g., in a column-family database like Cassandra).
7. Graph relationships:
- SQL: Model graph relationships using adjacency lists, path enumeration, or closure tables.
- NoSQL: Use a dedicated graph database (e.g., Neo4j) or store the relationships as edges in a document or column-family database (e.g., MongoDB or Cassandra).
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
🔥5👍2👏1🤣1
🔵Waiting for go1.21: Execution Tracing with < 1% Overhead
🟢https://blog.felixge.de/waiting-for-go1-21-execution-tracing-with-less-than-one-percent-overhead/
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
🟢https://blog.felixge.de/waiting-for-go1-21-execution-tracing-with-less-than-one-percent-overhead/
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
👏2👍1🍾1
👍1🔥1💊1
🔵FlameScope for Go
🟢Learn how to visualize CPU samples from Go execution traces with FlameScope.
🔴https://blog.felixge.de/flamescope-for-go/
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
🟢Learn how to visualize CPU samples from Go execution traces with FlameScope.
🔴https://blog.felixge.de/flamescope-for-go/
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
👍2🔥1
🔵8 Unexpected Profiling Use Cases Beyond Performance Optimization
🔻Detect Workload Shifts
🔻Detect Data Nesting
🔻Detect Dead Code
🔻Debug Unresponsiveness
🔻Debug Errors
🔻Verify Deployments
🔻Improve Maintainability
🔻Faster Onboarding
🟢https://blog.felixge.de/8-unexpected-profiling-use-cases-beyond-performance-optimization/
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
🔻Detect Workload Shifts
🔻Detect Data Nesting
🔻Detect Dead Code
🔻Debug Unresponsiveness
🔻Debug Errors
🔻Verify Deployments
🔻Improve Maintainability
🔻Faster Onboarding
🟢https://blog.felixge.de/8-unexpected-profiling-use-cases-beyond-performance-optimization/
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
👍3
🎉 Go 1.20.6 and 1.19.11 are released!
🔐 Security: Includes security fixes for CVE-2023-29406 and Go issue go.dev/issue/60374
📢 Announcement: https://groups.google.com/g/golang-announce/c/2q13H6LEEx0
📦 Download: go.dev/dl/#go1.20.6
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
🔐 Security: Includes security fixes for CVE-2023-29406 and Go issue go.dev/issue/60374
📢 Announcement: https://groups.google.com/g/golang-announce/c/2q13H6LEEx0
📦 Download: go.dev/dl/#go1.20.6
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
🎉1🍌1🍾1🗿1
درود دوستان ،تیم ما در حال ارزیابی و انجام تحقیقات روی یه پروژه در حوزه سینما هست؛
ممنون میشیم چند دقیقه از وقتتون رو بذارید و این پرسشنامه رو تکمیل کنید 😊💙
🔰 yun.ir/or5em
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
ممنون میشیم چند دقیقه از وقتتون رو بذارید و این پرسشنامه رو تکمیل کنید 😊💙
🔰 yun.ir/or5em
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
yun.ir
کوتاه کننده لینک
سرویس کوتاه کننده لینک با قابلیت انتخاب آدرس دلخواه برای لینک کوتاه شده و همچنین رمز عبور جهت مشاهده، ارائه خدمات متنوع دیگری از قبیل ایجاد لینک لیست و کوتاه کردن متن و ایجاد نظر سنجی آنلاین علاوه بر قابلیت کوتاه کردن لینک در این وبسایت فراهم آمده است
👏4👍3👎3❤2🕊2
✅ Govulncheck v1.0.0 is released!
Govulncheck is a command-line tool that helps Go users find known vulnerabilities in their project dependencies. The tool can analyze both codebases and binaries, and it reduces noise by prioritizing vulnerabilities in functions that your code is actually calling.
https://go.dev/blog/govulncheck
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
Govulncheck is a command-line tool that helps Go users find known vulnerabilities in their project dependencies. The tool can analyze both codebases and binaries, and it reduces noise by prioritizing vulnerabilities in functions that your code is actually calling.
https://go.dev/blog/govulncheck
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
go.dev
Govulncheck v1.0.0 is released! - The Go Programming Language
Version v1.0.0 of golang.org/x/vuln has been released, introducing a new API and other improvements.
👍8
🎉 Go 1.21 Release Candidate 3 is released!
🏃♂️ Run it in dev! Run it in prod! File bugs! go.dev/issue/new
🗣 Announcement: https://groups.google.com/g/golang-announce/c/5golCy-_yK0
📦 Download: go.dev/dl/#go1.21rc3
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
🏃♂️ Run it in dev! Run it in prod! File bugs! go.dev/issue/new
🗣 Announcement: https://groups.google.com/g/golang-announce/c/5golCy-_yK0
📦 Download: go.dev/dl/#go1.21rc3
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
GitHub
GitHub is where people build software. More than 150 million people use GitHub to discover, fork, and contribute to over 420 million projects.
🍾2🕊1
ماکروسافت به جایگزین کردن کدهای هسته ویندوز با Rust ادامه میده. به نظر میرسه در چند سال آینده قرار ویندوز تبدیل بشه به یکی از امن ترین سیستم عامل های موجود!
نکته مهمتر اینکه Rust هزینه توسعه سیستم عامل در دراز مدت بسیار پایین میاره و این یعنی توسعه سریعتر
https://www.itpro.com/software/windows/microsoft-continues-its-rust-mission-with-new-kernel-features
#DevTwitter | <Rust راه/>
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
نکته مهمتر اینکه Rust هزینه توسعه سیستم عامل در دراز مدت بسیار پایین میاره و این یعنی توسعه سریعتر
https://www.itpro.com/software/windows/microsoft-continues-its-rust-mission-with-new-kernel-features
#DevTwitter | <Rust راه/>
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
👍13💊2🕊1
این سایت مجموعه ای از سوالات SQL ای داره که روی یه دیتابیس از پیش ساخته شده سوال میپرسه و دارای بخشهای مختلفیه که قسمتهای مختلف SQL رو ازتون تست میگیری و میتونین عملی باهاش SQL رو یاد بگیرید.
https://pgexercises.com
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
https://pgexercises.com
➖➖➖➖➖➖➖➖
🕊 @gopher_academy
👍12