<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: (James) Kanin Kearpimy</title>
    <description>The latest articles on DEV Community by (James) Kanin Kearpimy (@kaninkearpimy).</description>
    <link>https://dev.to/kaninkearpimy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F551097%2F3fff5b01-e821-4378-87f3-94c71aad7148.jpg</url>
      <title>DEV Community: (James) Kanin Kearpimy</title>
      <link>https://dev.to/kaninkearpimy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kaninkearpimy"/>
    <language>en</language>
    <item>
      <title>3..2..1 Launch!: My journey from zero to Django Contributions</title>
      <dc:creator>(James) Kanin Kearpimy</dc:creator>
      <pubDate>Fri, 15 May 2026 13:49:46 +0000</pubDate>
      <link>https://dev.to/kaninkearpimy/321-launch-my-journey-from-zero-to-django-contributions-573i</link>
      <guid>https://dev.to/kaninkearpimy/321-launch-my-journey-from-zero-to-django-contributions-573i</guid>
      <description>&lt;p&gt;Though &lt;em&gt;contribution&lt;/em&gt; sound big, its process require many tiny step composed up for single PR. I hope my reflection journey of Django contribution via &lt;a href="https://djangonaut.space/" rel="noopener noreferrer"&gt;Djangonaut&lt;/a&gt; program will inspire anyone who want to contribute to open source. &lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When I surfed website before coding-ere. There was always a question; How was these website created? Such question was clarified during my first web-programming. We have to write HTML/CSS and Javascript. Then we plugged it to &lt;strong&gt;server-side application&lt;/strong&gt;. Well, I accidentally came across open-source framework, &lt;strong&gt;Django&lt;/strong&gt;, because of admin feature my client requested 5 years ago.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contribution Challenge
&lt;/h2&gt;

&lt;p&gt;As you may know, using open source and contributing to it are totally different. I thought it include: reading contribution.md, select an issue, fixing thing, open pull request, then boom! merged!!!&lt;/p&gt;

&lt;p&gt;Well, that's 50% true. But less people talks about hidden parts. So many times there are;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feeling nervous to select an issue because &lt;code&gt;good-first-issue&lt;/code&gt; are occupied so quick.&lt;/li&gt;
&lt;li&gt;No idea where to navigate, in particular large codebase software.&lt;/li&gt;
&lt;li&gt;What if reviewer wouldn't like my PR at all?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yeah, those are what happens when I first try to help Open Source project. Especially big project like &lt;strong&gt;Django&lt;/strong&gt;, they are over hundred smart engineers around the world working on this thing. Finding your spot and starting point are surely challenging. That's why Django team has beginner-friendly program fostering new contributor, &lt;a href="https://djangonaut.space/" rel="noopener noreferrer"&gt;Djangonaut&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Launch Your Contribution: Djangonaut Space!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8yscznlvsdgfdrqa02h2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8yscznlvsdgfdrqa02h2.png" alt="Djangonaut" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's 8-weeks near-asynchronize program where you'll be in team, mine is Saturn. (yeah, creative space relates name tho). Each team has different project to contribute. All team has Djangonauts (you and teammate) with your Captain, and Navigator. There is team expert, my team is Django Fellow who asynchornizedly help us along the program.&lt;/p&gt;

&lt;p&gt;It's not only Django Djangonaut contributed but also community-wide libraries in Django/Python ecosystem. (Check &lt;a href="https://djangonaut.space/" rel="noopener noreferrer"&gt;website&lt;/a&gt; for more)&lt;/p&gt;

&lt;h2&gt;
  
  
  My Artifacts from Saturn
&lt;/h2&gt;

&lt;p&gt;Fortunately, my two PRs got merged during program. It's my pleasure to receive very helpful suggestion from Django Core team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coalescing JSON-primitive strings
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0myekdu0humbcimrggti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0myekdu0humbcimrggti.png" alt="Coalescing JSON-primitive strings" width="800" height="231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PR:&lt;/strong&gt; &lt;a href="https://github.com/django/django/pull/20864" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;br&gt;
This is very interesting bug. You can perform &lt;code&gt;coalesce&lt;/code&gt; to receive not-null first value from given columns fetching. However, column's type are vary. Let imagine you coalesce &lt;code&gt;Column A (string)&lt;/code&gt;, &lt;code&gt;Column B (JSON)&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Technically to serve potential types, we need to wrap them with union type. In this case it's &lt;code&gt;NCLOB&lt;/code&gt;, which can hold String and JSON. Basically database would cast type for us resulting in no problem in other database except &lt;strong&gt;Oracle&lt;/strong&gt;. So, we have to handle type casting manually.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hidden sensitive variables for Django admin panel
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frjl8ul39ko9s3mc49vax.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frjl8ul39ko9s3mc49vax.png" alt="Hidden sensitive variables for Django admin panel" width="800" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PR:&lt;/strong&gt; &lt;a href="https://github.com/django/django/pull/20959" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Django show sensitive data in stack trace if &lt;code&gt;Debug=True&lt;/code&gt; is set. It's development-only and strongly recommended to disable during production. Even though even disable &lt;code&gt;Debug&lt;/code&gt; mode, somehow it will throw sensitive information to stack trace, or worse Admin email, for default login/reset password form. This bug damage is only exposed to admin role.&lt;/p&gt;

&lt;p&gt;The solution is straight forward, Django already provide &lt;code&gt;sensitive_variables()&lt;/code&gt; to hide sensitive information. I have to attach it to &lt;code&gt;authenticate()&lt;/code&gt; function for login / password reset.&lt;/p&gt;

&lt;h3&gt;
  
  
  How is it after two merged PRs?
&lt;/h3&gt;

&lt;p&gt;Well, it's mixed feeling. My works got merged into big project. On the other hand, it clarified mystery under the iceberg.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fur23uwa766b2ljr1lp7t.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fur23uwa766b2ljr1lp7t.jpg" alt="Iceberg to clarify open source contribution" width="492" height="643"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What I always see is new PRs open, new feature updated, new version to pull. But Those are just surface of iceberg. There are below the water where;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;People get stuck for a week without any progress because of codebase size.&lt;/li&gt;
&lt;li&gt;Over 20 discussions without (yet) tangible direction for issue.&lt;/li&gt;
&lt;li&gt;No paid for all of this &amp;lt;&amp;lt; this is very serious problem in open source now.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well, is it worth? &lt;strong&gt;Absolutely&lt;/strong&gt; Though my contributions are tiny progression, at least it gradually drive project forward. I learn many thing along the way, which I believe it will help me toward my career.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;I would like to thank all Saturn team member, Django Core Team, and Djangonaut for this valuable experience. For ones who want to join, new batch is coming soon! Please stay in touch by following &lt;a href="https://www.linkedin.com/company/djangonaut-space/" rel="noopener noreferrer"&gt;Djangonaut Linkin&lt;/a&gt; and &lt;a href="https://djangonaut.space/" rel="noopener noreferrer"&gt;website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also, if you have any question (relating/unrelating to this post), please feel free to &lt;a href="https://www.kkanin.com/" rel="noopener noreferrer"&gt;reach out&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>django</category>
      <category>opensource</category>
      <category>python</category>
    </item>
    <item>
      <title>[Short-Note] Data Engineering 101</title>
      <dc:creator>(James) Kanin Kearpimy</dc:creator>
      <pubDate>Sat, 17 Sep 2022 07:01:01 +0000</pubDate>
      <link>https://dev.to/kaninkearpimy/short-note-data-engineering-101--5go6</link>
      <guid>https://dev.to/kaninkearpimy/short-note-data-engineering-101--5go6</guid>
      <description>&lt;p&gt;I have been participating in Data Engineering Accelerated Program for 3 days and this is overview I perceived from program. I skipped technical aspect like coding and pipeline, another article would be better :)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Program is undergoing and the rest 5 days are waiting for me!&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  History of data engineering
&lt;/h3&gt;

&lt;p&gt;Organization would like to utilize data such as Dashboard. To compute dashbaord, operator need to pull data from sources (on the left one), clean it, and put to dashboard for analytic user (right one)&lt;/p&gt;

&lt;p&gt;When data source grow bigger. Manual operator is not capable. &lt;strong&gt;Data Engineering&lt;/strong&gt; is come to &lt;strong&gt;automate&lt;/strong&gt; the task.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhfgumii7c6o1mkr5azc1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhfgumii7c6o1mkr5azc1.png" alt="Data Engineering replace operator" width="800" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Extract, Transform, Load (ETL)
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9vbcj62amrrnfidubp9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9vbcj62amrrnfidubp9.png" alt="ETL" width="800" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We really know how &lt;strong&gt;consumer use&lt;/strong&gt; data."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pull data from source, clean and trasnform, save in storage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Extract, Load, Transform (ELT)
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"let &lt;strong&gt;consumer choose&lt;/strong&gt;"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pull data, store in database, then let &lt;strong&gt;consumer choose&lt;/strong&gt; which data they want to use and extract from our source.&lt;/p&gt;

&lt;p&gt;It speed up time to market at some use-cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Whole process of data engineering in organization.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tyglhcfla260rih6ecx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tyglhcfla260rih6ecx.png" alt="whole process of data engineering" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Engineer with ETL/ELT.
&lt;/h3&gt;

&lt;p&gt;Data engineer write script (python, scala) to automate &lt;br&gt;
1) pulling data from source, &lt;br&gt;
2) cleaning them&lt;br&gt;
3) loading them to database. &lt;/p&gt;

&lt;p&gt;Then dashboard will use data to visualize to dashboard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Warehouse and Data Lake.
&lt;/h3&gt;

&lt;p&gt;Data werehouse is type of database that is optimized to store, search, query huge amount of structure, semi-structure, and (sometime) unstructure data.&lt;/p&gt;

&lt;p&gt;Typical dashboard can only show fixed data to user. To acquire insightful one to help making decision, We need data scientist. Somehow current pipeline data can't give proper data to data scientist to explore.&lt;/p&gt;

&lt;p&gt;We need place that store &lt;strong&gt;raw data&lt;/strong&gt;, &lt;strong&gt;without preprocessing&lt;/strong&gt;, and &lt;strong&gt;able to pull&lt;/strong&gt; by data scientist. Its name is [[Data Lake]].&lt;/p&gt;

&lt;h3&gt;
  
  
  OLTP &amp;amp; OLAP
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Online Transactional Processing
&lt;/h4&gt;

&lt;p&gt;is focusing on transaction in database. It's &lt;strong&gt;&lt;em&gt;read, write, update frequently&lt;/em&gt;&lt;/strong&gt;. So, it heavily rely on fast processing. &lt;/p&gt;

&lt;h5&gt;
  
  
  Usecase:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Banking&lt;/li&gt;
&lt;li&gt;Shopping&lt;/li&gt;
&lt;li&gt;Retail scanning&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Online Analyltical Processing
&lt;/h4&gt;

&lt;p&gt;on the other hand, focus on &lt;strong&gt;&lt;em&gt;large volumn, high dimensional&lt;/em&gt;&lt;/strong&gt; data from data warehouse.&lt;/p&gt;

&lt;h5&gt;
  
  
  Usecase:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Data analytic purpose.&lt;/li&gt;
&lt;li&gt;Machine learning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;_I think those are differentiated by database architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Culture and Organization shifting.
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Data democratization
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsah3nxb6uif4on6kk7qd.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsah3nxb6uif4on6kk7qd.jpeg" alt="Data democratization" width="800" height="461"&gt;&lt;/a&gt;&lt;br&gt;
Core concept: enable everyone in organization access to data. It impact intention of people, culture of organization, and tool for everyone to access.&lt;/p&gt;

&lt;h4&gt;
  
  
  Reference
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Content: &lt;a href="https://data-derp.github.io/" rel="noopener noreferrer"&gt;https://data-derp.github.io/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Image &amp;amp; Content: &lt;a href="https://youtu.be/qWru-b6m030" rel="noopener noreferrer"&gt;https://youtu.be/qWru-b6m030&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>datascience</category>
      <category>database</category>
      <category>dataengineering</category>
    </item>
    <item>
      <title>Docker และ Containerization 101 หน้าตาประมาณไหนนะ</title>
      <dc:creator>(James) Kanin Kearpimy</dc:creator>
      <pubDate>Sat, 27 Aug 2022 14:22:34 +0000</pubDate>
      <link>https://dev.to/kaninkearpimy/docker-aela-containerization-101-hnaataapramaanaihnna-2548</link>
      <guid>https://dev.to/kaninkearpimy/docker-aela-containerization-101-hnaataapramaanaihnna-2548</guid>
      <description>&lt;p&gt;Source Code เมื่อพัฒนามากขึ้น จำเป็นต้องมี Environment ที่เหมาะสมเพื่อให้ทำงานได้ เช่น เวอร์ชั่นของ library, สิทธิของโปรแกรม, รวมถึงเรื่องอื่นๆ ทำให้หลายๆ ครั้งเราอาจจะพบกับปัญหาการทำงานร่วมกันภายในทีม เนื่องจาก Souce Code รันได้จากเครื่อง A อาจจะใช้ไม่ได้กับเครื่อง B เป็นต้น&lt;/p&gt;

&lt;h2&gt;
  
  
  Containerization
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpad91038u8k9beue8dny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpad91038u8k9beue8dny.png" alt="Containerization Architecture" width="800" height="639"&gt;&lt;/a&gt;&lt;br&gt;
 เกิดมาเพื่อแก้ไขปัญหาดังกล่าว โดยดึงศักยภาพบางส่วนของ Virtualization มาใช้ แต่ทำให้ขนาดเล็กลง และใช้งานได้ง่ายขึ้นเพื่อการ Automation &lt;/p&gt;

&lt;h2&gt;
  
  
  Docker
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdocs.docker.com%2Fengine%2Fimages%2Farchitecture.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdocs.docker.com%2Fengine%2Fimages%2Farchitecture.svg" alt="Docker Architecture" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
คือ Containerization ตัวหนึ่งที่ทำหน้าที่จำรอง environment ที่เหมาะสมให้กับ Souce Code เพื่อใช้งาน โดยตัว Docker นั้นมีโครงสร้างพื้นฐานประกอบไปด้วย 4 ส่วน ได้แก่&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgkds75ju23q7gre3588r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgkds75ju23q7gre3588r.png" alt="Docker Image &amp;amp; Container" width="800" height="396"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;1) Docker Image&lt;/strong&gt; ทำหน้าที่เป็นส่วนเก็บชุดคำสั่งสำหรับการจำรอง environment ที่เหมาะสม ซึ่งเกิดจากการลง build รายละเอียดคำสั่งจาก Dockerfile&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2) Docker Container&lt;/strong&gt; คือตัว docker image ที่ถูกนำมาเปิดใช้งาน จำรอง environment บน docker host เช่น เรามี image ที่ทำหน้าที่เป็น nginx web server เมื่อเรา build image ตัวดังกล่าว เราจะได้ container หนึ่งตัวมาใช้งานบนเครื่อง&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdvatyv9u4gdp5jlxib1h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdvatyv9u4gdp5jlxib1h.jpg" alt="Docker Daemon" width="702" height="702"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3) Docker Host &amp;amp; Docker Daemon&lt;/strong&gt; คือส่วนของเครื่องที่ติดตั้ง Docker เอาไว้ โดยตัว Deamon คือ core กลางสำคัญสำหรับการรับคำสั่งต่างๆ จากนักพัฒนา เช่น docker build, docker pull, docker run เป็นต้น&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1ydnw9jbgi4246tn3m3.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1ydnw9jbgi4246tn3m3.jpeg" alt="Docker Registry" width="748" height="697"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;4) Docker Registry&lt;/strong&gt; คือส่วนที่เก็บและกระจาย docker image ที่ได้จากนักพัฒนาหรือองค์กรต่างๆ ซึ่งโดยปกติเมื่อสร้าง image เสร็จบน local environment และอยากให้คนในทีมได้ใช้ image ตัวดังกล่าว จะต้องนำมาเก็บไว้บน registry&lt;/p&gt;

&lt;p&gt;Reference &amp;amp; Credit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;image:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/engine/images/architecture.svg" rel="noopener noreferrer"&gt;https://docs.docker.com/engine/images/architecture.svg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.docker.com/wp-content/uploads/2021/11/docker-containerized-appliction-blue-border_2.png" rel="noopener noreferrer"&gt;https://www.docker.com/wp-content/uploads/2021/11/docker-containerized-appliction-blue-border_2.png&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://miro.medium.com/max/1400/0*D4DUZT7y-JD2qyWP.png" rel="noopener noreferrer"&gt;https://miro.medium.com/max/1400/0*D4DUZT7y-JD2qyWP.png&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://miro.medium.com/max/748/1*OvIY-LZD4Y-edFTI8J5ZrQ.jpeg" rel="noopener noreferrer"&gt;https://miro.medium.com/max/748/1*OvIY-LZD4Y-edFTI8J5ZrQ.jpeg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nickjanetakis.com/assets/blog/dockers-architecture-6c296cdac053f794eabed5ddda5c04ba7110c746687a0e8b88ba6df919415175.jpg" rel="noopener noreferrer"&gt;https://nickjanetakis.com/assets/blog/dockers-architecture-6c296cdac053f794eabed5ddda5c04ba7110c746687a0e8b88ba6df919415175.jpg&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>containerization</category>
    </item>
    <item>
      <title>เรามาลองใช้ Git Command ระดับกลาง (หรือสูง) กันมั้ยครับ: stash, squash, rebase</title>
      <dc:creator>(James) Kanin Kearpimy</dc:creator>
      <pubDate>Wed, 02 Mar 2022 13:44:54 +0000</pubDate>
      <link>https://dev.to/kaninkearpimy/eraamaalngaich-git-command-ainradabyaakkhuen-nidnueng-kanmay-rebase-and-merge-3p1b</link>
      <guid>https://dev.to/kaninkearpimy/eraamaalngaich-git-command-ainradabyaakkhuen-nidnueng-kanmay-rebase-and-merge-3p1b</guid>
      <description>&lt;p&gt;หากว่าเราพูดถึง git สำหรับคนเริ่มต้น คงจะหนีไม่พ้นคำสั่งต่างๆ เหล่านี้&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;git add . &lt;em&gt;// เพิ่ม files ที่ถูกแก้เข้า staged change&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;git commit -m "message" &lt;em&gt;// เพิ่ม staged change files เข้า commit history&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;git push &amp;amp; git pull _// syncing ระหว่าง local (เครื่องที่บ้าน) กับ remote (เครื่องบน server ของผู้ให้บริการ เช่น github)&lt;br&gt;
_&lt;br&gt;
วันนี้เราจะลองดูอีก 3 คำสั่งที่ใช้กันค่อนข้างบ่อย เมื่อเริ่มคุ้นชินกับการทำงานของ git มากขึ้น&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;git stash&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;git squash&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;git rebase&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  git stash
&lt;/h2&gt;

&lt;p&gt;ลองนึกถึงสถานการณ์ที่พวกเรากำลังแก้ไฟล์อยู่ และทำไปได้ระดับหนึ่งแล้วแต่บังเอิญว่ามีงานด่วนเข้ามา และเราต้องหันไปทำงานนั้นทันที ปัญหาจะเกิดดังนี้ครับ&lt;br&gt;
1) ยังมี change files ที่ยังไม่เสร็จ และยัง commit ไม่ได้ เพราะอาจจะเกิดผลเสียมากกว่าข้อดี&lt;br&gt;
2) เราสามารถสร้าง branch ใหม่ให้เก็บ change ของเราได้ แต่ก็เปลืองอยู่ดี&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flj3i950gghr9h75fg7w4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flj3i950gghr9h75fg7w4.png" alt="git stash example 1" width="566" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ในกรณีแบบนี้ git stash จะมีประโยชน์มาก เพราะสิ่งที่ git stash ทำจะเป็นการ save ตัว change files ของเราเอาไว้ใน local แต่จะไม่ถือว่าเป็น commit ทำให้สามารถสลับไปทำงานอื่นและ syncing ข้อมูลกับ remote ได้อย่างอิสระ (เพราะอย่างไร change ก็ไม่ปนขึ้นไปด้วยอยู่ดี)&lt;/p&gt;

&lt;p&gt;โดยเมื่อต้องการทำ &lt;code&gt;git stash&lt;/code&gt; ให้ทำการเพิ่มทุก files ที่ต้องการเข้าสู่ staged change (&lt;code&gt;git add&lt;/code&gt;) ก่อน จากนั้นให้พิมพ์คำสั่ง &lt;code&gt;git stash&lt;/code&gt; เพื่อ save เก็บไว้ในเครื่อง (ตามภาพด้านล่าง)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1npmu85qxwbzsgsnfjw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1npmu85qxwbzsgsnfjw.png" alt="git stash example 2" width="566" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;จากนั้นเมื่อทำการ git status (หรือ gst) อีกครั้งจะเห็นได้ว่า change file ได้หายไป (ถูกเก็บเข้า stash) เรียบร้อยแล้ว ซึ่งเราสามารถสลับไปทำ features อื่นได้โดยไม่ต้องกังวลถึง change files อีก โดยสามารถเช็คได้ว่าเรามี change files ที่ stash ไว้กี่ครั้ง สามารถทำได้โดยคำสั่ง&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git stash list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frexvncu7s526uda3eek4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frexvncu7s526uda3eek4.png" alt="git stash example 3" width="566" height="49"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;และเมื่อต้องการนำสิ่งที่ stash ไปกลับมาเพื่อแก้ไข พัฒนาต่อเราสามารถใช้คำสั่ง&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git stash apply stash@{i}&lt;/code&gt; // โดย i คือตัวเลขของ stash order ซึ่ง stash ล่าสุดจะไล่จากน้อยไปมาก เช่น stash@{0} คือ stash ที่ถูกเพิ่มล่าสุด&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcualqtfakfxwf6gaxwtv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcualqtfakfxwf6gaxwtv.png" alt="git stash example 4" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เพียงเท่านี้ก็จะสามารถจัดการกับ change ที่เราต้องการ แต่ยังไม่อยาก commit ได้แล้ว&lt;/p&gt;

&lt;h2&gt;
  
  
  git squash
&lt;/h2&gt;

&lt;p&gt;ในสถานการณ์ที่ เรามีการทำงานบน features ใดๆ ไม่ใช่เรื่องแปลกที่จะมีการ commit อยู่บ่อยครั้ง เพื่อความสะดวกในการติดตามการเปลี่ยนแปลง ซึ่งในบางครั้ง เมื่อรู้สึกตัวอีกที commit history ของเราก็หน้าตาเช่นด้านล่างไปแล้ว&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmccs2e0mbwzfrv3oo0qs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmccs2e0mbwzfrv3oo0qs.png" alt="git squash history example 1" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เราจะสังเกตุได้ว่า มี commits 3 ครั้งคือ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;init squash&lt;/li&gt;
&lt;li&gt;set up init config in squash.txt&lt;/li&gt;
&lt;li&gt;modify config in squash.txt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ซึ่ง messages ทั้ง 3 ครั้งนี้ รวมถึงตัว source code เองมีความใกล้เคียงกันมาก หากเราทำงานในทีมขนาดใหญ่ การทำให้ commit history มีความกระชับและง่ายต่อการติดตาม เป็นเรื่องที่สำคัญอย่างหลีกเลี่ยงไม่ได้&lt;/p&gt;

&lt;p&gt;และ &lt;code&gt;git squash&lt;/code&gt; จะเข้ามาแก้ปัญหาข้างต้นครับ โดยปกติการทำกิจ squash ทักจะใช้คู่กับ git rebase หรือ git merge โดยเราจะใช้ git rebase ในตัวอย่างนี้ เพื่อ rebase squash นั้นวิธีที่ง่ายที่สุดคือใช้ interactive mode ของ git rebase โดยใช้งานคำสั่ง&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git rebase [commit hash] -i&lt;/code&gt; // โดย hash คือตัว commit ที่เราต้องการ rebase กลับไป&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuubi1ysi5djrpwofyhtu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuubi1ysi5djrpwofyhtu.png" alt="git squash history example 2" width="728" height="104"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;จากรูปด้านบน เราจะ squash 3 commits เข้าด้วยกัน &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa4cxkgl1y4pes8pnm5ne.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa4cxkgl1y4pes8pnm5ne.png" alt="git squash history example 6" width="419" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;หลังพิมพ์คำสั่ง terminal จะเปิดหน้าจอให้เราเลือกว่าจะ squash ตัวใด และตัวใดจะเป็น hash ที่รอรับการ squash ซึ่งเราเลือก hash &lt;code&gt;bdfaf72&lt;/code&gt; สำหรับรองรับ commit ที่กำลังจะถูก squash&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7942ddzmp66b4ce9fq4r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7942ddzmp66b4ce9fq4r.png" alt="git squash history example 4" width="553" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;s, squash คือการเลือก commit นั้นๆ ให้ถูกมัดรวม&lt;/li&gt;
&lt;li&gt;p, pick คือการเลือก commit นั้นๆ ให้เป็นที่รองรับ squash commit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;จากนั้นตัว terminal (git) จะเปิดหน้าต่างให้เราเลือก commit message ของการ squash &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjxllyvxx0w5b3bartyql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjxllyvxx0w5b3bartyql.png" alt="git squash history example 5" width="529" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;หลังเสร็จสิ้นการ squash เราจะสังเกตุได้ว่า commits ทั้ง 3 ตัวนั้นหายไปและมี commit ใหม่ที่เกิดจากการ squash ขึ้นมาแทนเรียบร้อยแล้ว&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwg4wjiip9orn8dvycjm2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwg4wjiip9orn8dvycjm2.png" alt="git squash history example 5" width="465" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  git rebase
&lt;/h2&gt;

&lt;p&gt;เมื่อคำสั่งที่ผ่านมา เราได้ใช้ git rebase ไปบ้างแล้ว แต่จริงๆ คำสั่ง git rebase เขาเอาไว้ทำอะไรกันแน่ละ&lt;/p&gt;

&lt;p&gt;ลองนึกถึงกรณีที่ระหว่างการพัฒนา ทีมของเรา commit code บางอย่างเข้ามาใน branch main และไม่มีใครสังเกตุ จนกระทั่งเวลาผ่านไป พึ่งรู้ว่ามีปัญหาอยู่ใน source code และต้องการแก้อย่างเร่งด่วน ประเด็นคือ เราไม่สามารถอยู่ๆ ไปไล่ลบ commit ออกได้เลย เพราะ commit ดังกล่าวก็มีคำสั่งอื่นๆ ที่จำเป็นอยู่ด้วย&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw7sjk9ptp0sop88d4udj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw7sjk9ptp0sop88d4udj.png" alt="git rebase example 1" width="652" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;โดยเราสามารถเลือกแก้ได้หลายแบบ โดยวิธีที่กำลังจะทำก็คือ &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;checkout กลับไปยัง commit ที่ต้องการแก้&lt;/li&gt;
&lt;li&gt;แตก branch ใหม่ และแก้ปัญหา&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuo9xmkxxb7uq2rtmrpsp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuo9xmkxxb7uq2rtmrpsp.png" alt="git rebase example 2" width="728" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เมื่อทราบ commit ที่ต้องการแก้แล้ว ให้ทำการ checkout กลับไปที่ hash ดังกล่าว&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git checkout d0ec37e&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwg3ex1pz9t2yrx3szfz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwg3ex1pz9t2yrx3szfz.png" alt="git rebase example 3" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;จากนั้นให้ทำการแก้สิ่งที่ต้องการและแตก branch แยกออกมา&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpd02d3j1vb8rce9a7iz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpd02d3j1vb8rce9a7iz.png" alt="git rebase example 4" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ซึ่งเมื่อสังเกตุจะเห็นได้ว่า history ของ git นั้นมีบางส่วนหายไป (อิงจากรูปด้านบน) คือ &lt;code&gt;bd3b066&lt;/code&gt; และ &lt;code&gt;eebae51&lt;/code&gt; ซึ่งกรณีนี้นั้น &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4aphy8x9l0giw7uk1p4x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4aphy8x9l0giw7uk1p4x.png" alt="git rebase example 5" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;หากเรา &lt;strong&gt;merge&lt;/strong&gt; main branch ทันที สิ่งที่เกิดขึ้นคือ ตัว history ของเราใน branch นี้จะหายไป (ซึ่งนำไปสู่การตาม track ที่ยากขึ้น)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03clrwrc4909wjmxy2m3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03clrwrc4909wjmxy2m3.png" alt="git rebase example 6" width="744" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;แต่หากเราใช้ git rebase สิ่งที่เกิดขึ้นคือ git จะนำ history ของ change มาต่อส่วนหัวของ branch ที่เราต้องการ rebase ทำให้ history ไม่หายไป (และตาม track ง่ายขึ้น)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5xona5n0zrmo1z71y9p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5xona5n0zrmo1z71y9p.png" alt="git rebase example 7" width="800" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;โดยเราสามารถพิมพ์คำสั่ง&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git rebase [target branch name] [current branch]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git rebase main fixed-critical-001&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkub5esffe51yurw12ug6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkub5esffe51yurw12ug6.png" alt="git rebase example 8" width="800" height="55"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;และหากเรา &lt;code&gt;git log --oneline&lt;/code&gt; อีกครั้ง เราจะพบว่า history ที่หายไปถูกนำมารวมกลับใน branch ใหม่แล้ว&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjz7aqtvuxg5u3pf5s0ca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjz7aqtvuxg5u3pf5s0ca.png" alt="git rebase example 9" width="800" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>เราจะใช้ SSH กับ Github ได้ยังไงบ้าง</title>
      <dc:creator>(James) Kanin Kearpimy</dc:creator>
      <pubDate>Sun, 06 Feb 2022 08:50:01 +0000</pubDate>
      <link>https://dev.to/kaninkearpimy/ssh-190o</link>
      <guid>https://dev.to/kaninkearpimy/ssh-190o</guid>
      <description>&lt;p&gt;การเข้ารหัสข้อมูลไม่ใช่เรื่องใหม่ แต่มีมานานมากแล้ว ในสมัยสมัครสงครามโลกครั้งที่ 2 นั้น นาซีเยอรมันได้ประดิษฐ์เครื่องสำหรับเข้ารหัสสื่อสารชื่อ Enigma ซึ่งในตอนท้ายถูกฝั่งอังกฤษถอดรหัสได้ด้วยการใช้เครื่อง Turing Machine อันเป็นต้นแบบคอมพิวเตอร์ยุคปัจจุบัน &lt;/p&gt;

&lt;p&gt;ในปัจจุบันการเข้ารหัสใช้กันอย่างแพร่หลายในวงการคอมพิวเตอร์ โดยเราจะเรียกว่าการสร้างความปลอดภัยภายในการสื่อสารระหว่างกันว่า Cryptography ซึ่ง secure shell (ssh) ก็ถือเป็นหนึ่งในการทำ Cryptography อย่างหนึ่งเช่นกัน แต่มันจะทำอะไรได้บ้างนั้น เรามาลองดูกันครับ&lt;/p&gt;

&lt;h2&gt;
  
  
  Secure Shell and Client-Server
&lt;/h2&gt;

&lt;p&gt;ก่อนเราจะเข้าใจ Secure Shell เรามาทวนเรื่อง Client-Server กันซักหน่อยก่อน &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmntjpeml01tm0ftm379g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmntjpeml01tm0ftm379g.png" alt="client-server architecture" width="800" height="646"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;การทำงานของ Client-Server นั้นจะมี client ขอส่ง request message เข้าหา server เพื่อทำการ manipulate บางสิ่ง จากนั้น return message response กลับไปให้ client เพื่อใช้งานต่อ ซึ่งจุดสังเกตุคือ หากว่ามีคนสามารถดักเส้นการส่ง message ดังกล่าวได้ แล้วแทรก message เพื่อโจมตี server หรือ client ระหว่างการขนส่ง (communication) ก็จะสร้างความเสียหายได้&lt;/p&gt;

&lt;p&gt;ดังนั้นเพื่อป้องกันเหตุการดังกล่าว จึงจำเป็นต้องมีการเข้ารหัสข้อความเอาไว้ เหมือนใส่ข้อความไว้ในกล่องที่มี&lt;strong&gt;แม่กุญแกล็อก&lt;/strong&gt;ไว้ และส่งออกไป จากนั้นเมื่อถึงปลายทางจึงให้คนที่มี&lt;strong&gt;ลูกกุญแจ&lt;/strong&gt;เท่านั้น สามารถเปิดอ่านข้อความได้&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqdyl5yurt778pya6mv1s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqdyl5yurt778pya6mv1s.png" alt="asymmetric key" width="800" height="602"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;การทำ secure shell (ssh) เป็นการสร้างกุญแจ (key) รูปแบบ asymmetric key โดยจะมี&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;public key: ที่ถูกแชร์ให้กับทุกคนที่ต้องการจะระบุตัวตนของข้อความ (verify)&lt;/li&gt;
&lt;li&gt;private key: จะถูกเก็บเอาไว้กับผู้ส่งข้อความเท่านั้น เพื่อทำการเข้ารหัส&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4g6bkq086kskb9dkr3u2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4g6bkq086kskb9dkr3u2.png" alt="asymmetric key" width="800" height="737"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SSH with Github
&lt;/h2&gt;

&lt;p&gt;โดยการประยุกต์ใช้ ssh ที่ชัดเจนที่สุดคือการระบุตัวตนในการเข้าถึง server เช่น การ login เข้า server ผ่าน client เพื่อส่งข้อมูล ส่งไฟล์ หรือแม้แต่การ remote control&lt;/p&gt;

&lt;p&gt;การใช้งาน git นั้นสามารถใช้ ssh เพื่อเพิ่มความปลอดภัยในการทำงานร่วมกันภายในทีมได้ ในทางปฏิบัติแล้วการใช้ ssh จะทำให้เราเข้าถึง remote server บน git ได้โดยไม่ต้องให้ username หรือ personal access token ทุกครั้ง เพราะข้อมูลเหล่านั้นถูกเก็บไว้ใน ssh key-pair หมดแล้ว&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;การตั้งค่า ssh และการใช้งานกับ github&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;เปิด Terminal และสร้าง ssh key-pair (public &amp;amp; private) ด้วยคำสั่ง 
&lt;code&gt;ssh-keygen -t [algorithm] -C [comment message]&lt;/code&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;จากนั้นให้ระบุ path และชื่อไฟล์ที่ต้องการสร้าง รวมถึง password &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3eyr951lfhomrj37z2og.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3eyr951lfhomrj37z2og.png" alt="generate ssh key-pair" width="800" height="88"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ทำการนำ key-pair สร้างเป็น default ใน ssh config ของเครื่อง เพื่อที่ทุก ครั้งที่ request หา git จะใช้ key-pair นี้ โดยให้ใช้คำสั่งสร้าง config ใน folder .ssh ที่ root directory.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;vim ~/.ssh/config&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;จากนั้นใส่ config ตามด้านล่างลงไปและบันทึกการเปลี่ยนแปลง&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4m44qq31s6ii3tj665tx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4m44qq31s6ii3tj665tx.png" alt="สร้าง ssh config file" width="800" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;เพิ่ม public key ลงใน github account 
ทำการคัดลอกค่า public key เอาไว้&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwuli4otjqug4clk4sjbr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwuli4otjqug4clk4sjbr.png" alt="github ssh create" width="800" height="36"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;จากนั้นเปิด setting ของ github account และ copy ค่า public key ลงไปและบันทึก&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fev0njoyeu906aqa18jc9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fev0njoyeu906aqa18jc9.png" alt="github ssh create" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03afkv5359ggouxl2jda.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03afkv5359ggouxl2jda.png" alt="github ssh create" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ทดสอบความถูกต้องด้วยการลองพยายาม secure shell เข้าที่ git remote server ด้วยคำสั่ง
&lt;code&gt;ssh -T git@github.com&lt;/code&gt; 
หากขึ้นผลลัพท์ที่ถูกต้องจะเป็นอย่างรูปด้านล่าง&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxraatao1npiaja1nhgx3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxraatao1npiaja1nhgx3.png" alt="ssh -T git@github.com result" width="800" height="39"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  สรุป
&lt;/h2&gt;

&lt;p&gt;การทำ secure shell เป็นการเพิ่มความปลอดภัยให้กับการส่งข้อมูลผ่านเครือข่าย โดยใน github เราสามารถใช้งาน ssh key-pair สำหรับการยืนยันตัวตนเพื่อทำงานร่วมกันภายใน github ได้ &lt;/p&gt;

&lt;p&gt;จริงๆ แล้วการทำ Cryptography ไม่ได้จำกัดเฉพาะ client-server หรือการส่งข้อมูลเพียงเท่านั้น แต่ยังสามารถใช้สำหรับงานอื่น อาทิเช่นการสร้าง transaction ใน blockchain ได้อีกด้วย ซึ่งจะเป็นอย่างไร เรามาติดตามกันต่อในบทความต่อๆ ไปครับ&lt;/p&gt;

</description>
      <category>github</category>
      <category>ssh</category>
    </item>
    <item>
      <title>Version Control คืออะไรนะ? จากความเข้าใจของ Junior Developer</title>
      <dc:creator>(James) Kanin Kearpimy</dc:creator>
      <pubDate>Fri, 21 Jan 2022 14:36:36 +0000</pubDate>
      <link>https://dev.to/kaninkearpimy/version-control-101-in-view-of-junior-developer-29ba</link>
      <guid>https://dev.to/kaninkearpimy/version-control-101-in-view-of-junior-developer-29ba</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzpjc0jey24guozt6jssm.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzpjc0jey24guozt6jssm.jpeg" alt="Ref: https://www.pexels.com/photo/person-choosing-document-in-folder-4792285/" width="800" height="534"&gt;&lt;/a&gt;&lt;br&gt;
เคยทำงานเอกสารเพื่อส่งอาจารย์ตรวจ แล้วต้องโดนแก้กลับมากันมั้ยครับ? ซักพัก ก็โดนให้ย้อนกลับไปดูเอกสารฉบับที่ส่งไปเมื่อ 3 วันก่อน ถ้าคนที่่เก็บเอกสารเก่าๆ เอาไว้ ก็จะแบ่งเอกสารเหล่านั้นเป็นเวอร์ชั่นๆ เช่น &lt;em&gt;แก้-ver1 แก้-ver2 แก้-ver[x]&lt;/em&gt; ไปเรื่อยๆ &lt;/p&gt;

&lt;p&gt;สิ่งนี้เองไม่ได้เกิดกับงานเอกสารเท่านั้น แต่กับงานพัฒนาซอฟต์แวร์ด้วยเช่นกัน การพัฒนาซอฟต์แวร์ สามารถเกิดการเพิ่มเติม แก้ไข เปลี่ยนแปลงตัว Source Code อยู่ตลอดเวลา &lt;/p&gt;

&lt;p&gt;แล้วเราจะ&lt;strong&gt;ติดตามการเปลี่ยนแปลง&lt;/strong&gt;ของ Source Code กันได้อย่างไรกัน คงจะไม่ใช่การตั้งชื่อไฟล์เป็น Version กันใช่มั้ยครับ? นั้นเป็นที่มาของคำว่า &lt;strong&gt;Version Control&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;อะไรคือ Version Control ละ?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;สั้นๆ Version Control คือเครื่องมือที่ทำให้ Developer ติดตามการเปลี่ยนแปลงที่เกิดขึ้นใน Source Code ของโปรเจคได้ ซึ่งเมื่อติดตามได้ มันจึงทำให้&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;การทำงานระหว่างกลุ่ม Developer ทำได้ง่ายขึ้น เพราะแต่ละคนก็พัฒนาของตัวเอง เมื่อต้องการจะรวมเข้ากับ Source ตรงกลาง ก็ทำการเช็คการเปลี่ยนแปลง (Change) และขอรวม Code version ของตัวเองเข้ามา (Merge)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Developer สามารถทราบถึงประวัติการเปลี่ยนแปลง (History Change) และดึง Source Code ตามประวัติกลับมา หากว่า version ปัจจุบันทำให้โปรเจคเสียหายหรือผิดพลาด&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ทราบว่าใครเป็นผู้สร้างการเปลี่ยนแปลงภายใน source code ทำให้หาผู้เกี่ยวข้องได้ และสามารถช่วยกันแก้ไขปัญหาได้รวดเร็ว (Ideally)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Repository หมายถึงโปรเจคหรือที่เก็บ Source Code เอาไว้เป็นที่เดียวกัน โดยใน หนึ่ง Repository อาจจะมี Repository ย่อย (Mono-Repository) เอาไว้อีกด้วย&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxji92n47f1nq16wm8g40.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxji92n47f1nq16wm8g40.png" alt="Ref: https://homes.cs.washington.edu/~mernst/advice/version-control.html#:~:text=Version%20control%20enables%20multiple%20people,interfere%20with%20another%20person's%20work." width="417" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Version Control จะแบ่งได้ออกเป็น 2 รูปแบบใหญ่ ได้แก่&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Centralized Version Control&lt;/strong&gt;: คือการที่ Repository ถูกรวบรวมไว้ที่ server กลาง ดังนั้นการเปลี่ยนแปลงทั้งหมดจะต้องเชื่อมโยงกับ Repository บน Server เป็นหลัก ตัวอย่างเครื่องมือเช่น Subversion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Distributed Version Control&lt;/strong&gt;: คือการที่ Repository สามารถถูกคัดลอก (copy) ลงไปแต่ละเครื่องของ Developer ได้ และคนอื่นๆ จะไม่สามารถเข้าถึง version ต่างๆ เหล่านั้นได้ จนกว่าเราจะทำการส่ง version ของเราขึ้นไปที่ Repository กลาง เครื่องมือเช่น Git&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*โดยในบทความนี้ เราจะพูดถึง Distributed VC ด้วยเครื่องมือ Git เป็นหลัก&lt;/p&gt;

&lt;h2&gt;
  
  
  Git คืออะไร?
&lt;/h2&gt;

&lt;p&gt;Git คือ Open Source สำหรับจัดการ ติดตาม การเปลี่ยนแปลงภายใน Project ตั้งแต่ขนาดเล็ก ไปจนถึงขนาดใหญ่ โดย Git จะสามารถติดตามการเปลี่ยนแปลงแบ่งเป็น Version ตามรูปด้านล่าง&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fipd4oiaad4ut06f2fzte.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fipd4oiaad4ut06f2fzte.png" alt="Ref: https://www.nobledesktop.com/learn/git/git-branches" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;โดยปกติในหนึ่งโปรเจคจะมีหลาย Features โดยเราจะนิยมเรียก features เหล่านี้ว่า branch โดยในแต่ละ branch ก็จะมี version ที่เกิดจากการพัฒนาปรับปรุงขึ้นมา&lt;/p&gt;

&lt;p&gt;เราจะเรียก feature หลักของโปรเจคว่า master หรือ main branch โดยจะทำหน้าที่เป็นตัวหลักในการทำงาน อ้างอิง รวมไปถึงการนำไปใช้งาน (on production) ต่างๆ อีกด้วย &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local &amp;amp; Remote Repository&lt;/strong&gt;&lt;br&gt;
ปกตินั้น การพัฒนาโปรเจค เราจะมีตัวเก็บ Repository หลักเอาไว้ เพื่อกระจาย อ้างอิง ให้ทุกคนภายในทีมพัฒนา เราจะเรียกว่า Remote Repository ซึ่ง repository ที่ถูกดึง (pull) ลงไปยังเครื่องของคนภายในทีมเพื่อพัฒนาต่อนั้น จะถูกเรียกว่า Local Repository&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fos6jl0n7v9b43c0cb3l9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fos6jl0n7v9b43c0cb3l9.png" alt=" " width="800" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ซึ่งแต่ละคนภายในทีม จะยังไม่สามารถเห็นการเปลี่ยนแปลงของสมาชิกได้ หากการเปลี่ยนแปลง (Change) ยังอยู่ที่เครื่อง (Local) ของแต่ละคน โดยเมื่อต้องการเพิ่มเติม source code ให้โปรเจคหลัก เพื่อให้ทุกคนเห็นหรือนำไปใช้ จะต้องทำการส่ง (push) ขึ้นมาที่ Remote Repository ต่อไป&lt;/p&gt;

&lt;h2&gt;
  
  
  คำสั่ง Git พื้นฐานและ usecase ใช้งาน
&lt;/h2&gt;

&lt;p&gt;เราจะมีพูดถึงคำสั่งพื้นฐานสำหรับการใช้งาน Git ทั้งหมด 5 คำสั่ง ได้แก่ clone, add, commit, push, pull &lt;/p&gt;

&lt;p&gt;1.&lt;code&gt;git clone&lt;/code&gt; : คือการดึง repository จาก remote ลงมาสู่ local โดยจะมีวิธีทำได้ 2 รูปแบบหลักๆ คือ https และ ssh (จะมีการอธิบายต่อในบทความต่อๆ ไปครับ )&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2d79j1s5s1n1dezaebbi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2d79j1s5s1n1dezaebbi.png" alt=" " width="500" height="584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2.&lt;code&gt;git pull&lt;/code&gt; : จะเป็นการดึง code version จาก remote branch ลงมาสู่ local branch เช่นกัน แต่ความแตกต่างคือ จะมีความเจาะจงไปยัง branch มากกว่า&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmpy0p2xrs99x42v6ncr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmpy0p2xrs99x42v6ncr.png" alt=" " width="572" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ตัวอย่าง:&lt;/strong&gt; เราพัฒนา shopping cart บน local branch จากนั้น เพื่อนได้อัพเดท code บางอย่างเข้า remote branch เดียวกัน เราสามารถ pull code ลงมาเพื่อตรวจสอบหรือใช้งานได้&lt;/p&gt;

&lt;p&gt;3.&lt;code&gt;git add&lt;/code&gt; : เราต้องเข้าใจก่อนว่า ในการพัฒนา source code บน local branch นั้น เวลาที่มีการเปลี่ยนแปลง ตัว git จะทำงานติดตาม (track) และหากว่าเราต้องการที่จะเก็บการเปลี่ยนแปลงนั้นไว้ แต่ยังไม่แน่ใจว่าจะอัพเดทเวอร์ชั่นใหม่มั้ย เราจะเรียกพื้นที่ตรงนั้นว่า stage change โดยการใช้ git add หมายถึงการนำไฟล์ที่เปลี่ยนแปลงเข้าสู่ stage change นั้นเอง&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw5de0iurjfosmh0bhglt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw5de0iurjfosmh0bhglt.png" alt=" " width="463" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4.&lt;code&gt;git commit&lt;/code&gt; : จะเป็นคำสั่งที่มักใช้ต่อกับ git add กล่าวคือ เมื่อเรามั่นใจแล้วว่า ต้องการให้การเปลี่ยนแปลงใน source code นั้นอัพเดทเวอร์ชั่นแน่ๆ เราจะทำการย้าย การเปลี่ยนแปลง (change) จาก stange change เข้าสู่ branch history ด้วยการ commit&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibz3u7is013trpv1d5v4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibz3u7is013trpv1d5v4.png" alt=" " width="480" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5.&lt;code&gt;git push&lt;/code&gt; : คือการนำการเปลี่ยนแปลงที่อยู่ใน branch history บน local branch ขึ้นสู่ remote branch เพื่อให้สมาชิกในทีมได้ตรวจสอบหรือนำไปใช้งานต่อไป&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl75i5hwgr99zr7fn30hu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl75i5hwgr99zr7fn30hu.png" alt=" " width="594" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  สรุป
&lt;/h2&gt;

&lt;p&gt;Version Control นั้นสามารถช่วยให้การติดตามการเปลี่ยนแปลงของ source กcode ภายในโปรเจคนั้นทำได้ง่าย ซึ่งก่อให้เกิดการพัฒนาเป็นทีมได้อย่างเป็นระบบ เกิดขึ้นพร้อมกันได้ ตั้งแต่โปรเจคขนาดเล็ก - ขนาดใหญ่ได้&lt;/p&gt;

&lt;p&gt;ในบทความต่อไป เราจะมาลงมือติดตั้ง git โดยใช้ github เป็น remote repository และทดลองใช้งานคำสั่งต่างๆ จากด้านบน และที่มีเพิ่มเติมกันครับ :)&lt;/p&gt;

&lt;h2&gt;
  
  
  อ้างอิงและขอบคุณ (Appreciate &amp;amp; Reference)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://homes.cs.washington.edu/%7Emernst/advice/version-control.html#:%7E:text=Version%20control%20enables%20multiple%20people,interfere%20with%20another%20person's%20work" rel="noopener noreferrer"&gt;https://homes.cs.washington.edu/~mernst/advice/version-control.html#:~:text=Version%20control%20enables%20multiple%20people,interfere%20with%20another%20person's%20work&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://towardsdatascience.com/version-control-101-getting-started-with-git-3b2c78d91184" rel="noopener noreferrer"&gt;https://towardsdatascience.com/version-control-101-getting-started-with-git-3b2c78d91184&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.toolsqa.com/git/local-repository-remote-repository/#:%7E:text=Git%20remote%20is%20just%20a,git%20remote%20for%20the%20same" rel="noopener noreferrer"&gt;https://www.toolsqa.com/git/local-repository-remote-repository/#:~:text=Git%20remote%20is%20just%20a,git%20remote%20for%20the%20same&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pexels.com/photo/person-choosing-document-in-folder-4792285/" rel="noopener noreferrer"&gt;https://www.pexels.com/photo/person-choosing-document-in-folder-4792285/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nobledesktop.com/learn/git/git-branches" rel="noopener noreferrer"&gt;https://www.nobledesktop.com/learn/git/git-branches&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/" rel="noopener noreferrer"&gt;https://git-scm.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
    </item>
    <item>
      <title>[KubeOps Academy] Palindrome with Rust ทำยังไงนะ!?</title>
      <dc:creator>(James) Kanin Kearpimy</dc:creator>
      <pubDate>Mon, 17 Jan 2022 13:02:57 +0000</pubDate>
      <link>https://dev.to/kaninkearpimy/kubeops-academy-palindrome-with-rust-thamyangaingna-10gm</link>
      <guid>https://dev.to/kaninkearpimy/kubeops-academy-palindrome-with-rust-thamyangaingna-10gm</guid>
      <description>&lt;p&gt;อยากให้ทุกคนลองเขียนชื่อตัวเองจาก หลังไปหน้า แล้วอ่านดู... อ่านรู้เรื่องกันมั้ยครับ? แล้วเคยสงสัยมั้ย ว่าทำไมชื่อคนบางคนไม่ว่าจะอ่านจากหลังไป&lt;/p&gt;

&lt;h2&gt;
  
  
  อะไรคือ palindrome?
&lt;/h2&gt;

&lt;p&gt;Palindrome คือ ประโยคหรือคำ ทั้งในเชิงอักษร (ABC, abc) ตัวเลข (123321) และตัวอักขระ ที่เรียงต่อกันแล้วสามารถอ่านแล้วได้ความหมายเดิม ทั้งจากหลังไปหน้า และหน้าไปหลัง&lt;/p&gt;

&lt;p&gt;ในทางคอมพิวเตอร์ ได้มีการทำ Palindrome มาใช้สำหรับการบีบอัด (Compression) DNA อีกด้วย &lt;a href="https://www.researchgate.net/publication/343284206_A_Compression_Algorithm_for_DNA_Palindrome_Compression_Technique" rel="noopener noreferrer"&gt;อ่านต่อ&lt;/a&gt;&lt;br&gt;
Why rust?&lt;/p&gt;
&lt;h2&gt;
  
  
  เราจะแก้โจทย์ Palindrome ได้อย่างไร?
&lt;/h2&gt;

&lt;p&gt;การแก้ Palindrome นั้นมีวิธีคิดได้หลากหลายในทางกระบวนการวิธี เช่น ตัดครึ่งคำ จากนั้นนำฝั่งซ้าย - ขวา มาทาบกัน โดยบทความนี้จะนำวิธีการ ไล่คำจากด้านหลังและด้านหน้าทีละตัวอักษรพร้อมๆ กัน เพื่อเปรียบเทียบว่าเป็น Palindrome หรือป่าว&lt;/p&gt;
&lt;h2&gt;
  
  
  แนวคิด
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fga1ja6gupiwm2j5zh2m8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fga1ja6gupiwm2j5zh2m8.png" alt=" " width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;จากภาพด้านบน ให้ลองคิดว่า ให้&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;เรานำปากกา 2 ด้านมาวางไว้ที่ปลายสุดของทั้งสองฝั่ง&lt;/li&gt;
&lt;li&gt;จากนั้นให้เปรียบเทียบตัวอักษรที่ปลายของปากกาทั้งสอง &lt;/li&gt;
&lt;li&gt;เมื่อเปรียบเทียบแล้ว ให้ขยับปากกาเข้าหากัน &lt;/li&gt;
&lt;li&gt;เปรียบเทียบ ทำเช่นนี้ไปเรื่อยๆ
5.1 หากรอบใดที่ปลายตัวอักษรปลายปากกาไม่เท่ากัน สรุปได้ว่าคำนั้น &lt;strong&gt;ไม่ใช่&lt;/strong&gt; Palindrome
5.2 หากว่าเปรียบเทียบหมดแล้ว ตัวอักษรทุกตัวเท่านั้น สรุปได้ว่า &lt;strong&gt;คำนั้นคือ Palindrome&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  ลงมือเขียน Code กัน!!
&lt;/h2&gt;

&lt;p&gt;โดยเราจะใช้ ภาษา Rust ซึ่งเป็นภาษา System Programming หนึ่งที่ค่อนข้างฝึกให้เราคิดถึง process เบื้องหลังการทำงานของ Computer &lt;/p&gt;

&lt;p&gt;Import การจัดการ input/output ของภาษา Rust&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;use std::io::stdin;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;ภายใน Function main ซึ่งถือเป็น function หลักของโปรแกรม เราจะแสดงข้อความออกทาง terminal ให้ผู้ใช้งานเข้าใจการทำงานคร่าวๆ และถ้าพร้อมให้ผู้ใช้พิมพ์คำที่อยากเช็ค Palindrome ลงมา&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;println!("Palindrome.");
    println!("If you want to exit. please type ==&amp;gt; :q\n");
    loop {
        let mut pre_string = String::new();
        println!("Please input your thing ==&amp;gt;");
        stdin().read_line(&amp;amp;mut pre_string).expect("Please put correct string.");

        let string: &amp;amp;str = &amp;amp;pre_string.trim().replace(" ", "");
        if string.to_uppercase() == END_GAME {
            println!("==========");
            println!("THANK YOU.");
            println!("==========");
            break;
        }
        if string == "" {
            println!("Please put correct string!\n");
            continue;
        }

        let is_palindrome: bool = check_palindrom(string);

        println!("is {} Palindrome? : {}\n", string, match is_palindrome { true =&amp;gt; "YES", false =&amp;gt; "NO" });
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;โดยจะทำการ loop วนจนกว่าผู้ใช้งานพิมพ์คำว่า "END" จึงจะหยุดการทำงาน&lt;/p&gt;

&lt;p&gt;โดยขออธิบายการทำงานของ check_palindrome function สำหรับเช็ค palindrome ตามด้านล่าง&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn check_palindrom(string: &amp;amp;str) -&amp;gt; bool {
    let mut is_palindrome: bool = true;
    for (c1, c2) in string.chars().zip(string.chars().rev()) {
        if c1 != c2 {
            is_palindrome = false;
        }
    }
    return is_palindrome;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;วิธีการทำงานจะเหมือนแนวคิดด้านบน นั้นคือสร้าง loop ทั้งคำ จากนั้นให้มี c1 และ c2 โดยที่ c1 ชี้ที่ด้านซ้ายสุด และ c2 ชี้ด้านขวาสุด โดยใน ภาษา rust นั้นการทำ indexing ใน string จะมีความท้าทาย ทางผู้เขียนจึงใช้วิธีสร้าง string ขึ้นมา 2 ตัว โดย ชุดแรกเป็นคำเดิม แต่ ชุดที่สอง จะเป็นคำที่กลับด้าน จากนั้นให้ c1 loop ผ่านชุดแรก และ c2 loop ผ่านชุดที่สอง&lt;/p&gt;

&lt;p&gt;และหากว่าทุกคำเท่ากัน จะถือว่าคำนั้นเป็น palindrome ด้วยการ return true ถือเป็นการจบกระบวนการเช็ค Palindrome&lt;/p&gt;

&lt;h2&gt;
  
  
  สรุปและต่อยอด
&lt;/h2&gt;

&lt;p&gt;โดยจริงแล้ว Palindrome จะเหมาะกับการแก้ปัญหาสิ่งที่เป็น sequence ต่อกันและสามารถ map เข้าหากันได้จากด้านหน้าและด้านหลัง ซึ่งวิธีการเช็ค Palindrome ในบทความนี้ต้องการนำเสนอ แนวคิดการเช็คแบบไล่ หัว-ท้าย โดยไม่ต้องตัดคำตรงกลางทิ้ง ทุกคนคิดเห็นอย่างไรมาแบ่งปันกันได้นะครับ&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;KubeOps Academy คือ Long-Term Program ที่อยากสร้าง Cloud Native จาก Zero to Workforce. หากสนใจกิจกรรมอื่นๆ ที่น่าสนใจ ของ Community สามารถติดตามต่อได้ที่ &lt;a href="https://www.facebook.com/kubeOpsSkills" rel="noopener noreferrer"&gt;KubeOps Skills&lt;/a&gt; ครับ&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>rust</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Short-Course Web-Development for none-technical people.</title>
      <dc:creator>(James) Kanin Kearpimy</dc:creator>
      <pubDate>Tue, 29 Jun 2021 08:41:00 +0000</pubDate>
      <link>https://dev.to/kaninkearpimy/short-course-web-development-for-none-technical-people-fe4</link>
      <guid>https://dev.to/kaninkearpimy/short-course-web-development-for-none-technical-people-fe4</guid>
      <description>&lt;h2&gt;
  
  
  Short-Course Web-Development for none-technical people.
&lt;/h2&gt;

&lt;p&gt;When we talk about web development, we might consider complex structure be-hide the scene. A lot of technical pieces of stuff like algorithms, mathematic, complex coding patterns. Yes but not at all, What if you have got challenges to incubate non-technical people for web development within 3 weeks! What do you prefer these people to learn? What do you expect them to grab out? and what does web development impact their career or daily life?&lt;/p&gt;

&lt;p&gt;I’m going to explain and share what I and my small study group, none-technical background, got through 3 weeks of web development.&lt;/p&gt;

&lt;h2&gt;
  
  
  My student background
&lt;/h2&gt;

&lt;p&gt;There are 5 students in my short class, Everyone has different but incredibly mixed and matched for courses.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;3 of them are Project Manager who, in daily life, work on tracking, planning, and negotiate with the technical team and customer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another one is UX/UI Designer who experienced web-design&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The rest is R&amp;amp;D Researcher who often involves in bringing new technology and innovation to the company.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Course commitment
&lt;/h2&gt;

&lt;p&gt;This offline course occurred every weekend for 3–5 hours (2 days per week), lasted 3 weeks. Every section is divided into lectures, mini-practical projects, and mentoring sessions every week.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Outline as listed below:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fundamental &amp;amp; Tool Installation&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Visual Studio Code Setup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Version Control Git&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Chrome Dev Tools&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HTML &amp;amp; CSS Fundamental&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Javascript Fundamental&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Grid &amp;amp; CSS Framework&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Grid System&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bootstrap&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Element &amp;amp; Component&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;RESTful API and Javascript for Application&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;POSTMAN&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Basic Network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RESTful API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JS for Application&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Practical Mini-Project&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Fundamental &amp;amp; Tool Installation
&lt;/h2&gt;

&lt;p&gt;We covered tools and foundations for a web developer. Breaking them down into 2 groups:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Tools: (Editor, Version Control, Debugging)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Visual Studio Code: A text editor with huge supportive extensions for the developer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Git with Github: Version Control.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Chrome Dev Tools: Debugging tool that covered necessary JS console components, HTML and CSS inspector, Network tracking, and Browser Storage.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frsc3v1r9dnftd7nm3v37.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frsc3v1r9dnftd7nm3v37.png" alt="Google Chrome Dev Tools" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Lesson Learn 1:&lt;/strong&gt; The most impression for my students is element inspector (not surprised) Because they can inspect element on page and grab style and structure to modify and re-create for themselves.&lt;br&gt;
 &lt;strong&gt;Lesson Learn 2:&lt;/strong&gt; Network tracking is quite boring at first but when it come to API session. My students really thank this tools as much. So, I prefer to underscore on how to read Request &amp;amp; Response while browser working on page.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;2. Basic Foundation: (HTML, CSS, Javascript)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This was my first challenge because of the limitation of time, background, and complex content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8762mzoxi1slmpfv83g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8762mzoxi1slmpfv83g.png" alt="Content that I and my students got through." width="800" height="796"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML (Hypertext Markup Language):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I tried to spread all tags out and teach only necessary tags and detail. Following the above picture. My student had learned 80% must-use tags of all web development in my experiences. We spent time on DIV tag first then explain it to others.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Lesson Learn 1:&lt;/strong&gt; HTML tag is a “blank tag with build-in style”. for example, p and h1 is likely to be the same if we cut off all css style. So, We can tell them concept, and let them learn which tag to apply on project building.&lt;br&gt;
 &lt;strong&gt;Lesson Learn 2:&lt;/strong&gt; Repeat word is quite helpful. My student got confused when I interchange between “tag attribute and tag property”. So, I changed my style to choose only one of them to express what we learn. It could reduce confusion well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;CSS (Cascading Style Sheets):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Actually, the selector is quite a challenge for the new learner if they can have the right vision on how to select elements, Other would be CSS styling. I break styles into 2 + 1 groups:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4f1zrwaludrcslhd96fx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4f1zrwaludrcslhd96fx.png" alt="CSS Selector" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dimension:&lt;/strong&gt; covering all pieces of stuff that could make element change their dimension and shape such as &lt;em&gt;width, height, margin, padding, and border&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Position:&lt;/strong&gt; All kinds of stuff that relate to positioning were explained here: float, display, flex, grid.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Font:&lt;/strong&gt; I added this section because a lot of projects need font decoration to be complete.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;JS (Javascript):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;HTML and CSS are intuitively understandable but Javascript. JS is quite a bit different. It is a programming language and needs a logical concept. My students often failed here. I’ve noticed that if one can “see” a pattern on it, can solve it. So, I change my teaching style. instead of looking at Javascript like computers do. I tried to teach my student to look at it as “Human” do.&lt;/p&gt;

&lt;p&gt;For example: to add an event listener to the button.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Computer:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Select button&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add function to the button&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;if a button clicked then …..&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Human:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Move your mouse to the button&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Left-click on the mouse&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the button is clicked.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your brain imagines that what would happen&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After my student can look like humans do then I teach them to **map Human to Computer. **As consequence, My student can understand how to work with javascript better (but they took more time to analyze the whole logic).&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Grid &amp;amp; CSS Framework:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;After the first week, my students struggled with how to &lt;strong&gt;position **HTML element. They mentioned **not precise&lt;/strong&gt; shape and position because of margin and padding. That was my intention. Because we were going to jump in the currently magical positioning style; Grid system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhy6aaflf0krtnnpczhy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhy6aaflf0krtnnpczhy.png" alt="The topic of Grid &amp;amp; CSS Framework" width="406" height="699"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Though We covered all required modern website should have: Responsive, Mobile Friendly, Reusable Component. Concentrating on Grid System was key to build up my student project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Lesson Learn 1:&lt;/strong&gt; Precisely positioning by pure margin and padding is really challenges for new learner. But If they did not experiences how hard it was. They would not know how useful of Grid.&lt;br&gt;
 &lt;strong&gt;Lesson Learn 2:&lt;/strong&gt; Build grid from scratch was quite challenge as well. So, I modified content to cover all concept of grid and let my student implement it by Bootstrap Grid system instead.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Grid is about how we look at elements and break them down into rows and columns. So, We spent 50% of the lesson on analyzing current elements on popular websites. How to shape it as Grid: row and column.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpaw4t8g95ntmoa85sauk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpaw4t8g95ntmoa85sauk.png" alt="Element Analysis for the grid system." width="749" height="617"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, We tried to cover some elements and components of Bootstrap. So, They can utilize it instantly for mini-project.&lt;/p&gt;

&lt;h2&gt;
  
  
  RESTful API
&lt;/h2&gt;

&lt;p&gt;In final lesson (before the final project) is about how UI (Frontend) communicates with a system (Backend). This is the most exciting because we try to track how popular websites send requests and responses (by chrome dev tool: network). My student learned how to use POSTMAN to send requests to the server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdpgo3lkaur7fe9jy999q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdpgo3lkaur7fe9jy999q.png" alt="Basic Client-Server" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What I designed is to build up backend API for event registration. My student has to request data from the first to last API sequentially. They must get unique data from one to use in another API.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Lesson Learn 1:&lt;/strong&gt; Everything about data is “Key and Value” in different form. JSON is Key:Value. On the other hand, Query string is key=value. So, If my students can understand this concept, they can map it to other type of sending data via API in future.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F105r2020sunyk66tvzr2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F105r2020sunyk66tvzr2.png" alt="Concept of data; Key, value" width="800" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Big Lesson Learn
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It is hard to explain how computers work by computer language. If your audience is normal people. So, Use normal language. Giving examples and compare them with things relating to their experiences is useful.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When it comes to HTML and CSS. They are what we can “see and touch”. But for Javascript, it, on the other hand, is quite a blinding area. SUDO Code could help here but have to be related to the audience's experiences.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Programming language likely relies on muscle memory. Explain the concept, give the example and let do a project on and on that could strengthen those muscles.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>webdev</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
