<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="https://recepinanc.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://recepinanc.com/" rel="alternate" type="text/html" /><updated>2022-02-21T14:54:07+00:00</updated><id>https://recepinanc.com/feed.xml</id><title type="html">Recep Inanc | Software Engineer</title><subtitle>Recep Inanc's Blog</subtitle><author><name>{&quot;name&quot;=&gt;nil, &quot;avatar&quot;=&gt;&quot;/assets/images/avatar.jpg&quot;, &quot;bio&quot;=&gt;&quot;Software Engineer &lt;strong&gt;@Amazon&lt;/strong&gt;&lt;br&gt;Previously &lt;strong&gt;@Sahibinden&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;\&quot;Verba Volant, Scripta Manent.\&quot;&lt;/i&gt;&quot;, &quot;location&quot;=&gt;nil, &quot;email&quot;=&gt;nil, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:recepinancc@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;GitHub&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-github&quot;, &quot;url&quot;=&gt;&quot;https://github.com/recepinanc&quot;}, {&quot;label&quot;=&gt;&quot;Twitter&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-twitter-square&quot;, &quot;url&quot;=&gt;&quot;https://twitter.com/recepinancc&quot;}, {&quot;label&quot;=&gt;&quot;Website&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;nil}, {&quot;label&quot;=&gt;&quot;Facebook&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-facebook-square&quot;}, {&quot;label&quot;=&gt;&quot;Instagram&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-instagram&quot;}]}</name></author><entry><title type="html">How to Read Technical Books Effectively</title><link href="https://recepinanc.com/How-to-read-technical-books-effectively/" rel="alternate" type="text/html" title="How to Read Technical Books Effectively" /><published>2022-02-19T00:00:00+00:00</published><updated>2022-02-19T00:00:00+00:00</updated><id>https://recepinanc.com/How%20to-read-technical-books-effectively</id><content type="html" xml:base="https://recepinanc.com/How-to-read-technical-books-effectively/">&lt;p&gt;My way of reading technical books effectively.&lt;/p&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;img src=&quot;/assets/images/content/technical_reading_header.jpg&quot; alt=&quot;How to read technical books effectively&quot; /&gt;&lt;figcaption&gt;
      Photo by Sincerely Media on Unsplash

    &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Reading a technical book is a lot different than reading a novel. That is why we need a different strategy to get the best out of technical books. I have been in the pursuit of a good reading technique for years now. I have tried to follow different approaches and finally, I was able to find a way that works for me well. In this post I will share my way of reading technical books in the most effective way.&lt;/p&gt;

&lt;h2 id=&quot;what-do-i-mean-by-effective&quot;&gt;What do I mean by “Effective”?&lt;/h2&gt;

&lt;p&gt;Actually, the use of the word “effective” here, depends on the type of the book. If the book is a “Reference” book, “effective” means after reading the book, I know where to look for answers. If it is not a reference book, “effective” means after reading the book, I learned the knowledge shared in the book.&lt;/p&gt;

&lt;p&gt;I think of Reference books as they are set of tools that I add up to my toolkit, and use whenever I need. I don’t have to carry all the tools I have with me, I will just “refer” to them when I need them.
On the other hand, I consider non-reference books as techniques that I actually learn. I do not have to spend extra effort to use them, I already have them with me all the time.&lt;/p&gt;

&lt;p&gt;Some of my favorite reference books:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.amazon.ca/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612&quot;&gt;Design Patterns: Elements of Reusable Object-Oriented Software&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.amazon.ca/Refactoring-Improving-Design-Existing-Code/dp/0134757599&quot;&gt;Refactoring: Improving the Design of Existing Code&lt;/a&gt;
You can also check &lt;a href=&quot;https://betterprogramming.pub/my-top-takeaways-from-refactoring-part-1-e802d81600aa&quot;&gt;My Top Takeaways from Refactoring&lt;/a&gt; here.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.amazon.ca/dp/B0096BYG7C&quot;&gt;Practical Object-Oriented Design in Ruby: An Agile Primer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some of my favorite non-reference books:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.amazon.ca/Pragmatic-Programmer-journey-mastery-Anniversary/dp/0135957052&quot;&gt;The Pragmatic Programmer: your journey to mastery&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.amazon.ca/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882&quot;&gt;Clean Code: A Handbook of Agile Software Craftsmanship&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;img src=&quot;/assets/images/content/technical_reading_strategy.jpg&quot; alt=&quot;How to read technical books effectively&quot; /&gt;&lt;figcaption&gt;
      Photo by Aaron Burden on Unsplash

    &lt;/figcaption&gt;&lt;/figure&gt;

&lt;h2 id=&quot;the-strategy&quot;&gt;The Strategy&lt;/h2&gt;

&lt;p&gt;Reading a technical book in one sitting might be overwhelming. Especially when you have no idea what is coming next as you read. When you don’t know how deep the rabbit hole will go, it makes you feel lost as you read and dive deeper into the concepts. The below strategy I developed over years is to overcome this struggle.&lt;/p&gt;

&lt;p&gt;Does not matter if you follow the upcoming step-by-step guide or not, it is crucial to keep in mind the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Understand the terminology.&lt;/strong&gt; If you encounter a term more than once, you need to make sure that you understand what it means. The more you encounter, the higher the chances of that term being important.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Know when to stop.&lt;/strong&gt; I have always thought to understand something I need to go as deep as possible on that topic. But that is not always very efficient. Sometimes you have to draw the line to stop dwelling on the theory and get into practicing (if applicable).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Review your notes.&lt;/strong&gt; Note taking is an important habit when it comes to reading a technical material - be it books or documents. And to make the most out of your notes you need to review them on a regular basis. This will help you internalize what you have learned from that book. And over time you will realize the need to review lessens.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are in mind, let’s get to my way of step-by-step reading a technical book efficiently.&lt;/p&gt;

&lt;h3 id=&quot;0-read-the-prefaceforeword&quot;&gt;0. Read the Preface/Foreword&lt;/h3&gt;
&lt;p&gt;Author’s of technical books usually include a very important part in these sections. They share “What is this book about?”, “Who should read it?”, “What each chapter explains?”, and sometimes even “How to Read?”. I find this information very useful before starting to read the book. Who could know the best way to read the book better than the author, right?&lt;/p&gt;

&lt;h3 id=&quot;1-scanning&quot;&gt;1. Scanning&lt;/h3&gt;

&lt;p&gt;I scan the chapter I am going to read. Scanning should be fast, and it should not take much of my time.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;I go over the titles,&lt;/li&gt;
  &lt;li&gt;I glance over the images,&lt;/li&gt;
  &lt;li&gt;I observe how long the chapter is and decide if I need to split it into smaller chunks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;2-skimming&quot;&gt;2. Skimming&lt;/h3&gt;

&lt;p&gt;Skimming is again faster than the actual reading but slower than scanning.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;I pay more attention on the subtitles, captioning of the images.&lt;/li&gt;
  &lt;li&gt;I read the first and last sentences of each paragraph.&lt;/li&gt;
  &lt;li&gt;I read the code snippets.&lt;/li&gt;
  &lt;li&gt;I try to get the main idea of each part and do not spend time on details.&lt;/li&gt;
  &lt;li&gt;I try to take mental notes of what might need more attention and what might not during the full reading phase. Please note that I use the term “mental” here because I do not want to spend time taking physical notes. It is way easier to remember “Yeah, this looks important” in your head than typing/writing “Pay attention to X”.&lt;/li&gt;
  &lt;li&gt;I do not linger. This is something I found important because it is easy to get started reading the whole thing as you try to skim.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;3-complete-reading&quot;&gt;3. Complete Reading&lt;/h3&gt;

&lt;p&gt;This is when the previous steps pay off.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I read the chapter completely.&lt;/li&gt;
  &lt;li&gt;I pay attention to the parts I took a mental note of during skimming.&lt;/li&gt;
  &lt;li&gt;I close the book and take notes in my own words. For me, it is usually hard than it sounds. But it is essential to use your own words. To describe what you’ve read you need to find the correct words, what do those words mean to you. And since you are taking notes you need to be able to summarize it. Sometimes as I write my notes I realize that I cannot find a word to describe it or even better start to question what I am writing down. This is a good indicator that I have not understood that concept in enough detail to internalize.&lt;/li&gt;
  &lt;li&gt;I write down my questions. I usually keep reading and collecting my questions with the hope that they might get answered as I read. If I could not answer my questions as I read the book, they will be my next topics to research.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;4-bonus&quot;&gt;4. Bonus!&lt;/h3&gt;

&lt;p&gt;Here’s the best part. If you are like me and spend some extra time when taking notes trying to make them look beautiful, with a few little adjustments you can publish them as a blog post!&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Everyone’s learning process is different, and this is mine. I wanted document it and share with you all. Who knows, someone with a similar learning process may find this post very useful! You can apply the ideas I share above to any technical material with a few little tweaks.&lt;/p&gt;</content><author><name>{&quot;name&quot;=&gt;nil, &quot;avatar&quot;=&gt;&quot;/assets/images/avatar.jpg&quot;, &quot;bio&quot;=&gt;&quot;Software Engineer &lt;strong&gt;@Amazon&lt;/strong&gt;&lt;br&gt;Previously &lt;strong&gt;@Sahibinden&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;\&quot;Verba Volant, Scripta Manent.\&quot;&lt;/i&gt;&quot;, &quot;location&quot;=&gt;nil, &quot;email&quot;=&gt;nil, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:recepinancc@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;GitHub&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-github&quot;, &quot;url&quot;=&gt;&quot;https://github.com/recepinanc&quot;}, {&quot;label&quot;=&gt;&quot;Twitter&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-twitter-square&quot;, &quot;url&quot;=&gt;&quot;https://twitter.com/recepinancc&quot;}, {&quot;label&quot;=&gt;&quot;Website&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;nil}, {&quot;label&quot;=&gt;&quot;Facebook&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-facebook-square&quot;}, {&quot;label&quot;=&gt;&quot;Instagram&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-instagram&quot;}]}</name></author><summary type="html">My way of reading technical books effectively.</summary></entry><entry><title type="html">Basics Of Consistency And Locking In Databases</title><link href="https://recepinanc.com/Basics-of-Consistency-and-Locking-in-Databases/" rel="alternate" type="text/html" title="Basics Of Consistency And Locking In Databases" /><published>2022-02-13T00:00:00+00:00</published><updated>2022-02-13T00:00:00+00:00</updated><id>https://recepinanc.com/Basics-of-Consistency-and-Locking-in-Databases</id><content type="html" xml:base="https://recepinanc.com/Basics-of-Consistency-and-Locking-in-Databases/">&lt;p&gt;Let’s learn about consistency, transaction isolation levels and locking in InnoDB.&lt;/p&gt;

&lt;h2 id=&quot;acid&quot;&gt;ACID&lt;/h2&gt;
&lt;p&gt;A database transaction is a unit of work performed in a database management system. Such as creating a record, updating a record, deleting a record and so on.&lt;/p&gt;

&lt;p&gt;ACID is an acronym that stands for Atomicity, Consistency, Isolation and Durability. These are the four properties of a reliable database transaction.&lt;/p&gt;

&lt;h2 id=&quot;c-for-consistency&quot;&gt;“C” for Consistency&lt;/h2&gt;
&lt;p&gt;This blog post focuses on the consistency aspect of database transactions.&lt;/p&gt;

&lt;p&gt;Consistency ensures data integrity intact at all times. Meaning, the database will be in a valid state at all times.&lt;/p&gt;

&lt;p&gt;Let’s imagine a shopping scenario to understand consistency better. The following may represent the steps to process such action:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;User adds item to cart&lt;/li&gt;
  &lt;li&gt;Item quantity checked&lt;/li&gt;
  &lt;li&gt;User pays for the item using their online wallet&lt;/li&gt;
  &lt;li&gt;Payment approved&lt;/li&gt;
  &lt;li&gt;Item quantity updated&lt;/li&gt;
  &lt;li&gt;User balance updated&lt;/li&gt;
  &lt;li&gt;Order processed&lt;/li&gt;
&lt;/ol&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Item ID&lt;/th&gt;
      &lt;th&gt;Price&lt;/th&gt;
      &lt;th&gt;Quantity&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;9&lt;/td&gt;
      &lt;td&gt;200.00&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Wallet ID&lt;/th&gt;
      &lt;th&gt;Balance&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;42&lt;/td&gt;
      &lt;td&gt;500.00&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Imagine these steps are part of a single database transaction. We expect a consistent database to be in this state once the transaction completes:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Item ID&lt;/th&gt;
      &lt;th&gt;Price&lt;/th&gt;
      &lt;th&gt;Quantity&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;9&lt;/td&gt;
      &lt;td&gt;200.00&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Wallet ID&lt;/th&gt;
      &lt;th&gt;Balance&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;42&lt;/td&gt;
      &lt;td&gt;300.00&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;This shows that database was never been in an invalid state. If consistency was not guaranteed we could have the database in such state:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Item ID&lt;/th&gt;
      &lt;th&gt;Price&lt;/th&gt;
      &lt;th&gt;Quantity&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;9&lt;/td&gt;
      &lt;td&gt;200.00&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Wallet ID&lt;/th&gt;
      &lt;th&gt;Balance&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;42&lt;/td&gt;
      &lt;td&gt;500.00&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Do you see the problem here? Database processed the order but for some reason the wallet balance is not changed. This is an inconsistent state for the database. And this inconsistency may damage our business.&lt;/p&gt;

&lt;h2 id=&quot;what-happens-at-different-level-of-consistency-lacks&quot;&gt;What happens at different level of Consistency lacks?&lt;/h2&gt;

&lt;p&gt;Three phenomena explain what might happen in case of a failed consistency guarantee.&lt;/p&gt;

&lt;p&gt;In databases “committing” means permanently saving the data in the database.&lt;/p&gt;

&lt;h3 id=&quot;1-dirty-reads&quot;&gt;1. Dirty Reads&lt;/h3&gt;
&lt;p&gt;Transaction T1 can read a not yet committed data from other transactions.&lt;/p&gt;

&lt;p&gt;Imagine the transaction for the above shopping to look like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1. BEGIN;
2. “User adds item to cart”
3. “Item quantity checked”
4. “User pays for the item using their online wallet”
5. “Payment approved”
6. “Item quantity updated”
7. “User balance updated”
8. “Order processed”
9. COMMIT;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now imagine that there’s only one item left in the stock.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;User 1 starts the transaction T1 goes through the steps 1 to 8.&lt;/li&gt;
  &lt;li&gt;Right after that User 2 tries to view the details of this item.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even though transaction T1 is not completed yet User 2 will see that  the item is out of stock.&lt;/p&gt;

&lt;p&gt;Now imagine for some reason T1 fails before committing. Now User 2 thought the item was out stock although User 1 could not buy the item.&lt;/p&gt;

&lt;h3 id=&quot;2-non-repeatable-reads&quot;&gt;2. Non-Repeatable Reads&lt;/h3&gt;
&lt;p&gt;Transaction T1 reads a row twice and gets different results. This might be because another transaction changed a value in the row or deleted the row.&lt;/p&gt;

&lt;h3 id=&quot;3-phantom-reads&quot;&gt;3. Phantom Reads&lt;/h3&gt;
&lt;p&gt;Transaction 1 executes the same read statement and see rows were not shown with the first read. This might be because another transaction inserted new rows that match T1’s read criteria.&lt;/p&gt;

&lt;p&gt;For our hypothetical example, we could avoid the issues shown above with a better design. There are also different isolation levels that brings different levels of consistency. Choosing an appropriate isolation level for our business is a critical decision.&lt;/p&gt;

&lt;h2 id=&quot;understanding-locks&quot;&gt;Understanding Locks&lt;/h2&gt;

&lt;p&gt;Before moving on with transaction isolation levels, let’s understand what different locks mean.&lt;/p&gt;

&lt;p&gt;Locking is all about achieving the promised level of consistency. To do so, each isolation level uses different locking methods based on their promise.&lt;/p&gt;

&lt;h3 id=&quot;shared-lock-s-lock&quot;&gt;Shared Lock (S Lock)&lt;/h3&gt;

&lt;p&gt;The transaction that holds the lock can read the row.&lt;/p&gt;

&lt;p&gt;If a transaction T1 holds a shared lock on row R:&lt;/p&gt;

&lt;p&gt;-Second transaction T2 can acquire an S lock on the row R.
They “share” the lock and both can read the row at the same time.&lt;/p&gt;

&lt;p&gt;-Second transaction T2 cannot acquire an X lock on the row R. 
T1 does not share the lock and prevents T2 from modifying the row R.&lt;/p&gt;

&lt;h3 id=&quot;exclusive-lock-x-lock&quot;&gt;Exclusive Lock (X Lock)&lt;/h3&gt;

&lt;p&gt;The transaction that holds the lock can update or delete the row.&lt;/p&gt;

&lt;p&gt;If a transaction T1 holds a exclusive lock on row R:&lt;/p&gt;

&lt;p&gt;-Second transaction T2 cannot acquire an S or an X lock on the row R. 
The lock belongs only to T1 until T1 releases it.&lt;/p&gt;

&lt;h3 id=&quot;non-locking-reads&quot;&gt;Non-Locking Reads&lt;/h3&gt;

&lt;p&gt;Non-Locking reads are the “SELECT” statements that does not put a lock on the rows. These are plain “SELECT” statements in the form of “SELECT … FROM …”. They do not guarantee consistency.&lt;/p&gt;

&lt;h3 id=&quot;locking-reads&quot;&gt;Locking Reads&lt;/h3&gt;

&lt;p&gt;Locking reads are the “SELECT” statements that puts a lock on the rows to prevent others from changing them.&lt;/p&gt;

&lt;h3 id=&quot;record-lock&quot;&gt;Record Lock&lt;/h3&gt;

&lt;p&gt;A record lock is a lock only on the index record. This lock prevents others from modifying that record.&lt;/p&gt;

&lt;h3 id=&quot;gap-lock&quot;&gt;Gap Lock&lt;/h3&gt;

&lt;p&gt;Gap Locks are set on a gap between index records. It is to prevent other transactions from inserting new rows into the locked gap.&lt;/p&gt;

&lt;p&gt;Gap locks are a part of the next-key lock. InnoDB uses locks the related gaps to make sure we do not encounter phantom rows in the range we are working on.&lt;/p&gt;

&lt;h3 id=&quot;next-key-lock&quot;&gt;Next-Key Lock&lt;/h3&gt;

&lt;p&gt;Next-key locks are combination of record locks and gap-locks. A record lock on the record and a gap lock is set in the range we do not want to be effected by another transaction. This might be the gap before and/or after the record we are dealing with.&lt;/p&gt;

&lt;h2 id=&quot;transaction-isolation-levels&quot;&gt;Transaction Isolation Levels&lt;/h2&gt;

&lt;p&gt;Transaction isolation levels are like presets with different levels of consistency-performance trade-offs.&lt;/p&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;img src=&quot;/assets/images/content/transaction_isolation_levels.jpg&quot; alt=&quot;Transaction Isolation Levels on Consistency-Performance Scale&quot; /&gt;&lt;figcaption&gt;
      Transaction Isolation Levels on Consistency-Performance Scale

    &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Different transaction isolation levels solve different problems.&lt;/p&gt;

&lt;h3 id=&quot;read-uncommitted&quot;&gt;Read Uncommitted&lt;/h3&gt;
&lt;p&gt;At this level, transaction isolation is at the lowest - they are not isolated and no locks are set when at this level. Each transaction will read the latest change by other transactions. Even though those changes are not committed yet. This may result in dirty reads.&lt;/p&gt;

&lt;h3 id=&quot;read-committed&quot;&gt;Read Committed&lt;/h3&gt;
&lt;p&gt;At this level, transactions only read only the committed changes by other transactions. This level only prevents dirty reads.&lt;/p&gt;

&lt;p&gt;For “SELECT … FOR UPDATE”, “SELECT … FOR SHARE”, “UPDATE” and “DELETE” statements InnoDB locks the index records. This is to prevent other transactions from modifying those rows.&lt;/p&gt;

&lt;h3 id=&quot;repeatable-read&quot;&gt;Repeatable Read&lt;/h3&gt;

&lt;p&gt;This is the default transaction isolation level for InnoDB.&lt;/p&gt;

&lt;p&gt;At this level, the reads inside a transaction are consistent. The transaction takes a snapshot of the current state with the first read and uses that through out the transaction. This ensures that all reads can be repeated in the same transaction, thus the name Repeatable-Read. This level prevents dirty reads and non-repeatable reads.&lt;/p&gt;

&lt;p&gt;At this level, InnoDB uses next-key locks for searches and index scans. Next-key locks prevents Phantom Reads. It is important to note that this level guarantees no phantom rows only for “Read” operations. An “UPDATE” to all the records in the table would take effect on “all the committed rows”. This includes the ones from other transactions - those are phantom rows. This means Phantom Rows can still appear at this level.&lt;/p&gt;

&lt;h3 id=&quot;serializable&quot;&gt;Serializable&lt;/h3&gt;
&lt;p&gt;At this level, transactions are completely isolated from each other. This prevents dirty reads, non-repeatable reads and phantom reads.&lt;/p&gt;

&lt;p&gt;As we can see each transaction isolation levels solve different problems. The way we achieve isolation is through the use of different locking mechanisms.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;When understanding locks in databases we need to keep in mind that the purpose is to provide a certain level of consistency. And as the saying goes, there is no such thing as a free lunch. To get more consistency we are going to need to add more locks, more locks mean more overhead, thus loss in performance. To be able to choose an appropriate solution, we must understand the needs of our system.&lt;/p&gt;</content><author><name>{&quot;name&quot;=&gt;nil, &quot;avatar&quot;=&gt;&quot;/assets/images/avatar.jpg&quot;, &quot;bio&quot;=&gt;&quot;Software Engineer &lt;strong&gt;@Amazon&lt;/strong&gt;&lt;br&gt;Previously &lt;strong&gt;@Sahibinden&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;\&quot;Verba Volant, Scripta Manent.\&quot;&lt;/i&gt;&quot;, &quot;location&quot;=&gt;nil, &quot;email&quot;=&gt;nil, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:recepinancc@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;GitHub&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-github&quot;, &quot;url&quot;=&gt;&quot;https://github.com/recepinanc&quot;}, {&quot;label&quot;=&gt;&quot;Twitter&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-twitter-square&quot;, &quot;url&quot;=&gt;&quot;https://twitter.com/recepinancc&quot;}, {&quot;label&quot;=&gt;&quot;Website&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;nil}, {&quot;label&quot;=&gt;&quot;Facebook&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-facebook-square&quot;}, {&quot;label&quot;=&gt;&quot;Instagram&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-instagram&quot;}]}</name></author><summary type="html">Let’s learn about consistency, transaction isolation levels and locking in InnoDB.</summary></entry><entry><title type="html">My Top Takeaways From Refactoring: Part 2</title><link href="https://recepinanc.com/My-Top-Takeaways-from-Refactoring-Part-2/" rel="alternate" type="text/html" title="My Top Takeaways From Refactoring: Part 2" /><published>2022-01-29T00:00:00+00:00</published><updated>2022-01-29T00:00:00+00:00</updated><id>https://recepinanc.com/My-Top-Takeaways-from-Refactoring:-Part%202</id><content type="html" xml:base="https://recepinanc.com/My-Top-Takeaways-from-Refactoring-Part-2/">&lt;p&gt;Let’s talk about the principles of refactoring!&lt;/p&gt;

&lt;p&gt;In this series, I share my top takeaways from the book &lt;a href=&quot;https://www.amazon.ca/Refactoring-Improving-Design-Existing-Code/dp/0134757599&quot;&gt;Refactoring by Kent Beck and Martin Fowler&lt;/a&gt;. I definitely recommend reading the book to anyone interested in learning more about refactoring.&lt;/p&gt;

&lt;p&gt;In &lt;a href=&quot;https://recepinanc.com/My-Top-Takeaways-from-Refactoring-Part-1/&quot;&gt;Part 1&lt;/a&gt; of this series we took a glance at refactoring in a more general sense. In Part 2, we will look at when and why to do refactoring and some more guidance on how to do refactoring.&lt;/p&gt;

&lt;h1 id=&quot;chapter-2---principles-in-refactoring&quot;&gt;Chapter 2 - Principles in Refactoring&lt;/h1&gt;

&lt;p&gt;In Chapter 2, Martin Fowler shares the definition of refactoring as:&lt;/p&gt;

&lt;p&gt;“A change made to the internal structure of software to make it easier to understand and cheaper to modify without breaking its observable behavior”.&lt;/p&gt;

&lt;p&gt;The term “observable behavior” refers to the public interface of the software. An example to that would be the public methods of a class that other classes call to interact with it. The definition makes the purpose of refactoring clear again. It is to make software easier to understand and restructure in a way that making a change is easier.&lt;/p&gt;

&lt;p&gt;Which takes us to our first takeaway.&lt;/p&gt;

&lt;h2 id=&quot;1-refactoring-should-be-economic&quot;&gt;1. Refactoring should be Economic&lt;/h2&gt;

&lt;p&gt;I love cleaning/restructuring a piece of code! The proud feeling I get looking back at the changes is inexplicable. That’s why this was a good realization for me that we refactor for economic reasons. We should refactor not only for the beauty of the outcome but for the economic benefits we get in the long-term.&lt;/p&gt;

&lt;p&gt;Martin Fowler mentions, we are professionals and responsible for getting the job done. And refactoring is an amazing tool that helps us achieve this goal as efficient as possible.&lt;/p&gt;

&lt;h2 id=&quot;2-refactoring-is-a-judgement-call&quot;&gt;2. Refactoring is a Judgement Call&lt;/h2&gt;

&lt;p&gt;If we were to list those:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Improving the design of the software,&lt;/li&gt;
  &lt;li&gt;Making software easier to understand,&lt;/li&gt;
  &lt;li&gt;Finding bugs in the software,&lt;/li&gt;
  &lt;li&gt;Increasing the development speed…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Last one in the above list may sound contradictory to some people. Because they consider refactoring as “more work”. This might only be true for some cases where the actual change is so small. But it is important to remember that refactoring pays dividends in the long-term.&lt;/p&gt;

&lt;p&gt;So it is usually a judgement call we need to make “to refactor or not to refactor”. The ability to make the right calls will develop over time as we face more of them in our career. As a starting point for making these decisions the book mentions the “The Rule of Three” by Don Roberts:&lt;/p&gt;

&lt;p&gt;“The first time you do something, you just do it. The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway. The third time you do something similar, you refactor”.&lt;/p&gt;

&lt;h2 id=&quot;3-identify-opportunities-to-refactor&quot;&gt;3. Identify Opportunities to Refactor&lt;/h2&gt;

&lt;p&gt;How do we find the correct time to refactor? We need to learn to identify those certain occasions that suits well for refactoring.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;When adding a new feature or fixing a bug. Why? It is easier to do  any modification on a well-structured code base.&lt;/li&gt;
  &lt;li&gt;When trying to understand a piece of code. Why? Renaming for the better, untangling the dependencies gives us a clear picture.&lt;/li&gt;
  &lt;li&gt;When we came across a piece of code that could do what is doing better. Why? Well, because “Always leave the campground cleaner than you found it.”.&lt;/li&gt;
  &lt;li&gt;When doing code reviews. Why? It is a good opportunity to share some perspective with your colleagues. This may not be suitable for the pull-request type of code review since that process takes longer. It is more appropriate when doing pair-programming and you can discuss the suggestions.&lt;/li&gt;
  &lt;li&gt;Having a planned refactoring time. Why? In some cases - usually for the ones involving a legacy code base - refactoring may not be an easy thing to do. For such cases, planning ahead of time to pay the debt of the previous development decisions is a good call.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;4-the-two-hats-metaphor--wear-only-one-hat-at-all-times&quot;&gt;4. The Two Hats Metaphor / Wear Only One Hat At All Times&lt;/h2&gt;

&lt;p&gt;The book mentions a good metaphor “The Two Hats” (by Kent Beck) for the way Martin Fowler does refactoring.&lt;/p&gt;

&lt;p&gt;It represents dividing the development time when using refactoring into two. One hat for adding a new functionality and the other for refactoring.&lt;/p&gt;

&lt;p&gt;When we put on the first hat, we should focus on adding the new functionality (and its tests, please) only. We should not be making any changes to the existing code.&lt;br /&gt;
When we put on the second hat, we should focus on restructuring the existing code and keeping the tests pass. We should not add any new functionality (not even new tests).&lt;/p&gt;

&lt;p&gt;We may keep switching the hats during the development process. But remembering which hat is currently on is essential.&lt;/p&gt;

&lt;p&gt;Kent Beck shares this note about The Two Hats:&lt;/p&gt;

&lt;p&gt;“Once the refactoring hat is on, note the things you think are not right about the code, but resist the temptation to change it right now, the code should be doing exactly the same thing after you’re done refactoring. Then, you can switch your hat and go back to fixing the implementation.”&lt;/p&gt;

&lt;p&gt;The book mentions great ideas for dealing with the common problems of refactoring. These problems include:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;How do we not let it slow down development,&lt;/li&gt;
  &lt;li&gt;How should we arrange our code ownership for a suitable environment for refactoring,&lt;/li&gt;
  &lt;li&gt;How do we deal with legacy code base,&lt;/li&gt;
  &lt;li&gt;How to make use of branches in the version control systems,&lt;/li&gt;
  &lt;li&gt;How to deal with database involving refactorings.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will not go into the details of these ideas. It is better to use them as a reference and refer to those sections when we face those problems.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;Thank you for reading, that’s all for Part 2! I hope you find these points as useful as I do. And, stay tuned for Part 3!&lt;/p&gt;</content><author><name>{&quot;name&quot;=&gt;nil, &quot;avatar&quot;=&gt;&quot;/assets/images/avatar.jpg&quot;, &quot;bio&quot;=&gt;&quot;Software Engineer &lt;strong&gt;@Amazon&lt;/strong&gt;&lt;br&gt;Previously &lt;strong&gt;@Sahibinden&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;\&quot;Verba Volant, Scripta Manent.\&quot;&lt;/i&gt;&quot;, &quot;location&quot;=&gt;nil, &quot;email&quot;=&gt;nil, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:recepinancc@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;GitHub&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-github&quot;, &quot;url&quot;=&gt;&quot;https://github.com/recepinanc&quot;}, {&quot;label&quot;=&gt;&quot;Twitter&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-twitter-square&quot;, &quot;url&quot;=&gt;&quot;https://twitter.com/recepinancc&quot;}, {&quot;label&quot;=&gt;&quot;Website&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;nil}, {&quot;label&quot;=&gt;&quot;Facebook&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-facebook-square&quot;}, {&quot;label&quot;=&gt;&quot;Instagram&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-instagram&quot;}]}</name></author><summary type="html">Let’s talk about the principles of refactoring!</summary></entry><entry><title type="html">My Top Takeaways From Refactoring: Part 1</title><link href="https://recepinanc.com/My-Top-Takeaways-from-Refactoring-Part-1/" rel="alternate" type="text/html" title="My Top Takeaways From Refactoring: Part 1" /><published>2022-01-22T00:00:00+00:00</published><updated>2022-01-22T00:00:00+00:00</updated><id>https://recepinanc.com/My-Top-Takeaways-from-Refactoring:-Part%201</id><content type="html" xml:base="https://recepinanc.com/My-Top-Takeaways-from-Refactoring-Part-1/">&lt;p&gt;As software developers we should embrace change. Frameworks change, requirements change, expectations change… Incorporating  those changes into the existing code base is not always easy. But, writing clean and well-structured code will make it easier for your future self.&lt;/p&gt;

&lt;p&gt;As developers and designer, or even as humans, we do not always make the best decision in the beginning. Sometimes it helps to see where this journey is taking us and then we revise our previous decisions. The more considerate we are for those future revisions the easier it will be to apply them when the time comes. It is almost always the case for software development. Refactoring is the way we revise our past decisions for our software.&lt;/p&gt;

&lt;p&gt;I would like to share my top takeaways from the book &lt;a href=&quot;https://www.amazon.ca/Refactoring-Improving-Design-Existing-Code/dp/0134757599&quot;&gt;Refactoring by Kent Beck and Martin Fowler&lt;/a&gt;. The book shares invaluable practical ideas about refactoring. There is also a catalog of many refactoring techniques illustrated with amazing examples. Definitely recommend reading the book to anyone interested in learning more about refactoring.&lt;/p&gt;

&lt;h1 id=&quot;chapter-1---refactoring-a-first-example&quot;&gt;Chapter 1 - Refactoring, a First Example&lt;/h1&gt;

&lt;p&gt;The first chapter is an example of refactoring in action. It justifies the actions taken and shares many useful rule of thumbs.&lt;/p&gt;

&lt;h2 id=&quot;1-aim-to-embrace-change&quot;&gt;1. Aim to Embrace Change&lt;/h2&gt;

&lt;p&gt;The idea that the software we code is dynamic brings the implicit necessity to change. To apply the next change with ease we first need to have a good structure in place. Refactoring aims to improve structure of the code without effecting any observable functionality.&lt;/p&gt;

&lt;h2 id=&quot;2-make-sure-you-have-enough-tests-before-refactoring&quot;&gt;2. Make Sure You Have Enough Tests Before Refactoring&lt;/h2&gt;

&lt;p&gt;When refactoring the code we want to make sure the software keeps working as expected. The best way to achieve this is with the help of a good set of tests. Tests ensure that no matter what we change the functionality remains the same. We must make sure that our tests cover the areas we touch during refactoring. If they do not, we must stop now, and start adding those tests before even starting to rename a single method.&lt;/p&gt;

&lt;h2 id=&quot;3-refactor-in-small-steps&quot;&gt;3. Refactor in Small Steps&lt;/h2&gt;

&lt;p&gt;Refactoring may break things and this is why we wrote the tests first, right? Right? Okay. We should make changes in steps as small as possible and test those changes. This way we know what and when we messed up and it is easier to revert as our step was small.&lt;/p&gt;

&lt;h2 id=&quot;4-have-a-system-refactor-test-commit&quot;&gt;4. Have a System: Refactor, Test, Commit&lt;/h2&gt;

&lt;p&gt;No matter how careful we are, having a system when refactoring will help with the process.&lt;/p&gt;

&lt;p&gt;When you refactor, you refactor in small steps. You test your change. Finally, you commit that change into your favorite version control system. Now you have a clear history of well tested changes! Thanks to this process, you can:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Revert to any of those commits with 100% confidence,&lt;/li&gt;
  &lt;li&gt;Stop whenever you like and release any commit and it will be an improvement, and,&lt;/li&gt;
  &lt;li&gt;You can squash those tiny commits into a larger more meaningful commits for a good looking history!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;5-first-refactor-then-extend&quot;&gt;5. First Refactor, Then Extend&lt;/h2&gt;

&lt;p&gt;Refactoring before adding a new functionality will help with the thought process. And leaving the code base better than you have found it is a bonus!&lt;/p&gt;

&lt;h2 id=&quot;6-use-descriptive-names-when-renaming&quot;&gt;6. Use Descriptive Names when Renaming&lt;/h2&gt;

&lt;p&gt;Renaming is a crucial technique in refactoring. Renaming variables, renaming methods, renaming classes… The point of renaming should be to use descriptive names that saves us time. A good name for a variable saves us from reading how it got here to understand what value it holds. A good name for a method saves us from reading its entire implementation to understand what it does. A good name for a class saves us from reading its entirety to understand its responsibility.&lt;/p&gt;

&lt;p&gt;Spending a good amount of time and effort to choose a name is at the heart of refactoring. Otherwise, what would be the point of splitting a large method if we still had to read the smaller ones?&lt;/p&gt;

&lt;h2 id=&quot;7-keep-an-eye-on-performance-when-refactoring&quot;&gt;7. Keep an Eye on Performance when Refactoring&lt;/h2&gt;

&lt;p&gt;Performance might get effected during the refactoring process. Even if it does, it usually does in small scales with no significant loss. But, it is a good habit to take note of possible performance degrading points. After completing refactoring, we should review those points and fine tune for performance. It is going to be easier to fine tune as the code base will have a better structure at the end of refactoring.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;Thanks for reading, that’s all for Chapter 1! I hope you find these points useful as I do. And, stay tuned for Chapter 2!&lt;/p&gt;</content><author><name>{&quot;name&quot;=&gt;nil, &quot;avatar&quot;=&gt;&quot;/assets/images/avatar.jpg&quot;, &quot;bio&quot;=&gt;&quot;Software Engineer &lt;strong&gt;@Amazon&lt;/strong&gt;&lt;br&gt;Previously &lt;strong&gt;@Sahibinden&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;\&quot;Verba Volant, Scripta Manent.\&quot;&lt;/i&gt;&quot;, &quot;location&quot;=&gt;nil, &quot;email&quot;=&gt;nil, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:recepinancc@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;GitHub&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-github&quot;, &quot;url&quot;=&gt;&quot;https://github.com/recepinanc&quot;}, {&quot;label&quot;=&gt;&quot;Twitter&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-twitter-square&quot;, &quot;url&quot;=&gt;&quot;https://twitter.com/recepinancc&quot;}, {&quot;label&quot;=&gt;&quot;Website&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;nil}, {&quot;label&quot;=&gt;&quot;Facebook&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-facebook-square&quot;}, {&quot;label&quot;=&gt;&quot;Instagram&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-instagram&quot;}]}</name></author><summary type="html">As software developers we should embrace change. Frameworks change, requirements change, expectations change… Incorporating those changes into the existing code base is not always easy. But, writing clean and well-structured code will make it easier for your future self.</summary></entry><entry><title type="html">Docker Networking Explained With Example</title><link href="https://recepinanc.com/docker-networking-explained-with-example/" rel="alternate" type="text/html" title="Docker Networking Explained With Example" /><published>2021-03-09T00:00:00+00:00</published><updated>2021-03-09T00:00:00+00:00</updated><id>https://recepinanc.com/docker-networking-explained-with-example</id><content type="html" xml:base="https://recepinanc.com/docker-networking-explained-with-example/">&lt;p&gt;Most of our applications in production are multi-container applications. In a multi-container application, two or more containers work together as one to create a properly functioning application.&lt;/p&gt;

&lt;p&gt;Imagine a web application with a backend, frontend, and database components that are all dockerized and work together to bring the web application to life! But how does the communication between these containers work?&lt;/p&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;img src=&quot;/assets/images/content/multi-container-app-visualized.png&quot; alt=&quot;Multi-Container Application Illustration&quot; /&gt;&lt;figcaption&gt;
      Multi-Container Application Illustration

    &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;This post explains how multiple containers on a single host communicate with each other to form a properly functioning application. The term &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;container networking&lt;/code&gt; is examined on a Spring Boot application that uses Redis as the data store.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Please check out &lt;a href=&quot;https://github.com/recepinanc/springbootredis&quot;&gt;GitHub&lt;/a&gt; for the source code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;img src=&quot;/assets/images/content/springboot_redis_docker_networking.png&quot; alt=&quot;Dockerized Spring Boot with Redis Demo Project Overview&quot; /&gt;&lt;figcaption&gt;
      Dockerized Spring Boot with Redis Demo Project Overview

    &lt;/figcaption&gt;&lt;/figure&gt;

&lt;h1 id=&quot;container-networking&quot;&gt;Container Networking&lt;/h1&gt;

&lt;p&gt;By default, containers are isolated from each other by any means. But when it comes to communication, there’s a simple rule to that:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If two containers are on the same network, they can talk to each other. If they are not on the same network, then they can not talk to each other.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When we run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker network ls&lt;/code&gt; we get a similar response to the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;NETWORK ID     NAME      DRIVER    SCOPE
878992be35ab   bridge    bridge    local
67416f902106   host      host      local
141ad47583f3   none      null      local
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When we compose our application and then check with the same command, we will see an additional line in the response:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;NETWORK ID     NAME                   DRIVER    SCOPE
878992be35ab   bridge                 bridge    local
67416f902106   host                   host      local
141ad47583f3   none                   null      local
fccef87cd248   spring-redis_default   bridge    local
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When we get our application up and running, we also created a separate network for our containers to communicate through. But how do we that?&lt;/p&gt;

&lt;h1 id=&quot;docker-compose-networking&quot;&gt;Docker Compose Networking&lt;/h1&gt;

&lt;p&gt;There are different ways to create a network for our containers to use. In our example, we use docker-compose to build and run our containers. When we call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker-compose up&lt;/code&gt; to start up our application, docker-compose creates a network, creates containers, and adds them to the network for services defined in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker-compose.yml&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;version: &quot;3.9&quot;
services:
    web:
        build: ./springboot
        ports:
            - &quot;8888:8080&quot;
    containerizedredis:
        build: ./redis
        image: &quot;redis:alpine&quot;
        ports:
            - &quot;16378:16379&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When we run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker-compose up&lt;/code&gt; providing the above configuration, what compose does is:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Create a new network and give it a default name (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spring-redis_default&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;As my “web” service, create a container using the configuration at ./springboot and add it to the network&lt;/li&gt;
  &lt;li&gt;As my “containerizedredis” service, create a container using the configuration at ./redis and add it to the network&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;The network name is set based on the directory name of your application. For example: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spring-redis&lt;/code&gt; is the name of my directory and the network is called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spring-redis_deafult&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;inspecting-the-network&quot;&gt;Inspecting the Network&lt;/h1&gt;

&lt;p&gt;When our application is up and running, we can inspect the network to see that our containers have joined the network. To do so we are going to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker network inspect spring-redis_default&lt;/code&gt; command.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;Containers&quot;: {
    &quot;ec23f91b6ab55e202080da5b62d8cf4c44f60001aebc618a410d279d915c674d&quot;: {
        &quot;Name&quot;: &quot;spring-redis_web_1&quot;,
        &quot;EndpointID&quot;: &quot;ba1753bcbdda6bbfda126b99223f2690155e0f80a7c57df53c5c04857f9e03c0&quot;,
        &quot;MacAddress&quot;: &quot;02:42:ac:12:00:02&quot;,
        &quot;IPv4Address&quot;: &quot;172.18.0.2/16&quot;,
        &quot;IPv6Address&quot;: &quot;&quot;
    },
    &quot;f02034324ffeaf8f4483265a3c0663e24f3982835512d4a5cf6c56e523ad6e4b&quot;: {
        &quot;Name&quot;: &quot;spring-redis_containerizedredis_1&quot;,
        &quot;EndpointID&quot;: &quot;1d148a1d0889a863e4cf506ea985c1149df6e7ba2f0fedba4a4607565067aea7&quot;,
        &quot;MacAddress&quot;: &quot;02:42:ac:12:00:03&quot;,
        &quot;IPv4Address&quot;: &quot;172.18.0.3/16&quot;,
        &quot;IPv6Address&quot;: &quot;&quot;
    }
},
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What we are looking for in the output is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Containers&lt;/code&gt; section. Here we can see that both of our containers (for redis and spring-boot) are joined to the network and now are able to communicate with each other!&lt;/p&gt;

&lt;h1 id=&quot;bridge-network&quot;&gt;Bridge Network&lt;/h1&gt;

&lt;p&gt;By default, a network called Docker Bridge Network is created, and all the containers are connected to that network if any other network is specified. Each container gets an internal IP address, and now all containers in that bridge can speak to one another. This provides an isolated network to the containers that live in a single host.&lt;/p&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;img src=&quot;/assets/images/content/docker-bridge-network.png&quot; alt=&quot;Docker Bridge Network Illustration&quot; /&gt;&lt;figcaption&gt;
      Docker Bridge Network Illustration

    &lt;/figcaption&gt;&lt;/figure&gt;

&lt;blockquote&gt;
  &lt;p&gt;There are other network drivers such as Host and Overlay. By default, docker-compose creates a bridge network if any other driver is specified. Having a user-defined bridge network is better for isolation since all new containers are bound automatically when created without a “–network” flag.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;discoverability-of-containers&quot;&gt;Discoverability of Containers&lt;/h1&gt;

&lt;p&gt;In our case, our Spring Boot and Redis containers talk to each other to exchange information. They are already in the same network and have their IP addresses but, our Spring Boot Application is not using a static IP address to reach to Redis container but instead, it uses a hostname &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;containerizedredis&lt;/code&gt;. Containers, like all other machines, use IP addresses at the end to communicate over the internet. The name “containerizedredis” is resolved to an IP address thanks to an A record created for it. We can examine the record with the help of another container that includes lots of useful debugging tools called &lt;a href=&quot;https://github.com/nicolaka/netshoot&quot;&gt;nicolaka/netshoot&lt;/a&gt;. We will assign it to our new network “spring-redis_default” and run the container in interactive mode.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker run -it --network spring-redis_default nicolaka/netshoot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now let’s check out the record with the name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;containerizedredis&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ dig containerizedredis

; &amp;lt;&amp;lt;&amp;gt;&amp;gt; DiG 9.16.11 &amp;lt;&amp;lt;&amp;gt;&amp;gt; containerizedredis
;; global options: +cmd
;; Got answer:
;; -&amp;gt;&amp;gt;HEADER&amp;lt;&amp;lt;- opcode: QUERY, status: NOERROR, id: 62165
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;containerizedredis.		IN	A

;; ANSWER SECTION:
containerizedredis.	600	IN	A	172.18.0.3

;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Sat Mar 06 10:20:39 UTC 2021
;; MSG SIZE  rcvd: 70
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can see in the response that there’s an A record for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;containerizedredis&lt;/code&gt; and it is resolved to an IP address &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;172.18.0.3&lt;/code&gt;. This means that whenever our Spring Boot application tries to access the host &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;containerizedredis&lt;/code&gt; it is directed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;172,18.0.3&lt;/code&gt;.&lt;/p&gt;

&lt;h1 id=&quot;exposing-ports&quot;&gt;Exposing Ports&lt;/h1&gt;

&lt;p&gt;Exposing the ports is not needed for the container to container communication. Exposing a port of a container means that the port is open to anyone as long as the host allows. Now that our containers can communicate with each other in an isolated environment, finally, it is time we talk to them.&lt;/p&gt;

&lt;p&gt;In Docker Compose files, we define ports we want to expose with the following format: “HOST_PORT:CONTAINER_PORT”.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HOST_PORT&lt;/code&gt; is used when we want to specify which port to use to access the container from the host.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CONTAINER_PORT&lt;/code&gt; is used for container-to-container communication between services.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example in our docker-compose.yml file, we set our ports as follows:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;version: &quot;3.9&quot;
services:
    web:
        build: ./springboot
        ports:
            - &quot;8888:8080&quot;
    containerizedredis:
        build: ./redis
        image: &quot;redis:alpine&quot;
        ports:
            - &quot;16379&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here what we say is that:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Let the containers created with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;web&lt;/code&gt; service configuration communicate with other containers in the same network over its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;8080&lt;/code&gt; port, and let anyone reach out to these containers from the host’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;8888&lt;/code&gt; port.&lt;/li&gt;
  &lt;li&gt;Let the containers created with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;containerizedredis&lt;/code&gt; service configuration communicate with other containers in the same network over its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;16379&lt;/code&gt; port, and it is not important which host port is assigned for outside communication.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So when we run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker ps&lt;/code&gt; what we see should be similar to what we have here:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS          PORTS                                NAMES
8f5b4ce0bf18   spring-redis_web   &quot;java -jar /app.jar&quot;     18 minutes ago   Up 18 minutes   0.0.0.0:8888-&amp;gt;8080/tcp               spring-redis_web_1
804581c50507   redis:alpine       &quot;docker-entrypoint.s…&quot;   18 minutes ago   Up 18 minutes   6379/tcp, 0.0.0.0:55000-&amp;gt;16379/tcp   spring-redis_containerizedredis_1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spring-redis_web_1&lt;/code&gt;, port 8080 is exposed, and 0.0.0.0:8888 on the host machine accepts the requests and delivers them to the container.
For &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spring-redis_containerizedredis_1&lt;/code&gt;, port 1679 is exposed and 55000 is given arbitrarily to deliver requests to that port on the host machine to the container.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;You may ask why the port &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;6379&lt;/code&gt; is listed to be exposed for redis container, even though we have not done it ourselves, it is because the redis:alpine image we use to build our container has the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EXPOSE 6379&lt;/code&gt; line in its &lt;a href=&quot;https://hub.docker.com/layers/redis/library/redis/alpine/images/sha256-10d07ea2c72bc9f6e417cefb8638ee6b018f6977128599533bb340ce5f441631?context=explore&quot;&gt;Dockerfile&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;show-time&quot;&gt;Show Time!&lt;/h1&gt;

&lt;p&gt;Apparently, the encoding of Java’s UUID on the redis-server side was a bit weird, but you get the idea.&lt;/p&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;img src=&quot;/assets/images/content/docker-networking-demo.gif&quot; alt=&quot;Docker Networking Demonstration&quot; /&gt;&lt;figcaption&gt;
      Docker Networking Demonstration

    &lt;/figcaption&gt;&lt;/figure&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.docker.com/network/&quot;&gt;https://docs.docker.com/network/&lt;/a&gt;
&lt;a href=&quot;https://docs.docker.com/compose/networking/&quot;&gt;https://docs.docker.com/compose/networking/&lt;/a&gt;
&lt;a href=&quot;https://www.youtube.com/watch?v=PpyPa92r44s&quot;&gt;https://www.youtube.com/watch?v=PpyPa92r44s&lt;/a&gt;
&lt;a href=&quot;https://www.youtube.com/watch?v=Yr6-2ddhLVo&quot;&gt;https://www.youtube.com/watch?v=Yr6-2ddhLVo&lt;/a&gt;&lt;/p&gt;</content><author><name>{&quot;name&quot;=&gt;nil, &quot;avatar&quot;=&gt;&quot;/assets/images/avatar.jpg&quot;, &quot;bio&quot;=&gt;&quot;Software Engineer &lt;strong&gt;@Amazon&lt;/strong&gt;&lt;br&gt;Previously &lt;strong&gt;@Sahibinden&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;\&quot;Verba Volant, Scripta Manent.\&quot;&lt;/i&gt;&quot;, &quot;location&quot;=&gt;nil, &quot;email&quot;=&gt;nil, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:recepinancc@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;GitHub&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-github&quot;, &quot;url&quot;=&gt;&quot;https://github.com/recepinanc&quot;}, {&quot;label&quot;=&gt;&quot;Twitter&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-twitter-square&quot;, &quot;url&quot;=&gt;&quot;https://twitter.com/recepinancc&quot;}, {&quot;label&quot;=&gt;&quot;Website&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;nil}, {&quot;label&quot;=&gt;&quot;Facebook&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-facebook-square&quot;}, {&quot;label&quot;=&gt;&quot;Instagram&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-instagram&quot;}]}</name></author><summary type="html">Most of our applications in production are multi-container applications. In a multi-container application, two or more containers work together as one to create a properly functioning application.</summary></entry><entry><title type="html">Cloud Computing Explained: Public vs. Private vs. Virtual Private</title><link href="https://recepinanc.com/cloud-computing-explained-public-vs.-private-vs.-virtual-private/" rel="alternate" type="text/html" title="Cloud Computing Explained: Public vs. Private vs. Virtual Private" /><published>2021-02-01T00:00:00+00:00</published><updated>2021-02-01T00:00:00+00:00</updated><id>https://recepinanc.com/cloud-computing-explained:-public%20vs.-private%20vs.-virtual-private</id><content type="html" xml:base="https://recepinanc.com/cloud-computing-explained-public-vs.-private-vs.-virtual-private/">&lt;p&gt;Let’s talk about cloud in simpler terms!&lt;/p&gt;

&lt;p&gt;Coming across different terms about a technology without actually getting your head around what they meant is a common issue. Recently, I decided to study Cloud Computing and I wanted start by learning the terminology and then diving deeper into the specific topics.&lt;/p&gt;

&lt;p&gt;With the first post of the “Cloud Computing Explained” series, we will look at a small but commonly used subset of cloud terms:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Public Cloud&lt;/li&gt;
  &lt;li&gt;Private Cloud&lt;/li&gt;
  &lt;li&gt;Virtual Private Cloud&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s first look at the definitions, and then create an analogy to make them easy to remember!&lt;/p&gt;

&lt;h1 id=&quot;public-cloud&quot;&gt;Public Cloud&lt;/h1&gt;

&lt;p&gt;A Public Cloud is a set of cloud services provided to you and other customers by a vendor.&lt;/p&gt;

&lt;p&gt;The Public Cloud enables us to provision resources on-demand according to our needs. There are many different vendors for public cloud services that offer you variant solutions based on your needs to build your software.&lt;/p&gt;

&lt;p&gt;As these solutions’ levels &lt;strong&gt;go down&lt;/strong&gt;, it gives you &lt;strong&gt;more control over the resource&lt;/strong&gt;. However, this also means more &lt;strong&gt;overhead&lt;/strong&gt; since you’ll have more things to do for that resource to be working reliably.&lt;/p&gt;

&lt;p&gt;And one of the tremendous benefits of the public cloud is that you only pay for what you use. That gives you the ability to &lt;strong&gt;optimize your expenses&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;different-levels-of-services&quot;&gt;Different Levels of Services&lt;/h2&gt;

&lt;p&gt;Take a look at the below diagram to visualize solutions at different levels. At the lowest level (bare-metal), you are the most flexible since you got all the control over your system. However, you also have to deal with almost everything by yourself, including scaling, monitoring and, deployment. On the highest level (Serverless, FaaS), you can concentrate solely on writing your application. You give up some of the flexibility for more convenience.&lt;/p&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;img src=&quot;/assets/images/content/different_levels_of_abstraction.png&quot; alt=&quot;Different levels of cloud service abstractions&quot; /&gt;&lt;figcaption&gt;
      By Nate Schutta (Developer Advocate, Pivotal) at SpringOne Platform 2018

    &lt;/figcaption&gt;&lt;/figure&gt;

&lt;h1 id=&quot;private-cloud&quot;&gt;Private Cloud&lt;/h1&gt;

&lt;p&gt;The Private Cloud is having a public cloud environment on the infrastructure that is &lt;strong&gt;dedicated to you&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That brings the disadvantage of being limited by &lt;strong&gt;your infrastructure’s limits&lt;/strong&gt; and the advantage of having &lt;strong&gt;no other neighbors to share your resources&lt;/strong&gt;.&lt;/p&gt;

&lt;h1 id=&quot;virtual-private-cloud&quot;&gt;Virtual Private Cloud&lt;/h1&gt;

&lt;p&gt;A Virtual Private Cloud is where a public cloud’s resources are divided into &lt;strong&gt;virtually isolated&lt;/strong&gt; divisions - “private clouds”.&lt;/p&gt;

&lt;p&gt;Isolating each division from each other creates the illusion of customers have their private cloud - but it’s only there virtually. Virtual Private Clouds are similar to virtual machines where there are no actual physical machines but only the isolation of resources.&lt;/p&gt;

&lt;p&gt;Virtual Private Clouds are a type of Hybrid Clouds. Virtual Private Clouds are a type of &lt;a href=&quot;https://www.redhat.com/en/topics/cloud-computing/what-is-hybrid-cloud&quot;&gt;Hybrid Clouds&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;img src=&quot;/assets/images/content/different_clouds.png&quot; alt=&quot;Different Cloud Types Visualization&quot; /&gt;&lt;figcaption&gt;
      Different Cloud Types Visualization

    &lt;/figcaption&gt;&lt;/figure&gt;

&lt;h1 id=&quot;an-analogy&quot;&gt;An Analogy&lt;/h1&gt;

&lt;p&gt;Imagine the &lt;strong&gt;public cloud&lt;/strong&gt; as an internet cafe where they have these computers and charge you for the time you use them. In that case, the internet cafe is the &lt;strong&gt;vendor&lt;/strong&gt; (in real life, this could be Amazon, Google, Microsoft, etc.). When you go and there and ask for a computer, they start your session on one of the available computers in the public area with others, using the same underlying infrastructure.&lt;/p&gt;

&lt;p&gt;The private gaming rooms, in which they provide you an isolated internet connection from the ones in the public area and the other private gaming rooms. These rooms can be an analogy for &lt;strong&gt;virtual private clouds&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let’s say this internet cafe vendor provides you the service to build one of these private gaming rooms at your house. They use your house’s infrastructure but with their computers and all the software in it. That would be the equivalent of a &lt;strong&gt;private cloud&lt;/strong&gt;.&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://azure.microsoft.com/en-us/overview/what-are-private-public-hybrid-clouds/&quot;&gt;https://azure.microsoft.com/en-us/overview/what-are-private-public-hybrid-clouds/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cloudflare.com/learning/cloud/what-is-a-public-cloud/&quot;&gt;https://www.cloudflare.com/learning/cloud/what-is-a-public-cloud/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cloudflare.com/learning/cloud/what-is-a-virtual-private-cloud/&quot;&gt;https://www.cloudflare.com/learning/cloud/what-is-a-virtual-private-cloud/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.redhat.com/en/topics/cloud-computing/what-is-public-cloud&quot;&gt;https://www.redhat.com/en/topics/cloud-computing/what-is-public-cloud&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.redhat.com/en/topics/cloud-computing/public-cloud-vs-private-cloud-and-hybrid-cloud&quot;&gt;https://www.redhat.com/en/topics/cloud-computing/public-cloud-vs-private-cloud-and-hybrid-cloud&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=8tOj4A7jgWg&quot;&gt;https://www.youtube.com/watch?v=8tOj4A7jgWg&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name>{&quot;name&quot;=&gt;nil, &quot;avatar&quot;=&gt;&quot;/assets/images/avatar.jpg&quot;, &quot;bio&quot;=&gt;&quot;Software Engineer &lt;strong&gt;@Amazon&lt;/strong&gt;&lt;br&gt;Previously &lt;strong&gt;@Sahibinden&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;\&quot;Verba Volant, Scripta Manent.\&quot;&lt;/i&gt;&quot;, &quot;location&quot;=&gt;nil, &quot;email&quot;=&gt;nil, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:recepinancc@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;GitHub&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-github&quot;, &quot;url&quot;=&gt;&quot;https://github.com/recepinanc&quot;}, {&quot;label&quot;=&gt;&quot;Twitter&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-twitter-square&quot;, &quot;url&quot;=&gt;&quot;https://twitter.com/recepinancc&quot;}, {&quot;label&quot;=&gt;&quot;Website&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;nil}, {&quot;label&quot;=&gt;&quot;Facebook&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-facebook-square&quot;}, {&quot;label&quot;=&gt;&quot;Instagram&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-instagram&quot;}]}</name></author><summary type="html">Let’s talk about cloud in simpler terms!</summary></entry><entry><title type="html">Welcome To My Blog!</title><link href="https://recepinanc.com/welcome-to-my-blog!/" rel="alternate" type="text/html" title="Welcome To My Blog!" /><published>2021-01-16T00:00:00+00:00</published><updated>2021-01-16T00:00:00+00:00</updated><id>https://recepinanc.com/welcome-to-my-blog!</id><content type="html" xml:base="https://recepinanc.com/welcome-to-my-blog!/">&lt;p&gt;A warm welcome to you all!&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;i&gt;Verba Volant, Scripta Manent!&lt;/i&gt; - &lt;strong&gt;Latin Proverb&lt;/strong&gt; &lt;br /&gt; Spoken words fly away, written words remain.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hey, it’s Recep! You can learn more about me here in the &lt;a href=&quot;/about/&quot;&gt;“About”&lt;/a&gt; page!&lt;/p&gt;

&lt;p&gt;I took the below three philosophies very seriously as I started my blog:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Verba Volant, Scripta Manent&lt;/strong&gt; - Spoken words fly away, written words remain. I’ve always loved taking notes of the things I learned and writing documents for the things I’ve built because that’s what keeps the information accessible at any time. Although I digitalize most of my notes, pens and notebooks are still my favorites. :)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Teaching is the best teacher&lt;/strong&gt; - To teach something to someone, you have to get into the subject in detail. Studying some topics is good but teaching them to others is a whole another thing. It helps with two things, you understand the topic better and enhance your communication skills.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Ideas worth spreading&lt;/strong&gt; - I love sharing what I know with others via any medium, but writing has always been my first choice. The essential purpose of this blog is to make my knowledge easily accessible to anybody.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope you enjoy reading as much as I enjoy writing my blog.&lt;/p&gt;

&lt;p&gt;&lt;i&gt;To access my older posts please check out: &lt;a href=&quot;http://medium.com/@recepinancc&quot;&gt;http://medium.com/@recepinancc&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;</content><author><name>{&quot;name&quot;=&gt;nil, &quot;avatar&quot;=&gt;&quot;/assets/images/avatar.jpg&quot;, &quot;bio&quot;=&gt;&quot;Software Engineer &lt;strong&gt;@Amazon&lt;/strong&gt;&lt;br&gt;Previously &lt;strong&gt;@Sahibinden&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;\&quot;Verba Volant, Scripta Manent.\&quot;&lt;/i&gt;&quot;, &quot;location&quot;=&gt;nil, &quot;email&quot;=&gt;nil, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:recepinancc@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;GitHub&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-github&quot;, &quot;url&quot;=&gt;&quot;https://github.com/recepinanc&quot;}, {&quot;label&quot;=&gt;&quot;Twitter&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-twitter-square&quot;, &quot;url&quot;=&gt;&quot;https://twitter.com/recepinancc&quot;}, {&quot;label&quot;=&gt;&quot;Website&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;nil}, {&quot;label&quot;=&gt;&quot;Facebook&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-facebook-square&quot;}, {&quot;label&quot;=&gt;&quot;Instagram&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-instagram&quot;}]}</name></author><summary type="html">A warm welcome to you all!</summary></entry></feed>