<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/rss.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Codeduthu</title><description>Blog về lập trình của Thắng - Software, Game và mọi thứ xung quanh</description><link>https://codeduthu.com</link><item><title>Fixing CORS Issue When Calling API in React Native</title><link>https://codeduthu.com/posts/react-native-fix-cors-by-rn-fetch-blob</link><guid isPermaLink="true">https://codeduthu.com/posts/react-native-fix-cors-by-rn-fetch-blob</guid><description>A guide on using rn-fetch-blob to address CORS errors when making API calls in React Native.</description><pubDate>Fri, 22 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Fixing CORS Issue When Calling API&lt;/p&gt;
&lt;h2&gt;Introduction:&lt;/h2&gt;
&lt;p&gt;Many developers face issues related to CORS. But what is CORS? CORS is a mechanism that allows various resources (JavaScript) on a web page to be requested from a domain different from the domain of that page. This is the CORS policy error that most developers encounter. When calling an API to a server without the Access-Control-Allow-Origin header or with an invalid value, this error occurs, and data cannot be retrieved from the API.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./fetch.webp&quot; alt=&quot;image.png&quot; /&gt;
&amp;lt;!-- truncate --&amp;gt;&lt;/p&gt;
&lt;h2&gt;Installing rn-fetch-blob to Address the Issue&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;First, we need to install the rn-fetch-blob library.
If using npm:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;npm install --save rn-fetch-blob
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;using yarn&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn add rn-fetch-blob
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;To use it on IOS, add the following to the Podfile:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;pod &apos;rn-fetch-blob&apos;,
    :path =&amp;gt; &apos;../node_modules/rn-fetch-blob&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;How it works:
&lt;img src=&quot;./blob.webp&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Example of usage:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;import RNFetchBlob from &apos;rn-fetch-blob&apos;;

export async function apiLogin({
  phone,
  password,
}: {
  phone: number | string;
  password: string;
}): Promise&amp;lt;any&amp;gt; {
  return RNFetchBlob.config({
    trusty: true,
  }).fetch(
    &apos;POST&apos;,
    `${URl_API}/api/auth/login?phone=${phone}&amp;amp;password=${password}`,
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now your API calls will work. In the example, I&apos;m demonstrating an API login with parameters phone and password. The use of trusty: true in RNFetchBlob.config helps us resolve this issue.&lt;/p&gt;
&lt;h2&gt;Other Ways to Handle CORS Errors&lt;/h2&gt;
&lt;p&gt;A common misconception, especially for developers working with APIs from large companies with comprehensive documentation, is thinking that CORS is a frontend task. But in reality, CORS is entirely a backend task.&lt;/p&gt;
&lt;p&gt;You can communicate with the backend to handle CORS.&lt;/p&gt;
&lt;p&gt;You can change the project&apos;s port to match.&lt;/p&gt;
&lt;p&gt;Both approaches are effective, but for standardization, it&apos;s best to consult the backend for the most accurate handling.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Using rn-fetch-blob is straightforward and easy, although it may not be the most optimal solution. Still, it can be a choice for you in cases where you face challenges, and the project needs to progress quickly without relying heavily on the backend.&lt;/p&gt;
&lt;p&gt;I hope this article is helpful to you. Thank you for reading!&lt;/p&gt;
&lt;p&gt;If you have any questions or comments, please leave them below. We can discuss this topic together.&lt;/p&gt;
</content:encoded><author>Pham Quyet Thang</author></item><item><title>React - Uploading Images and Videos in React Quill using Cloudinary</title><link>https://codeduthu.com/posts/upload-image-video-in-richtext-editor</link><guid isPermaLink="true">https://codeduthu.com/posts/upload-image-video-in-richtext-editor</guid><description>Guide on using react-quill to create a rich text editor (WYSIWYG) and integrating Cloudinary for image storage in posts</description><pubDate>Fri, 22 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Uploading Images and Videos in React Quill using Cloudinary&lt;/h1&gt;
&lt;h3&gt;1.Introduction:&lt;/h3&gt;
&lt;p&gt;In the process of developing web applications or blogs, providing a rich text editor for users is a common requirement. This allows users to create, edit, and format their content flexibly and easily. One popular text editor in the programming community is React Quill, known for its high customization and easy integration into your React projects.&lt;/p&gt;
&lt;p&gt;However, allowing users to upload and insert images or videos into the text editor is not a simple task. Especially when you need to store and manage thousands of multimedia files. The solution is to use a powerful cloud image storage service like Cloudinary. Cloudinary allows you to store, upload, and manage images and videos efficiently, enhancing the functionality and performance of your application.&lt;/p&gt;
&lt;p&gt;In this article, we will learn how to integrate React Quill with the Cloudinary image storage service to address this complex issue. Together, we will build an editor that enables users to conveniently and quickly upload and insert images and videos.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;React Quill: An open-source text editor that allows users to create and edit content with various formats.&lt;/li&gt;
&lt;li&gt;Cloudinary: A powerful cloud storage service that supports easy management, uploading, and processing of images and videos.
&amp;lt;!-- truncate --&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. Installing react-quill&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;First, we need to initialize a React project using Vite or create-react-app.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;yarn create vite react-quill-upload --template react-ts
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Install react-quill:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;yarn add react-quill
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Import react-quill component:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;import React, { useState } from &apos;react&apos;;
import ReactQuill from &apos;react-quill&apos;;
import &apos;react-quill/dist/quill.snow.css&apos;;

function MyComponent() {
  const [value, setValue] = useState(&apos;&apos;);
  const reactQuillRef = useRef&amp;lt;ReactQuill&amp;gt;(null);

  return &amp;lt;ReactQuill ref={reactQuillRef} theme=&quot;snow&quot; value={value} onChange={setValue} /&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;To upload images in the quill editor, declare the image in the modules and formats section.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;ReactQuill
      ref={reactQuillRef}
      theme=&quot;snow&quot;
      placeholder=&quot;Start writing...&quot;
      modules={{
        toolbar: {
          container: [
            [{ header: &quot;1&quot; }, { header: &quot;2&quot; }, { font: [] }],
            [{ size: [] }],
            [&quot;bold&quot;, &quot;italic&quot;, &quot;underline&quot;, &quot;strike&quot;, &quot;blockquote&quot;],
            [
              { list: &quot;ordered&quot; },
              { list: &quot;bullet&quot; },
              { indent: &quot;-1&quot; },
              { indent: &quot;+1&quot; },
            ],
            [&quot;link&quot;, &quot;image&quot;, &quot;video&quot;],
            [&quot;code-block&quot;],
            [&quot;clean&quot;],
          ],
        },
        clipboard: {
          matchVisual: false,
        },
      }}
      formats={[
        &quot;header&quot;,
        &quot;font&quot;,
        &quot;size&quot;,
        &quot;bold&quot;,
        &quot;italic&quot;,
        &quot;underline&quot;,
        &quot;strike&quot;,
        &quot;blockquote&quot;,
        &quot;list&quot;,
        &quot;bullet&quot;,
        &quot;indent&quot;,
        &quot;link&quot;,
        &quot;image&quot;,
        &quot;video&quot;,
        &quot;code-block&quot;,
      ]}
      value={value}
      onChange={onChange}
    /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Now you will see the upload image icon on the toolbar of react-quill. Import and print the entire text content, and you will see that by default, react-quill saves your image as base-64:
&lt;img src=&quot;./1.webp&quot; alt=&quot;image.png&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;=&amp;gt; If using this default approach, we can store the image in the database as base-64. In the demo, I only use small-sized images. If the image size is larger, the base-64 string will be larger, consuming more memory.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3. Handle upload image&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;To avoid storing images in the text content as base-64, we need to integrate a cloud service and only store the image&apos;s link. Next, I will guide you on handling the upload action of react-quill and using Cloudinary to store it (you can do the same with any other cloud, e.g., Firebase Storage, ...).&lt;/li&gt;
&lt;li&gt;Add the imageHandler&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt; &amp;lt;ReactQuill
      ref={reactQuillRef}
      theme=&quot;snow&quot;
      placeholder=&quot;Start writing...&quot;
      modules={{
        toolbar: {
          container: [
             ...
            [&quot;link&quot;, &quot;image&quot;, &quot;video&quot;],
            [&quot;code-block&quot;],
            [&quot;clean&quot;],
          ],
          handlers: {
            image: imageHandler,   // &amp;lt;- 
          },
        },
        clipboard: {
          matchVisual: false,
        },
      }}
      ...
    /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;  const imageHandler = useCallback(() =&amp;gt; {
    const input = document.createElement(&quot;input&quot;);
    input.setAttribute(&quot;type&quot;, &quot;file&quot;);
    input.setAttribute(&quot;accept&quot;, &quot;image/*&quot;);
    input.click();
    input.onchange = async () =&amp;gt; {
      if (input !== null &amp;amp;&amp;amp; input.files !== null) {
        const file = input.files[0];
        console.log(file)
      }
    };
  }, []);
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Explanation: In the code above, I added a function to handle the image container of react-quill. In the imageHandler function, I create an input file element and trigger a click() to open the file import window. You can extend this part to open the cloudinary upload widget ( &lt;a href=&quot;https://cloudinary.com/documentation/react_image_and_video_upload&quot;&gt;read more&lt;/a&gt; ). &lt;strong&gt;Using the widget is more secure and efficient because we can reuse previously uploaded images. If you have time and need, you should use that method!&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Function to upload the image to Cloudinary:
There are many ways to upload to Cloudinary, but I choose the simplest method of calling the API:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;const uploadToCloudinary = async (file: File): Promise&amp;lt;string&amp;gt; =&amp;gt; {
  const formData = new FormData();
  formData.append(&quot;file&quot;, file);
  formData.append(
    &quot;upload_preset&quot;,
    import.meta.env.VITE_CLOUDINARY_PRESET
  );
  const res = await fetch(
    `https://api.cloudinary.com/v1_1/${
      import.meta.env.VITE_CLOUDINARY_NAME
    }/upload`,
    { method: &quot;POST&quot;, body: formData }
  );
  const data = await res.json();
  const url = data.url;

  return url
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Explanation: To upload an image to Cloudinary via the API, you need the Product Name and upload_preset, which you can obtain from the cloudinary settings page (set the upload_preset mode to Unsigned for simplicity; for enhanced security, you can use other cloudinary upload methods).
&lt;img src=&quot;./2.webp&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Insert the image URL returned from Cloudinary into the text content.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;  const imageHandler = useCallback(() =&amp;gt; {
    const input = document.createElement(&quot;input&quot;);
    input.setAttribute(&quot;type&quot;, &quot;file&quot;);
    input.setAttribute(&quot;accept&quot;, &quot;image/*&quot;);
    input.click();
    input.onchange = async () =&amp;gt; {
      if (input !== null &amp;amp;&amp;amp; input.files !== null) {
        const file = input.files[0];
        const url = await uploadToCloudinary(file);
        const quill = reactQuillRef.current;
        if (quill) {
          const range = quill.getEditorSelection();
          range &amp;amp;&amp;amp; quill.getEditor().insertEmbed(range.index, &quot;image&quot;, url);
        }
      }
    };
  }, []);
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Explanation: After obtaining the URL from uploading to Cloudinary, we need to assign it to the correct position of the corresponding img tag in the text content:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;const range = quill.getEditorSelection();
range &amp;amp;&amp;amp; quill.getEditor().insertEmbed(range.index, &quot;image&quot;, url);
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;This part is to determine the position of the img tag and assign it with the URL returned from Cloudinary (before this, use useRef to reference the ReactQuill component).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;And here is the result, now the text content only contains the link of the image instead of base-64:
&lt;img src=&quot;./3.webp&quot; alt=&quot;image.png&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can find the entire source code at: https://github.com/phamquyetthang/react-quill-image-upload&lt;/p&gt;
&lt;h3&gt;4. Conclusion&lt;/h3&gt;
&lt;p&gt;This is my simple guide on handling image uploads in react-quill; you can do something similar with video uploads!&lt;/p&gt;
&lt;p&gt;You can view the entire code of this tutorial on my GitHub: https://github.com/phamquyetthang/react-quill-image-upload&lt;/p&gt;
&lt;p&gt;I hope this article is helpful to you. Thank you for reading!&lt;/p&gt;
&lt;p&gt;If you have any questions or comments, please leave them below.&lt;/p&gt;
</content:encoded><author>Pham Quyet Thang</author></item><item><title>Securing Swagger Documentation with express-basic-auth in Nodejs - Nestjs | Code đủ thứ</title><link>https://codeduthu.com/posts/express-basic-auth-swagger-doc</link><guid isPermaLink="true">https://codeduthu.com/posts/express-basic-auth-swagger-doc</guid><description>Learn how to secure your Swagger API documentation in Node.js and NestJS projects using the express-basic-auth library, with step-by-step examples for both JavaScript and TypeScript.</description><pubDate>Thu, 28 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Image } from &apos;astro:assets&apos;;
import basicAuth from &apos;./basic-auth-1.png&apos;;&lt;/p&gt;
&lt;p&gt;Swagger is a powerful tool for creating and managing API documentation. However, securing Swagger documents is crucial to ensure that sensitive information is not exposed. In this article, we will explore how to use the express-basic-auth library to protect Swagger documentation pages in JavaScript and TypeScript projects. We will focus on two cases: a regular JavaScript/TypeScript project and a NestJS project with @nestjs/swagger.&lt;/p&gt;
&lt;p&gt;After implementation, a user/password input form will appear when accessing the document page, and the correct credentials must be entered to view the document:
&amp;lt;Image   src={basicAuth} alt=&quot;Basic auth&quot; style={{height: 300}} height={300} /&amp;gt;&lt;/p&gt;
&lt;h2&gt;1. Install the express-basic-auth library&lt;/h2&gt;
&lt;p&gt;First, we need to install the express-basic-auth library. For regular JavaScript/TypeScript projects, you can run the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install express-basic-auth
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you are using TypeScript, add types for express-basic-auth:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install --save-dev @types/express-basic-auth
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2. Secure Swagger Document Page in JavaScript/TypeScript Projects&lt;/h2&gt;
&lt;p&gt;JavaScript&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// app.js
const express = require(&quot;express&quot;);
const basicAuth = require(&quot;express-basic-auth&quot;);
const swaggerUi = require(&quot;swagger-ui-express&quot;);
const swaggerDocument = require(&quot;./swagger.json&quot;);

const app = express();

// Secure Swagger page with express-basic-auth
const users = { admin: &quot;password123&quot; };
app.use(
  &quot;/api-docs&quot;,
  basicAuth({ users, challenge: true }),
  swaggerUi.serve,
  swaggerUi.setup(swaggerDocument)
);

// Other routes and middleware of the application
// ...

const PORT = process.env.PORT || 3000;
app.listen(PORT, () =&amp;gt; {
  console.log(`Server is running on port ${PORT}`);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;TypeScript&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// app.ts
import express from &quot;express&quot;;
import basicAuth from &quot;express-basic-auth&quot;;
import swaggerUi from &quot;swagger-ui-express&quot;;
import swaggerDocument from &quot;./swagger.json&quot;;

const app = express();

// Secure Swagger page with express-basic-auth
const users = { admin: &quot;password123&quot; };
app.use(
  &quot;/api-docs&quot;,
  basicAuth({ users, challenge: true }),
  swaggerUi.serve,
  swaggerUi.setup(swaggerDocument)
);

// Other routes and middleware of the application
// ...

const PORT = process.env.PORT || 3000;
app.listen(PORT, () =&amp;gt; {
  console.log(`Server is running on port ${PORT}`);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&lt;code&gt;challenge: true&lt;/code&gt; You need to pass this parameter to express-basic-auth to display the login prompt.&lt;/h4&gt;
&lt;p&gt;Usersname is &lt;code&gt;admin&lt;/code&gt;&lt;br /&gt;
password is &lt;code&gt;password123&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;3. Secure Swagger Document Page in NestJS Project&lt;/h2&gt;
&lt;p&gt;For NestJS projects, we can use express-basic-auth in the main.ts file of the application.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// main.ts
import { NestFactory } from &quot;@nestjs/core&quot;;
import { SwaggerModule, DocumentBuilder } from &quot;@nestjs/swagger&quot;;
import * as basicAuth from &quot;express-basic-auth&quot;;
import { AppModule } from &quot;./app.module&quot;;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Secure Swagger page with express-basic-auth
  const users = { admin: &quot;password123&quot; };
  app.use(&quot;/api-docs&quot;, basicAuth({ users, challenge: true }));

  const options = new DocumentBuilder()
    .setTitle(&quot;Your API&quot;)
    .setDescription(&quot;API documentation&quot;)
    .setVersion(&quot;1.0&quot;)
    .build();
  const document = SwaggerModule.createDocument(app, options);
  SwaggerModule.setup(&quot;api-docs&quot;, app, document);

  const PORT = process.env.PORT || 3000;
  await app.listen(PORT);
}
bootstrap();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;That&apos;s how you can secure the Swagger document page in JavaScript and TypeScript projects using the express-basic-auth library. With this article, you can apply a similar approach in your projects to ensure that your API documentation is securely protected.&lt;/p&gt;
</content:encoded><author>Pham Quyet Thang</author></item><item><title>Guide to Installing Node.js via NVM on Windows, Linux, and Mac</title><link>https://codeduthu.com/posts/install-nodejs-by-nvm</link><guid isPermaLink="true">https://codeduthu.com/posts/install-nodejs-by-nvm</guid><description>In this article, we&apos;ll learn how to write automated tests for a login page using Playwright - playwright test login page</description><pubDate>Sat, 13 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Node.js is an open-source platform used to build web applications, servers, and real-time apps. It is written in JavaScript, the programming language primarily used in web applications.&lt;/p&gt;
&lt;p&gt;NVM stands for Node.js Version Manager, a tool that helps you manage multiple Node.js versions on the same system. This is useful when you need different Node.js versions for different projects.&lt;/p&gt;
&lt;p&gt;In this article, we will walk through installing Node.js via NVM on every environment: Windows, Linux, and Mac.&lt;/p&gt;
&lt;h2&gt;Install NVM on Windows&lt;/h2&gt;
&lt;p&gt;You can install &lt;code&gt;nvm&lt;/code&gt; on Windows through &lt;code&gt;choco&lt;/code&gt; (learn about &lt;a href=&quot;/blog/chocolatey-windows-package&quot;&gt;choco&lt;/a&gt; if you have not used it before). Open an elevated PowerShell window, then run:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Install Chocolatey
choco install nvm

# Restart PowerShell
Restart-Powershell
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After restarting PowerShell, verify that NVM installed successfully with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nvm --version
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the command returns a version number, you are all set.&lt;/p&gt;
&lt;h2&gt;Install NVM on Linux&lt;/h2&gt;
&lt;p&gt;To install NVM on Linux, open a terminal and run:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Install curl if it is missing
sudo apt install curl

# Install NVM via curl
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After installation, check that NVM is available:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nvm --version
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the command returns a version number, the installation worked.&lt;/p&gt;
&lt;h2&gt;Install NVM on Mac&lt;/h2&gt;
&lt;p&gt;To install NVM on macOS, open a terminal and run:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Install Homebrew if you do not have it
/bin/bash -c &quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)&quot;

# Install NVM
brew install nvm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After installation, verify NVM with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nvm --version
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you see a version number, the setup is complete.&lt;/p&gt;
&lt;h2&gt;Install Node.js via NVM&lt;/h2&gt;
&lt;p&gt;Install Node.js through NVM with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nvm install [version]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example, to install Node.js 16.13.0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nvm install 16.13.0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After installation, activate that version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nvm use [version]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example, to switch to Node.js 16.13.0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nvm use 16.13.0
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;NVM is a handy tool that lets you manage multiple Node.js versions on the same system. With it, you can install, switch, and manage any version you need.&lt;/p&gt;
&lt;h3&gt;Additional NVM commands&lt;/h3&gt;
&lt;p&gt;Beyond the basic commands above, NVM offers extra commands that make version management easier. Common ones include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nvm list&lt;/code&gt; to show every Node.js version currently installed.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nvm ls-remote&lt;/code&gt; to list every Node.js version available for installation.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nvm uninstall [version]&lt;/code&gt; to remove a Node.js version.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nvm alias [alias] [version]&lt;/code&gt; to create an alias for a Node.js version.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can learn more on the official NVM repository (https://github.com/nvm-sh/nvm).&lt;/p&gt;
</content:encoded><author>Pham Quyet Thang</author></item><item><title>How to modify library in node module and save it forever</title><link>https://codeduthu.com/posts/modify-library-in-node-module</link><guid isPermaLink="true">https://codeduthu.com/posts/modify-library-in-node-module</guid><description>Ways to Fix Errors in node_modules and Preserve Edits (Using patch-package, ...)</description><pubDate>Thu, 18 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ways to Fix Errors in node_modules and Preserve Edits (Using patch-package, ...)&lt;/p&gt;
&lt;h2&gt;1. When Fixing a Library from npm:&lt;/h2&gt;
&lt;p&gt;For JavaScript enthusiasts, installing third-party libraries using the command &lt;code&gt;npm install &amp;lt;package name&amp;gt;&lt;/code&gt; (or yarn) is a familiar routine.&lt;/p&gt;
&lt;p&gt;After installation, these libraries reside in the node_modules directory, and we can easily use them.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./35468773-2fcb-4363-8ac0-52a6a00f2f07.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;What&apos;s inside the node_module is usually not something we need to know in detail. The node_module can sometimes be an untouchable area.&lt;/p&gt;
&lt;p&gt;Deleting the node_module and reinstalling is a spiritual solution many have used in desperation to fix bugs.&lt;/p&gt;
&lt;p&gt;Issues arise when we encounter a problem with a library but don&apos;t want to find an alternative.&lt;/p&gt;
&lt;p&gt;&amp;lt;!-- truncate --&amp;gt;&lt;/p&gt;
&lt;h3&gt;So, how can we fix libraries ourselves without losing changes if we delete the node_module?&lt;/h3&gt;
&lt;p&gt;Here are some approaches:&lt;/p&gt;
&lt;h2&gt;2. Ways to Fix Libraries in node_modules&lt;/h2&gt;
&lt;h3&gt;Approach 1: Fork the Package&apos;s Repo&lt;/h3&gt;
&lt;p&gt;You can go to the source code of the package, fork it to your own Git repository, make changes, and then edit it.&lt;/p&gt;
&lt;p&gt;Afterward, declare it in your package.json like this:
For example:
&lt;img src=&quot;./072ae723-f94b-4da3-9802-17bd928bfb57.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Replace the package version with the path to your repository in the format &lt;code&gt;git+{repo}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You may encounter some issues if you try to modify mega-packages like those from Facebook. Some packages are subdirectories of others.&lt;/p&gt;
&lt;p&gt;You can go to https://gitpkg.vercel.app/, paste the link directly to the directory containing that package. The website will render a link and yarn (npm) command for you.&lt;/p&gt;
&lt;p&gt;(That&apos;s the theory, but whether it runs or not... To be sure, you can try approach 2.)&lt;/p&gt;
&lt;h3&gt;Approach 2: Use patch-package&lt;/h3&gt;
&lt;p&gt;This approach is more direct than the first one.&lt;/p&gt;
&lt;p&gt;Boldly find the code in your node_module that you want to edit and bravely make the changes.&lt;/p&gt;
&lt;p&gt;Then run the command:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;npx patch-package &amp;lt;package name&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;patch-package will create a patches folder, declaring your changes.&lt;/p&gt;
&lt;p&gt;You can push this folder to Git and run the &lt;code&gt;npx patch-package&lt;/code&gt; command to reapply your changes.&lt;/p&gt;
&lt;p&gt;To avoid one step each time you reinstall the project, you can add the line &lt;code&gt;&quot;postinstall&quot;: &quot;npx patch-package&quot;&lt;/code&gt; to the scripts like this to let node_module automatically render your changes every time you reinstall.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./ef048d12-b117-4597-8e6e-3de033978daa.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;3. Demo:&lt;/h2&gt;
&lt;p&gt;I have a small demo.&lt;/p&gt;
&lt;p&gt;It involves changing the default logo of the metro in REACT-NATIVE.&lt;/p&gt;
&lt;p&gt;After some investigation, I found out it was written in a file named TerminalReporter.js in /node_modules/metro/src/lib.&lt;/p&gt;
&lt;p&gt;I thought there would be some complicated algorithms to print it out, like the C++ days at school, but no, it&apos;s just an array containing each line of #### :)))))&lt;/p&gt;
&lt;p&gt;So, I just changed it.&lt;/p&gt;
&lt;p&gt;From:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./6dffe6ba-b46f-43a1-a235-d30d12bf7cfa.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;To:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./adef09a3-5890-477a-92af-7c5c4dbc7118.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;(I did it during the deadline days, too busy, so I decided to spend a day messing around to relieve stress after finishing.)&lt;/p&gt;
</content:encoded><author>Pham Quyet Thang</author></item><item><title>20 SQL Interview Questions – Senior Level Part 1 (Questions 1 through 5)</title><link>https://codeduthu.com/posts/100-interview-question-sql-senior-01</link><guid isPermaLink="true">https://codeduthu.com/posts/100-interview-question-sql-senior-01</guid><description>100 SQL interview questions – Senior level, part 1 (questions 1 through 5) for advanced MySQL use cases.</description><pubDate>Tue, 23 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. What are window functions in SQL and how are they used?&lt;/h2&gt;
&lt;p&gt;Window functions operate over a “window” of rows related to the current row, typically defined with an &lt;code&gt;OVER&lt;/code&gt; clause. They allow you to perform calculations such as running totals, rankings, and moving averages without collapsing rows the way aggregate queries do.&lt;/p&gt;
&lt;h3&gt;Basic syntax&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;SELECT
  column1,
  column2,
  window_function(column3)
    OVER (PARTITION BY partition_column ORDER BY order_column)
FROM table_name;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;column1&lt;/code&gt;, &lt;code&gt;column2&lt;/code&gt;: ordinary columns returned in the result set.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;window_function(column3)&lt;/code&gt;: the function applied over the window.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PARTITION BY&lt;/code&gt;: splits the dataset into independent partitions (optional).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ORDER BY&lt;/code&gt;: defines ordering inside each partition (optional).&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Running sum of salary per department
SELECT
  employee_id,
  department_id,
  salary,
  SUM(salary) OVER (
    PARTITION BY department_id
    ORDER BY employee_id
  ) AS cumulative_salary
FROM employees;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Popular window functions include &lt;code&gt;ROW_NUMBER()&lt;/code&gt;, &lt;code&gt;RANK()&lt;/code&gt;, &lt;code&gt;DENSE_RANK()&lt;/code&gt;, &lt;code&gt;SUM()&lt;/code&gt;, &lt;code&gt;AVG()&lt;/code&gt;, &lt;code&gt;MIN()&lt;/code&gt;, and &lt;code&gt;MAX()&lt;/code&gt;. They are invaluable whenever you need to compare each row against its peers without losing detail.&lt;/p&gt;
&lt;h2&gt;2. Explain database sharding&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Database sharding&lt;/strong&gt; splits a large dataset into smaller, independent chunks called &lt;em&gt;shards&lt;/em&gt;. Each shard holds a subset of the data—often determined by a key range or hashing strategy—and can be hosted separately. Sharding improves scalability and performance by distributing load across multiple nodes.&lt;/p&gt;
&lt;h3&gt;Key traits&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Data partitioning&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tables are divided into shards, each storing a specific slice of the data (for example, by customer region or primary-key range).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Workload distribution&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each shard handles reads and writes for its own data range, and some deployments dedicate shards to read or write workloads.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Instead of scaling a single monolithic database, you add more shards to handle growth.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Queries touch less data per shard, so they complete faster when routed intelligently.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Distributed management&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Operating multiple shards requires coordination, metadata tracking, and careful failover planning.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Challenges and considerations&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Data synchronization&lt;/strong&gt;: ensure consistency across shards when cross-shard operations occur.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shard key selection&lt;/strong&gt;: choose a partitioning strategy that avoids hotspots (one shard receiving disproportionate traffic).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Metadata management&lt;/strong&gt;: keep reliable metadata about shard locations, ranges, and status.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Sharding is complex and best reserved for systems that truly need horizontal scaling.&lt;/p&gt;
&lt;h2&gt;3. How do you design an effective database?&lt;/h2&gt;
&lt;p&gt;Designing a solid database schema demands a deep understanding of application requirements and data usage patterns. Core steps include:&lt;/p&gt;
&lt;h4&gt;1. Gather application requirements&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Understand entities, workflows, and how data is accessed to capture the right relationships.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2. Normalize data&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Apply normalization rules to reduce redundancy and keep data consistent.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;3. Define primary and foreign keys&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Assign primary keys for uniqueness and foreign keys to model relationships.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;4. Choose appropriate data types&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Pick data types that match the value range and precision you need.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;5. Classify data&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Organize data into tables based on behavior and usage to keep schemas coherent.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;6. Design for performance&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Anticipate frequent queries and add supporting indexes or structures ahead of time.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;7. Consider partitioning and sharding (when needed)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Use partitioning or sharding to keep very large tables performant and scalable.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;8. Plan data synchronization&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Define how data stays consistent across tables, services, or replicas.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;9. Add constraints&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Enforce integrity with constraints such as foreign keys, unique indexes, and checks.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;10. Test and optimize&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Benchmark and profile the schema under realistic workloads to uncover bottlenecks.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;11. Maintain and iterate&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Establish maintenance routines to evolve the schema as requirements change.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Effective design is iterative—keep measuring, refining, and validating against real-world use.&lt;/p&gt;
&lt;h2&gt;4. Differentiate OLAP and OLTP databases&lt;/h2&gt;
&lt;p&gt;OLAP (Online Analytical Processing) and OLTP (Online Transaction Processing) systems target different workloads.&lt;/p&gt;
&lt;h3&gt;OLAP&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: supports complex analysis, multidimensional reporting, and aggregated insights.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Query style&lt;/strong&gt;: heavy, computation-intensive queries over large datasets.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data model&lt;/strong&gt;: multidimensional structures with historical data and precomputed metrics.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Users&lt;/strong&gt;: managers, analysts, and decision-makers who need big-picture visibility.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;OLTP&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: handles day-to-day business transactions (insert, update, delete).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Query style&lt;/strong&gt;: short, simple, highly concurrent operations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data model&lt;/strong&gt;: row-oriented schemas optimized for strict consistency and fast commits; typically stores only current transactional data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Users&lt;/strong&gt;: operational staff and applications running core business processes.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;OLAP focuses on analytics; OLTP focuses on transactional workloads.&lt;/li&gt;
&lt;li&gt;OLAP queries are complex and scan lots of data; OLTP queries are simple and frequent.&lt;/li&gt;
&lt;li&gt;OLAP uses multidimensional storage; OLTP uses normalized row-oriented tables.&lt;/li&gt;
&lt;li&gt;OLAP serves leadership insights; OLTP powers daily operations.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5. How do you optimize a query execution plan?&lt;/h2&gt;
&lt;p&gt;Improving a query plan centers on helping the optimizer make better choices and reducing the data it must process. Techniques include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Use indexes wisely&lt;/strong&gt;: index columns involved in &lt;code&gt;WHERE&lt;/code&gt;, &lt;code&gt;JOIN&lt;/code&gt;, and &lt;code&gt;ORDER BY&lt;/code&gt; clauses to avoid full-table scans.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keep statistics current&lt;/strong&gt;: up-to-date table and index statistics let the optimizer estimate cardinality accurately.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avoid &lt;code&gt;SELECT *&lt;/code&gt;&lt;/strong&gt;: return only the columns you need to cut down on I/O and network transfer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Choose joins carefully&lt;/strong&gt;: pick the right join type (INNER, LEFT, etc.) to limit intermediate row counts.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Order filters strategically&lt;/strong&gt;: put the most selective predicates first when possible to prune rows early.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Limit result size&lt;/strong&gt;: use &lt;code&gt;LIMIT&lt;/code&gt; (or database-specific equivalents) when you only need a subset.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Partition large tables&lt;/strong&gt;: partitioning reduces the data scanned for queries that target specific ranges.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skip functions in &lt;code&gt;WHERE&lt;/code&gt;&lt;/strong&gt;: wrapping indexed columns in functions can disable index usage; rewrite predicates when you can.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Refresh database statistics&lt;/strong&gt;: periodically regenerate statistics so the optimizer reflects real data distribution.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Leverage tuning tools&lt;/strong&gt;: use your database’s explain/analyze, profiling, or advisor tools to spot bottlenecks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inspect execution plans&lt;/strong&gt;: review generated plans to find unnecessary scans, sorts, or joins and adjust queries or schema accordingly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consider denormalization&lt;/strong&gt;: for read-heavy workloads, denormalizing select tables can reduce joins and improve speed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Always test and measure—optimizations depend on schema design, workload patterns, and the database engine in use.&lt;/p&gt;
</content:encoded><author>Pham Quyet Thang</author></item><item><title>20 SQL Interview Questions – Intern Level Part 4 (Questions 16 through 20)</title><link>https://codeduthu.com/posts/100-interview-question-sql-intern-04</link><guid isPermaLink="true">https://codeduthu.com/posts/100-interview-question-sql-intern-04</guid><description>100 SQL interview questions – Intern level, part 4 (questions 16 through 20) for MySQL beginners.</description><pubDate>Tue, 23 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;16. Describe the difference between CHAR and VARCHAR data types&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;CHAR&lt;/code&gt; and &lt;code&gt;VARCHAR&lt;/code&gt; both store character strings but manage storage differently.&lt;/p&gt;
&lt;h3&gt;CHAR (Fixed-length)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Storage&lt;/strong&gt;: &lt;code&gt;CHAR(n)&lt;/code&gt; uses a fixed length. Every value occupies &lt;code&gt;n&lt;/code&gt; characters, padding with spaces if necessary.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Example&lt;/strong&gt;: With &lt;code&gt;CHAR(5)&lt;/code&gt;, storing &lt;code&gt;ABC&lt;/code&gt; takes all five slots (&lt;code&gt;ABC  &lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use cases&lt;/strong&gt;: Ideal when data length is predictable and consistent.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;VARCHAR (Variable-length)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Storage&lt;/strong&gt;: &lt;code&gt;VARCHAR(n)&lt;/code&gt; uses only as much space as the actual string plus some overhead; no extra padding.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Example&lt;/strong&gt;: With &lt;code&gt;VARCHAR(5)&lt;/code&gt;, storing &lt;code&gt;ABC&lt;/code&gt; uses only three characters.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use cases&lt;/strong&gt;: Preferred when data length varies and storage efficiency matters.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Choosing between CHAR and VARCHAR&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;CHAR&lt;/code&gt; for fixed-length data that benefits from uniform storage.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;VARCHAR&lt;/code&gt; for variable-length data to conserve space.&lt;/li&gt;
&lt;li&gt;In most cases, &lt;code&gt;VARCHAR&lt;/code&gt; is favored due to better storage utilization.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;17. What is an INDEX and why is it important?&lt;/h2&gt;
&lt;p&gt;An &lt;strong&gt;INDEX&lt;/strong&gt; is a specialized data structure that speeds up data retrieval from a table. It helps the database locate rows faster, lowering query complexity and improving performance.&lt;/p&gt;
&lt;h3&gt;Why indexes matter&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Faster lookups&lt;/strong&gt;: An index creates an ordered structure so the database can quickly find rows based on indexed column values.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lower query cost&lt;/strong&gt;: Searches or sorts on indexed columns avoid scanning the entire table.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Better sorting and joins&lt;/strong&gt;: Indexes make ordering and join operations more efficient.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optimized WHERE clauses&lt;/strong&gt;: Indexed columns significantly speed up filtering conditions.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Usage tips&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Create indexes with &lt;code&gt;CREATE INDEX&lt;/code&gt; on columns frequently used in WHERE clauses, joins, or ORDER BY.&lt;/li&gt;
&lt;li&gt;Avoid over-indexing; too many indexes increase storage requirements and slow down INSERT/UPDATE/DELETE operations.&lt;/li&gt;
&lt;li&gt;Choose indexes strategically to balance read performance with write overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;18. How do you insert a new record into a table?&lt;/h2&gt;
&lt;p&gt;Use the &lt;code&gt;INSERT INTO&lt;/code&gt; statement to add a new row:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;table_name&lt;/code&gt;: the table receiving the new row.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;column1, column2, ...&lt;/code&gt;: columns to populate.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;value1, value2, ...&lt;/code&gt;: the values to insert.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;INSERT INTO employees (employee_id, employee_name, department_id, salary)
VALUES (101, &apos;John Doe&apos;, 3, 50000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This inserts a full record into &lt;code&gt;employees&lt;/code&gt;. If a column is auto-incremented, omit it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;INSERT INTO employees (employee_name, department_id, salary)
VALUES (&apos;Jane Smith&apos;, 2, 60000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the database generates &lt;code&gt;employee_id&lt;/code&gt; automatically.&lt;/p&gt;
&lt;h2&gt;19. Explain the purpose of the LIMIT clause&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;LIMIT&lt;/code&gt; restricts how many rows a query returns. It is useful when you only need a subset of results, which reduces memory usage and speeds up responses.&lt;/p&gt;
&lt;h3&gt;Syntax&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;SELECT column1, column2, ...
FROM table_name
WHERE condition
LIMIT row_count;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SELECT&lt;/code&gt;: columns to return.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FROM&lt;/code&gt;: source table.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WHERE&lt;/code&gt; (optional): filter condition.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LIMIT&lt;/code&gt;: maximum number of rows to retrieve.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Fetch the top 5 highest-paid employees
SELECT employee_id, employee_name, salary
FROM employees
ORDER BY salary DESC
LIMIT 5;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This query returns only five rows, ordered by salary from highest to lowest.&lt;/p&gt;
&lt;h2&gt;20. How do you update data in a table?&lt;/h2&gt;
&lt;p&gt;Use the &lt;code&gt;UPDATE&lt;/code&gt; statement to modify existing rows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;table_name&lt;/code&gt;: table to update.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SET&lt;/code&gt;: columns and new values.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WHERE&lt;/code&gt;: condition that selects which rows to change.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Update the salary of employee 101
UPDATE employees
SET salary = 55000
WHERE employee_id = 101;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Always include a &lt;code&gt;WHERE&lt;/code&gt; clause to avoid updating every row accidentally. Ensure new values match the columns’ data types and constraints.&lt;/p&gt;
</content:encoded><author>Pham Quyet Thang</author></item><item><title>20 SQL Interview Questions – Intern Level Part 1 (Questions 1 through 5)</title><link>https://codeduthu.com/posts/100-interview-question-sql-intern-01</link><guid isPermaLink="true">https://codeduthu.com/posts/100-interview-question-sql-intern-01</guid><description>100 SQL interview questions, part 1 – 20 intern-level SQL interview questions (questions 1 through 5) for MySQL newcomers.</description><pubDate>Tue, 23 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. What is SQL and why is it important?&lt;/h2&gt;
&lt;h3&gt;What is SQL?&lt;/h3&gt;
&lt;p&gt;SQL is a database query language used to interact with database management systems.&lt;/p&gt;
&lt;h3&gt;Why does SQL matter?&lt;/h3&gt;
&lt;p&gt;SQL is essential because it lets you query, update, and manage data in relational databases.&lt;/p&gt;
&lt;h3&gt;What is SQL used for?&lt;/h3&gt;
&lt;p&gt;SQL is used to query data, update data, manage databases, and perform other data-related operations.&lt;/p&gt;
&lt;h3&gt;Why is SQL important in programming?&lt;/h3&gt;
&lt;p&gt;SQL provides a standardized, powerful way to manipulate data in relational database systems, helping keep data consistent and secure.&lt;/p&gt;
&lt;h2&gt;2. Differentiate SQL and MySQL&lt;/h2&gt;
&lt;p&gt;SQL (Structured Query Language) is a standard query language used to interact with database management systems (DBMS). MySQL, meanwhile, is an open-source relational DBMS that relies on SQL as its query language.&lt;/p&gt;
&lt;p&gt;Key differences between SQL and MySQL:&lt;/p&gt;
&lt;h3&gt;SQL:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A standardized language for database queries.&lt;/li&gt;
&lt;li&gt;Not a specific database engine; it can be used with many DBMS implementations.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;MySQL:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;An open-source relational DBMS.&lt;/li&gt;
&lt;li&gt;Uses SQL as its query language for working with data.&lt;/li&gt;
&lt;li&gt;Developed and maintained by Oracle Corporation.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;In short, SQL is the general-purpose language for interacting with databases, while MySQL is a specific database system that uses SQL.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;3. Explain the basic structure of an SQL query&lt;/h2&gt;
&lt;p&gt;A basic SQL query usually follows these clauses:&lt;/p&gt;
&lt;h3&gt;SELECT:&lt;/h3&gt;
&lt;p&gt;Choose the columns you want to retrieve. Use &lt;code&gt;*&lt;/code&gt; to select every column.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT column1, column2 FROM table_name;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;FROM:&lt;/h3&gt;
&lt;p&gt;Specify the table that holds the data.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT column1, column2 FROM employees;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;WHERE:&lt;/h3&gt;
&lt;p&gt;Filter the data; only rows matching the condition are returned.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT column1, column2 FROM employees WHERE department = &apos;IT&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;GROUP BY:&lt;/h3&gt;
&lt;p&gt;Group rows based on one or more columns.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT department, COUNT(*) FROM employees GROUP BY department;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;HAVING:&lt;/h3&gt;
&lt;p&gt;Filter groups after &lt;code&gt;GROUP BY&lt;/code&gt;; only groups that satisfy the condition remain.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT department, COUNT(*) FROM employees GROUP BY department HAVING COUNT(*) &amp;gt; 5;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ORDER BY:&lt;/h3&gt;
&lt;p&gt;Sort the result set by one or more columns.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT column1, column2 FROM employees ORDER BY column1 ASC;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;This is just a basic structure; you can extend or adjust the query depending on your needs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;4. List the types of SQL commands&lt;/h2&gt;
&lt;h3&gt;DQL (Data Query Language):&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SELECT&lt;/code&gt;: Query data from the database.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;DML (Data Manipulation Language):&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;INSERT&lt;/code&gt;: Add new data into a table.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UPDATE&lt;/code&gt;: Modify existing data in a table.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DELETE&lt;/code&gt;: Remove data from a table.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;DDL (Data Definition Language):&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CREATE&lt;/code&gt;: Create databases, tables, indexes, or other objects.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ALTER&lt;/code&gt;: Modify database, table, or other object structures.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DROP&lt;/code&gt;: Delete databases, tables, indexes, or other objects.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;DCL (Data Control Language):&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GRANT&lt;/code&gt;: Give permissions to access database objects.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;REVOKE&lt;/code&gt;: Remove previously granted permissions.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;TCL (Transaction Control Language):&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;COMMIT&lt;/code&gt;: Persist changes made in a transaction.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ROLLBACK&lt;/code&gt;: Undo changes made in a transaction.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SAVEPOINT&lt;/code&gt;: Mark a transaction point you can roll back to later.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Each command category serves a specific purpose: DQL for querying, DML for modifying data, DDL for managing structure, DCL for access control, and TCL for transaction control.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;5. Define the SELECT statement and how to use it&lt;/h2&gt;
&lt;h3&gt;Definition&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;SELECT&lt;/code&gt; statement retrieves data from one or more tables in a database. It is a DQL (Data Query Language) command that lets you specify which columns to fetch and the conditions for returning data.&lt;/p&gt;
&lt;h3&gt;Usage&lt;/h3&gt;
&lt;p&gt;Basic syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT column1, column2, ...
FROM table_name
WHERE condition;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;SELECT&lt;/code&gt;: lists the columns to retrieve.&lt;br /&gt;
&lt;code&gt;FROM&lt;/code&gt;: specifies the table containing the data.&lt;br /&gt;
&lt;code&gt;WHERE&lt;/code&gt; (optional): filters the rows returned.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Retrieve every column from the &quot;employees&quot; table
SELECT * FROM employees;

-- Retrieve specific columns from the &quot;products&quot; table
SELECT product_name, price FROM products WHERE category = &apos;Electronics&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;SELECT&lt;/code&gt; statement is fundamental for exploring and analyzing SQL data, and you can customize it for a wide range of query scenarios.&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded><author>Pham Quyet Thang</author></item><item><title>20 SQL Interview Questions – Intern Level Part 3 (Questions 11 through 15)</title><link>https://codeduthu.com/posts/100-interview-question-sql-intern-03</link><guid isPermaLink="true">https://codeduthu.com/posts/100-interview-question-sql-intern-03</guid><description>100 SQL interview questions – Intern level, part 3 (questions 11 through 15) for MySQL beginners.</description><pubDate>Tue, 23 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;11. Differentiate INNER JOIN and OUTER JOIN&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;INNER JOIN&lt;/code&gt; and &lt;code&gt;OUTER JOIN&lt;/code&gt; are distinct join types with different behaviors:&lt;/p&gt;
&lt;h3&gt;INNER JOIN&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Key trait&lt;/strong&gt;: Returns rows only when the join condition matches in both tables.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Result&lt;/strong&gt;: Contains rows that have matching values in both tables.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Syntax&lt;/strong&gt;: &lt;code&gt;SELECT ... FROM table1 INNER JOIN table2 ON condition;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;OUTER JOIN (LEFT, RIGHT, FULL)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Key trait&lt;/strong&gt;: Returns rows from at least one table even if the join condition fails.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Result types&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;LEFT JOIN&lt;/code&gt; (or &lt;code&gt;LEFT OUTER JOIN&lt;/code&gt;): All rows from the left table plus matching rows from the right table.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RIGHT JOIN&lt;/code&gt; (or &lt;code&gt;RIGHT OUTER JOIN&lt;/code&gt;): All rows from the right table plus matching rows from the left table.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FULL JOIN&lt;/code&gt; (or &lt;code&gt;FULL OUTER JOIN&lt;/code&gt;): Every row from both tables, whether or not there is a match.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Syntax&lt;/strong&gt;: &lt;code&gt;SELECT ... FROM table1 LEFT|RIGHT|FULL JOIN table2 ON condition;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- INNER JOIN
SELECT e.employee_id, e.employee_name, d.department_name
FROM employees e
INNER JOIN departments d ON e.department_id = d.department_id;

-- LEFT JOIN
SELECT c.customer_id, c.customer_name, o.order_id
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The INNER JOIN returns rows only where both tables have matching departments. The LEFT JOIN returns all customers, plus their orders when they exist.&lt;/p&gt;
&lt;h2&gt;12. How is DISTINCT used?&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;DISTINCT&lt;/code&gt; removes duplicate rows from query results so only unique values appear in the selected columns.&lt;/p&gt;
&lt;h4&gt;Syntax&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;SELECT DISTINCT column1, column2, ...
FROM table_name
WHERE condition;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SELECT DISTINCT&lt;/code&gt;: chooses the columns to return unique values for.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FROM&lt;/code&gt;: identifies the source table.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WHERE&lt;/code&gt; (optional): filters rows before deduplication.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Retrieve unique departments
SELECT DISTINCT department
FROM employees;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This query lists every department exactly once, eliminating duplicates.&lt;/p&gt;
&lt;h2&gt;13. Explain database normalization&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Normalization&lt;/strong&gt; is the process of structuring a database to reduce data redundancy and improve data integrity. It helps maintain consistent, efficient data storage.&lt;/p&gt;
&lt;p&gt;Common normal forms include First Normal Form (1NF), Second Normal Form (2NF), Third Normal Form (3NF), Boyce-Codd Normal Form (BCNF), Fourth Normal Form (4NF), and Fifth Normal Form (5NF).&lt;/p&gt;
&lt;h3&gt;Key normal forms&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;1NF&lt;/strong&gt;: Each cell holds a single value, and column values share the same data type.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2NF&lt;/strong&gt;: The table is in 1NF, and every non-key column depends fully on the entire primary key.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;3NF&lt;/strong&gt;: The table is in 2NF, and non-key columns do not depend on other non-key columns (no transitive dependency).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BCNF&lt;/strong&gt;: A stronger version of 3NF ensuring every determinant is a candidate key.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Benefits&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Less redundancy&lt;/strong&gt;: Store each piece of data once, minimizing duplicates and saving space.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consistency&lt;/strong&gt;: Well-structured tables reduce the risk of inconsistent data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Better performance&lt;/strong&gt;: Properly normalized schemas can improve query efficiency.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Over-normalizing may introduce too many joins and hurt performance, so balance normalization with practical requirements.&lt;/p&gt;
&lt;h2&gt;14. What is a PRIMARY KEY?&lt;/h2&gt;
&lt;p&gt;In a database table, a &lt;strong&gt;PRIMARY KEY&lt;/strong&gt; is a column or set of columns whose values uniquely identify each row. It enforces uniqueness and ensures every record is distinguishable.&lt;/p&gt;
&lt;h3&gt;Characteristics&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unique&lt;/strong&gt;: No two rows share the same primary key value.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Not null&lt;/strong&gt;: Primary key columns cannot contain NULL.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Identifier&lt;/strong&gt;: Serves as the definitive way to reference each record.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Syntax&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE table_name (
    column1 datatype PRIMARY KEY,
    column2 datatype,
    ...
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For composite keys:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE table_name (
    column1 datatype,
    column2 datatype,
    ...
    PRIMARY KEY (column1, column2)
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    employee_name VARCHAR(50),
    department_id INT
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;employee_id&lt;/code&gt; uniquely identifies each row in &lt;code&gt;employees&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;15. What is a FOREIGN KEY and how is it used?&lt;/h2&gt;
&lt;p&gt;A &lt;strong&gt;FOREIGN KEY&lt;/strong&gt; is a column (or set of columns) in one table that references a primary key or unique key in another table. It defines relationships between tables and enforces referential integrity.&lt;/p&gt;
&lt;h3&gt;Key roles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Establish relationships&lt;/strong&gt;: Links rows in the child table to rows in the parent table.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Preserve integrity&lt;/strong&gt;: Prevents orphaned records by requiring referenced values to exist in the parent table.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Syntax&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE child_table (
    column1 datatype,
    foreign_key_column datatype,
    FOREIGN KEY (foreign_key_column) REFERENCES parent_table(parent_key_column)
);
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;foreign_key_column&lt;/code&gt;: column in the child table that stores the reference.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;parent_table&lt;/code&gt;: table that owns the referenced primary key.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;parent_key_column&lt;/code&gt;: primary key column in the parent table.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE departments (
    department_id INT PRIMARY KEY,
    department_name VARCHAR(50)
);

CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    employee_name VARCHAR(50),
    department_id INT,
    FOREIGN KEY (department_id) REFERENCES departments(department_id)
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, &lt;code&gt;department_id&lt;/code&gt; in &lt;code&gt;employees&lt;/code&gt; references &lt;code&gt;department_id&lt;/code&gt; in &lt;code&gt;departments&lt;/code&gt;, linking each employee to a department and enforcing valid relationships.&lt;/p&gt;
</content:encoded><author>Pham Quyet Thang</author></item><item><title>20 SQL Interview Questions – Intern Level Part 2 (Questions 6 through 10)</title><link>https://codeduthu.com/posts/100-interview-question-sql-intern-02</link><guid isPermaLink="true">https://codeduthu.com/posts/100-interview-question-sql-intern-02</guid><description>100 SQL interview questions – Intern level, part 2 (questions 6 through 10) for MySQL beginners.</description><pubDate>Tue, 23 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;6. How do you retrieve every column from a table named &quot;employees&quot;?&lt;/h2&gt;
&lt;p&gt;Use the &lt;code&gt;SELECT&lt;/code&gt; statement with the wildcard &lt;code&gt;*&lt;/code&gt; to fetch all columns:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT *
FROM employees;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the asterisk acts as a wildcard, so the query returns every column for each row in the &lt;code&gt;employees&lt;/code&gt; table.&lt;/p&gt;
&lt;h2&gt;7. Explain the WHERE clause in SQL&lt;/h2&gt;
&lt;h3&gt;Definition&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;WHERE&lt;/code&gt; clause filters query results using one or more conditions. It restricts the returned dataset to only the rows that satisfy the specified criteria.&lt;/p&gt;
&lt;h3&gt;Usage&lt;/h3&gt;
&lt;p&gt;Basic syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT column1, column2, ...
FROM table_name
WHERE condition;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SELECT&lt;/code&gt;: specifies the columns to retrieve.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FROM&lt;/code&gt;: identifies the table containing the data.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WHERE&lt;/code&gt;: applies the filtering condition.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Fetch all employees in the IT department
SELECT *
FROM employees
WHERE department = &apos;IT&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This query returns only the rows where the &lt;code&gt;department&lt;/code&gt; column equals &lt;code&gt;IT&lt;/code&gt;. The WHERE clause is essential for narrowing down results to the records that matter.&lt;/p&gt;
&lt;h2&gt;8. What is the purpose of the ORDER BY clause?&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ORDER BY&lt;/code&gt; sorts query results based on the values of one or more columns, either ascending (&lt;code&gt;ASC&lt;/code&gt;) or descending (&lt;code&gt;DESC&lt;/code&gt;).&lt;/p&gt;
&lt;h4&gt;Usage&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;SELECT column1, column2, ...
FROM table_name
ORDER BY column1 [ASC|DESC], column2 [ASC|DESC], ...;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SELECT&lt;/code&gt;: identifies the columns to return.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FROM&lt;/code&gt;: defines the source table.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ORDER BY&lt;/code&gt;: lists the columns used for sorting.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Show all employees, sorted alphabetically by name
SELECT *
FROM employees
ORDER BY employee_name ASC;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The result set is sorted by &lt;code&gt;employee_name&lt;/code&gt; in ascending order (A–Z). Use ORDER BY when you need predictable, readable output.&lt;/p&gt;
&lt;h2&gt;9. Describe the GROUP BY clause and what it does&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;GROUP BY&lt;/code&gt; groups rows that share the same values in specified columns, which allows you to run aggregate functions such as &lt;code&gt;SUM&lt;/code&gt;, &lt;code&gt;AVG&lt;/code&gt;, &lt;code&gt;COUNT&lt;/code&gt;, &lt;code&gt;MAX&lt;/code&gt;, and &lt;code&gt;MIN&lt;/code&gt; on each group.&lt;/p&gt;
&lt;h4&gt;Usage&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;SELECT column1, aggregate_function(column2), ...
FROM table_name
GROUP BY column1, ...;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SELECT&lt;/code&gt;: chooses the columns and aggregates to return.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FROM&lt;/code&gt;: names the table source.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GROUP BY&lt;/code&gt;: lists the columns used for grouping.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Total number of products sold in each category
SELECT category, SUM(quantity_sold) AS total_sold
FROM sales
GROUP BY category;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The query groups sales by &lt;code&gt;category&lt;/code&gt; and calculates the total quantity sold for each category. GROUP BY helps you analyze distributions and summaries across segments of your data.&lt;/p&gt;
&lt;h2&gt;10. What is a JOIN in SQL and how does it work?&lt;/h2&gt;
&lt;h3&gt;Definition&lt;/h3&gt;
&lt;p&gt;A JOIN combines data from two or more tables based on a related column. When your data is split across multiple tables, JOIN pulls matching rows together in a unified result set.&lt;/p&gt;
&lt;h3&gt;Syntax&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;SELECT column1, column2, ...
FROM table1
JOIN table2 ON join_condition;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SELECT&lt;/code&gt;: lists the columns to return from the join.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FROM&lt;/code&gt;: specifies the primary table.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JOIN&lt;/code&gt;: identifies the table to combine with the primary table.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ON&lt;/code&gt;: defines the matching condition between the two tables.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Combine employee data with department names
SELECT employees.employee_id,
       employees.employee_name,
       departments.department_name
FROM employees
JOIN departments ON employees.department_id = departments.department_id;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This query joins &lt;code&gt;employees&lt;/code&gt; and &lt;code&gt;departments&lt;/code&gt; using the shared &lt;code&gt;department_id&lt;/code&gt;. The output includes employee details along with the name of their department.&lt;/p&gt;
&lt;p&gt;Common JOIN types include INNER JOIN, LEFT JOIN, RIGHT JOIN, and FULL JOIN, each suited to different data-combining scenarios.&lt;/p&gt;
</content:encoded><author>Pham Quyet Thang</author></item><item><title>Build a cross platform desktop app with electron and react typescript, tailwind css</title><link>https://codeduthu.com/posts/electron-react-typescript-tailwind-css</link><guid isPermaLink="true">https://codeduthu.com/posts/electron-react-typescript-tailwind-css</guid><description>Build a cross platform desktop app with electron and react typescript, tailwind css</description><pubDate>Tue, 21 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hello everyone, I just released the first version of &lt;a href=&quot;https://github.com/phamquyetthang/offline-dev-tools&quot;&gt;Offline Dev Tools&lt;/a&gt; - A small desktop application built with electron, react typescript, tailwindcss, &lt;a href=&quot;https://ui.shadcn.com/&quot;&gt;shadcn/ui&lt;/a&gt;, and some other tools.&lt;/p&gt;
&lt;p&gt;It provides some useful offline tools such as data generation, data transformation, base64 encoding/decoding, time zone comparison, ...&lt;/p&gt;
&lt;p&gt;The software is inspired by &lt;a href=&quot;https://devtoys.app/&quot;&gt;DevToys&lt;/a&gt; and other libraries like https://transform.tools/, &lt;a href=&quot;https://fakerjs.dev/&quot;&gt;faker-js&lt;/a&gt;. I designed and built it myself in a few weeks.
There are still many features I want to improve and add to the software in the future.&lt;/p&gt;
&lt;p&gt;Regarding the application I built, you can view it or download and use it on Linux, Windows, or macOS.&lt;/p&gt;
&lt;p&gt;https://github.com/phamquyetthang/offline-dev-tools&lt;/p&gt;
&lt;p&gt;&amp;lt;div style=&quot;display:flex; gap: 4px&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/phamquyetthang/offline-dev-tools/releases/latest/download/offline-dev-tools.exe&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/Download-Windows-blue?style=flat-square&amp;amp;logo=windows&quot; alt=&quot;Windows&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://github.com/phamquyetthang/offline-dev-tools/releases/latest/download/offline-dev-tools_amd64.deb&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/Download-Linux-orange?style=flat-square&amp;amp;logo=linux&quot; alt=&quot;Linux&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://github.com/phamquyetthang/offline-dev-tools/releases/latest/download/offline-dev-tools.dmg&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/Download-macOS-lightgrey?style=flat-square&amp;amp;logo=apple&quot; alt=&quot;macOS&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://github.com/phamquyetthang/offline-dev-tools/releases/latest&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/v/release/phamquyetthang/offline-dev-tools?style=flat-square&amp;amp;logo=github&quot; alt=&quot;GitHub Release&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h2&gt;Electron-forge vs electron-vite&lt;/h2&gt;
&lt;p&gt;When starting to build and explore electron, I initialized the project with &lt;a href=&quot;https://electron-vite.org/&quot;&gt;electron-vite&lt;/a&gt; because I was familiar with vite and react recently,
And it really did a great job when I didn&apos;t spend much time to start the project, integrate tailwindcss and shadcn/ui into the project. Everything you need is here: https://electron-vite.org/guide/&lt;/p&gt;
&lt;p&gt;I have completed about 30% of the features in my software using electron-vite, until I encountered some issues when packaging (building for production) or installing additional packages.
The electron-vite community and documentation are not large enough for me to find help with the issues I encountered.&lt;/p&gt;
&lt;p&gt;After evaluating multiple times, I decided to switch to &lt;a href=&quot;https://www.electronforge.io/&quot;&gt;electron-forge&lt;/a&gt; and have been working conveniently with it until now.&lt;/p&gt;
&lt;p&gt;Installing react typescript and tailwindcss into the electron-forge project is not difficult but will take quite a while if you do not have experience (not as easy as electron-vite),
In this article I will help you save a little time and get started
an electron-forge project that works seamlessly with react typescript and tailwindcss.&lt;/p&gt;
&lt;h2&gt;Create new app with Electron Forge&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;npm init electron-app@latest my-new-app -- --template=webpack-typescript
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;my-new-app: Please change this to your project name&lt;/p&gt;
&lt;p&gt;--template=webpack-typescript: indicates you will use webpack, and typescript instead of javascript&lt;/p&gt;
&lt;p&gt;electron-forge supports you to initialize with vite but it seems it is not ready to combine with react so please just work with webpack for now&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After running the above command, a project will be created and you can run it with the &lt;code&gt;npm start&lt;/code&gt; command
Looking through the files, you will see the content in the &lt;code&gt;src/index.html&lt;/code&gt; file being displayed on the interface.&lt;/p&gt;
&lt;p&gt;And the &lt;code&gt;src/renderer.ts&lt;/code&gt; file will be where we write our typescipt code.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./electron1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Install React to the project:&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;npm install --save react react-dom
npm install --save-dev @types/react @types/react-dom

# or with yarn
yarn add react react-dom
yarn add -D @types/react @types/react-dom
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you can create an &lt;code&gt;app.tsx&lt;/code&gt; file in src to be the root file for your react part&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// # src/app.tsx

import &apos;./index.css&apos;; // import css

import * as React from &quot;react&quot;;
import { createRoot } from &quot;react-dom/client&quot;;

const root = createRoot(document.getElementById(&apos;root&apos;) as HTMLElement);
root.render(
  &amp;lt;React.StrictMode&amp;gt;
   &amp;lt;h1&amp;gt;Hello react&amp;lt;/h1&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;
);

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Import to &lt;code&gt;src/renderer.ts&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// # src/renderer.ts
import &apos;./index.css&apos;
import &apos;./app&apos; // &amp;lt;== add this line
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Modify the src/index.html file so that it works with the &lt;code&gt;document.getElementById(&apos;root&apos;)&lt;/code&gt; line in the app.tsx file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- # src/index.html --&amp;gt;
&amp;lt;!doctype html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;UTF-8&quot; /&amp;gt;
    &amp;lt;title&amp;gt;My app name&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;

  &amp;lt;body&amp;gt;
    &amp;lt;div id=&quot;root&quot;&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;!-- &amp;lt;== add this, root element --&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You may get the error &lt;code&gt;Cannot use JSX unless the &apos;--jsx&apos; flag is provided.ts&lt;/code&gt;, please add this line to the tsconfig.json file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    &quot;jsx&quot;: &quot;react-jsx&quot; // &amp;lt;== add this line
    // other existed configs
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rerun the project and you will see the code you just changed displayed&lt;/p&gt;
&lt;p&gt;From this point, you can organize the project structure of a react application and import it into src/app.tsx&lt;/p&gt;
&lt;h2&gt;Install tailwindscss&lt;/h2&gt;
&lt;p&gt;First, install tailwind css dependentces&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install tailwindcss autoprefixer --save-dev

# or with yarn
yarn add -D tailwindcss autoprefixer
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Init file config&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npx tailwindcss init
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A tailwind.config.js file will be created in the project&apos;s root directory&lt;/p&gt;
&lt;p&gt;Open that file and modify this section so tailwind understands where its classnames will be used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/** @type {import(&apos;tailwindcss&apos;).Config} */
module.exports = {
  content: [
    &apos;./src/**/*.{ts,tsx,html}&apos;, // &amp;lt;== Update this
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For webpack and electron to work with tailwind, we also need to install &lt;code&gt;postcss&lt;/code&gt;, &lt;code&gt;postcss-loader&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install postcss postcss-loader

# or with yarn
yarn add postcss postcss-loader
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then create the file &lt;code&gt;postcss.config.js&lt;/code&gt; with the following content:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//postcss.config.js

import tailwindcss from &apos;tailwindcss&apos;
import autoprefixer from &apos;autoprefixer&apos;
export default {
  plugins: [tailwindcss(&apos;./tailwind.config.js&apos;), autoprefixer],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add postcss-loader to webpack.renderer.config.ts&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// webpack.renderer.config.ts

rules.push({
  test: /\.css$/,
  use: [
    { loader: &apos;style-loader&apos; },
    { loader: &apos;css-loader&apos; },
    { loader: &apos;postcss-loader&apos; }, // &amp;lt;== add this
  ],
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add the Tailwind directives to your CSS, src/index.css&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@tailwind base;
@tailwind components;
@tailwind utilities;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now let&apos;s test it by adding a few classnames to the h1 tag&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
const root = createRoot(document.getElementById(&apos;root&apos;) as HTMLElement);
root.render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;h1 className=&quot;font-bold text-2xl underline text-red-700&quot;&amp;gt;Hello react&amp;lt;/h1&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You will see the UI has been applied on the interface.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./electron2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Completed tailwind css integration, you can use components of &lt;em&gt;&lt;a href=&quot;https://ui.shadcn.com/&quot;&gt;shadcn/ui&lt;/a&gt;&lt;/em&gt; if you want.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&quot;https://github.com/phamquyetthang/offline-dev-tools&quot;&gt;my project&lt;/a&gt; to see how I work with &lt;em&gt;&lt;a href=&quot;https://ui.shadcn.com/&quot;&gt;shadcn/ui&lt;/a&gt;&lt;/em&gt; , tailwindcss in the electron project.&lt;/p&gt;
&lt;p&gt;Above I have guided you to create an electron typescript project, integrating react, and tailwind css.&lt;/p&gt;
&lt;p&gt;Please ask questions if there is any part that is difficult to understand!&lt;/p&gt;
&lt;p&gt;Finally, thank you for taking the time to read the article, please support the original article at: https://www.codeduthu.com/en/blog/electron-react-typescript-tailwind-css&lt;/p&gt;
</content:encoded><author>Pham Quyet Thang</author></item></channel></rss>