<?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: Jeisson Florez</title>
    <description>The latest articles on DEV Community by Jeisson Florez (@jeissonflorez29).</description>
    <link>https://dev.to/jeissonflorez29</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%2F592640%2F0a302105-b89e-4572-9de4-e70943022684.jpg</url>
      <title>DEV Community: Jeisson Florez</title>
      <link>https://dev.to/jeissonflorez29</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jeissonflorez29"/>
    <language>en</language>
    <item>
      <title>Best books I've read in 2022 📚</title>
      <dc:creator>Jeisson Florez</dc:creator>
      <pubDate>Fri, 16 Dec 2022 15:55:15 +0000</pubDate>
      <link>https://dev.to/jeissonflorez29/best-books-ive-read-in-2022-3kc1</link>
      <guid>https://dev.to/jeissonflorez29/best-books-ive-read-in-2022-3kc1</guid>
      <description>&lt;p&gt;One of my goals this year was to read more than in previous years and I wanted to share with you some of the best books I read in 2022, some of them are recommendations from other people and others were simply in the long &lt;strong&gt;Wanted to read&lt;/strong&gt; list. These books covered a wide range of topics and all provided valuable insights and information.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;"Thinking, Fast and Slow" by Daniel Kahneman&lt;/strong&gt;. This book goes in-depth into the psychology of decision making and how the brain processes information. It is a fascinating read that help to better understand the thought processes and make more effective decisions. The book contains many examples from different scientific experiments about how our brain acts in different conditions. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Time Smart" by Ashley Whillans&lt;/strong&gt;. This book explores the importance of time and how to use it more effectively. The author covers topics like time management, work-life balance, and the benefits of taking breaks. Like the previous one, this book shows some examples of everyday life where we think that something is very important and we can not postpone it and the reality is that it is not so. This book is a must-read for people looking to optimize their time and increase productivity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Why We Sleep" by Matthew Walker.&lt;/strong&gt; In this book, Walker discusses the science behind sleep and the numerous benefits it has on our physical and mental health. He also offers practical tips for improving sleep quality and getting a good night's rest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"A Short History of Nearly Everything" by Bill Bryson&lt;/strong&gt;. For those interested in science this book covers a wide range of scientific topics, from the origins of the universe to the evolution of life on Earth and humans. It is a thorough and entertaining read that leaves us with a greater appreciation for the world around us and how fortunate we are to be in an age where even a minimal understanding of it is possible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Little Book of Common Sense Investing" by John C. Bogle.&lt;/strong&gt; Bogle, the founder of Vanguard and a pioneer of index fund investing, offers practical advice for avoiding the most common mistakes that can set even the best-intentioned investors up for failure. He advocates for a low-cost, passive approach to investing that focuses on diversification and long-term growth rather than trying to beat the market. It's a great resource for anyone looking to build a solid investment portfolio.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Overall, these five books offer a wealth of knowledge and insights, and I highly recommend them to anyone whose reading desires fall between these topics.&lt;/p&gt;

&lt;p&gt;Any recommendations for the coming year? &lt;/p&gt;

&lt;p&gt;Happy reading!&lt;/p&gt;

&lt;p&gt;If you like this post you can find more in &lt;a href="https://jeisson.dev/blog/"&gt;https://jeisson.dev/blog/&lt;/a&gt; and can follow me in twitter &lt;a class="mentioned-user" href="https://dev.to/jeissonflorez29"&gt;@jeissonflorez29&lt;/a&gt; 👋&lt;/p&gt;

</description>
      <category>reading</category>
      <category>books</category>
      <category>science</category>
    </item>
    <item>
      <title>How to deploy apps from GitHub to Heroku</title>
      <dc:creator>Jeisson Florez</dc:creator>
      <pubDate>Thu, 12 May 2022 15:58:09 +0000</pubDate>
      <link>https://dev.to/jeissonflorez29/how-to-deploy-apps-from-github-to-heroku-5dej</link>
      <guid>https://dev.to/jeissonflorez29/how-to-deploy-apps-from-github-to-heroku-5dej</guid>
      <description>&lt;p&gt;Some weeks ago, the &lt;a href="https://devcenter.heroku.com/articles/github-integration#enabling-github-integration"&gt;Heroku’s GitHub integration&lt;/a&gt; was deactivated due to an issue where some tokens of private repositories in GitHub were compromised and attackers were potentially able to download and access source code of those repositories. More info regarding the issue in &lt;a href="https://blog.heroku.com/we-heard-your-feedback"&gt;a blog post from Heroku&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are many posts, threads on Twitter and videos about alternatives to Heroku, however, for those who want to keep using it as platform provider with a similar behaviour as the official integration, there are some alternatives without put too much effort on it like using GitHub actions. &lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Action - Deploy to Heroku
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/marketplace/actions/deploy-to-heroku"&gt;Deploy to Heroku&lt;/a&gt;  is a GitHub action that allow to deploy to Heroku by using NodeJS commands under the hoods. The official documentation is pretty clear and complete, so to use this action (as any other action 😛) we just need to follow some basic steps.&lt;/p&gt;

&lt;p&gt;In this case we are going to use &lt;a href="https://devcenter.heroku.com/articles/procfile"&gt;The Procfile | Heroku Dev Center&lt;/a&gt; but there are also options to application using docker configurations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make sure the folder named &lt;code&gt;.github/workflows/&lt;/code&gt; exists.&lt;/li&gt;
&lt;li&gt;Create or modify the &lt;code&gt;YAML&lt;/code&gt; file that contains the GitHub action we want to use to deploy.&lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;akhileshns/heroku-deploy@v3.12.12&lt;/code&gt; to your job.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="s"&gt;.... other steps&lt;/span&gt; 

      &lt;span class="s"&gt;- name&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to stage&lt;/span&gt;
        &lt;span class="s"&gt;uses&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;akhileshns/heroku-deploy@v3.12.12&lt;/span&gt;
        &lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;heroku_api_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{secrets.HEROKU_API_KEY}}&lt;/span&gt;
          &lt;span class="na"&gt;heroku_app_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{secrets.HEROKU_APP}}&lt;/span&gt;
          &lt;span class="na"&gt;heroku_email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{secrets.HEROKU_EMAIL}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Set the environment variables in the repository using the action. Go to &lt;strong&gt;Settings -&amp;gt; Security -&amp;gt; Secrets -&amp;gt; Actions&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ctNMm2pK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/47xijhouyiprv8w27ovm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ctNMm2pK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/47xijhouyiprv8w27ovm.png" alt="Add secrets to GitHub" width="880" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execute the job and check that it is able to finish the deployment successfully.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0QlJx6M8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7yjlj4fgoq3f9bujadn9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0QlJx6M8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7yjlj4fgoq3f9bujadn9.png" alt="Job execution success" width="880" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have tried other options to make a deployment to Heroku from GitHub like using the Heroku CLI commands directly but in terms of simplicity and easiness I believe this is one of the easiest way to get close to how it was working before with the official integration.&lt;/p&gt;

&lt;p&gt;If you like this post you can find more in &lt;a href="https://jeisson.dev/blog/"&gt;https://jeisson.dev/blog/&lt;/a&gt; and follow me in twitter &lt;a class="mentioned-user" href="https://dev.to/jeissonflorez29"&gt;@jeissonflorez29&lt;/a&gt; 👋&lt;/p&gt;

</description>
      <category>github</category>
      <category>heroku</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Off-heap memory in Java</title>
      <dc:creator>Jeisson Florez</dc:creator>
      <pubDate>Thu, 08 Apr 2021 12:50:22 +0000</pubDate>
      <link>https://dev.to/jeissonflorez29/off-heap-memory-in-java-4dd1</link>
      <guid>https://dev.to/jeissonflorez29/off-heap-memory-in-java-4dd1</guid>
      <description>&lt;p&gt;The heap area is one of the most important parts in the JVM architecture since it stores all the objects created in a JVM instance, however, there are some cases when it is convenient to put them outside of it. In this post we will see how this can be achieved and some implementations in this regard.&lt;/p&gt;

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

&lt;p&gt;First, let's take a quick look at the JVM architecture. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F9nrq9ahw2lc6a9lz0u9u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F9nrq9ahw2lc6a9lz0u9u.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see the heap is into the Runtime Data Area which contains the areas that are used during the execution of a program, some of them are per thread and others are unique by JVM instance such as the heap. The garbage collector must be taken into account because it is key to understand how memory is managed in the heap.&lt;/p&gt;

&lt;p&gt;A formal definition of the heap area is: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated. The heap is created on virtual machine start-up. Heap storage for objects is reclaimed by an automatic storage management system (known as a &lt;strong&gt;garbage collector&lt;/strong&gt;); objects are never explicitly deallocated. The Java Virtual Machine assumes no particular type of automatic storage management system, and the storage management technique may be chosen according to the implementor’s system requirements. The heap may be of a fixed size or may be expanded as required by the computation and may be contracted if a larger heap becomes unnecessary. The memory for the heap does not need to be contiguous.  &lt;a href="https://docs.oracle.com/javase/specs/jvms/se11/jvms11.pdf" rel="noopener noreferrer"&gt;JVM Specification&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Knowing that all the data stored in the heap is subject to the garbage collector, if the data stored in the heap becomes huge, the time consumed by the garbage collector will be proportionally higher, and here we may be wondering why this may affect us? Well, each garbage collector has a different method to do the heap cleanup but they all have something in common, the &lt;strong&gt;Stop-The-World&lt;/strong&gt; mechanism, which means that at some point all the application threads will be suspended until the garbage collector processes all the objects in the heap. &lt;/p&gt;

&lt;p&gt;That said, while the garbage collector algorithms do a great job of cleaning up in super fast time, when we are dealing with near real-time applications we don't have the option of having these pauses, or when the available physical memory is less than needed then that is when dumping that data off the heap is an option.&lt;/p&gt;

&lt;h2&gt;
  
  
  Off-heap memory
&lt;/h2&gt;

&lt;p&gt;Off-heap memory refers to the memory allocated directly to the operative system, it can be part of the same physical memory or/and disk access based such as &lt;a href="https://medium.com/i0exception/memory-mapped-files-5e083e653b1" rel="noopener noreferrer"&gt;memory mapped-files&lt;/a&gt;. As putting data out of the JVM, serialization  is needed to write and read that data, and the performance will depend on the buffer, serialization process and disk speed (if applicable).&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Reduction of garbage collection pressure.&lt;/li&gt;
&lt;li&gt;Large memory size, depending on the implementation. &lt;/li&gt;
&lt;li&gt;Memory shared among all JVMs present in the OS.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Considerations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Serialization process impact on the performance&lt;/li&gt;
&lt;li&gt;Manual memory management is hard and error-prone (ask to C devs 😅). &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Usage
&lt;/h3&gt;

&lt;p&gt;The way to use off-heap memory depends on the developers and the business case, either creating an own implementation using Java NIO API that allow us to allocate memory manually or using any of the implementations already in the market. &lt;/p&gt;

&lt;p&gt;In this post we will see in a general overview a library that implements some of the most common data structures used in java. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/OpenHFT/Chronicle-Map" rel="noopener noreferrer"&gt;Chronicle-Map&lt;/a&gt;: &lt;em&gt;Chronicle Map is an in-memory, key-value store, designed for low-latency, and/or multi-process applications.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's do a simple test in which the scenario is an application that processes a few million numbers and put them in a Set data structure to sum them up afterwards.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project repo: &lt;a href="https://github.com/kmiloflorez2/off-heap-tests" rel="noopener noreferrer"&gt;GitHub - off-heap-tests&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Max Heap size: 2Gb &lt;/li&gt;
&lt;li&gt;JDK: OpenJDK 64-Bit Server VM Microsoft-18724&lt;/li&gt;
&lt;li&gt;Physical memory: 16Gb&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="nf"&gt;sumNumbers&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;30_000_000&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextLong&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;1_000_000&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// To have time to check jconsole&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;reduce&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0L&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;Long:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Instant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;now&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt; &lt;span class="n"&gt;executeTest&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Instant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;now&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;timeMilli&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toEpochMilli&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toEpochMilli&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Time to get finished in ms: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;timeMilli&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  HashSet Java implementation
&lt;/h4&gt;

&lt;p&gt;The first test will be using a simple HashSet implementation&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;executeTest&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sumNumbers&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.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%2F4j3yw2tpz6qrg9hs6dlw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F4j3yw2tpz6qrg9hs6dlw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fn1isbo07336hhrcegqkh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fn1isbo07336hhrcegqkh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can say It took about 58K ~ 59K milliseconds to get finished.&lt;/p&gt;

&lt;h4&gt;
  
  
  ChronicleSet implementation
&lt;/h4&gt;

&lt;p&gt;ChronicleSet provides a builder that needs the type and the max amount of entries to allocate the memory based on them. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;executeTest&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChronicleSetBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entries&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30_000_000&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sumNumbers&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fkik0cdc8nmlmiczwurjw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fkik0cdc8nmlmiczwurjw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fwba5o50pevxh0pkepni5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fwba5o50pevxh0pkepni5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can say It took about 52K ~ 53K milliseconds to get finished and also notice about change in the heap memory used and the reduction of GC impact.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Off-heap memory is a good option when the data stored in the heap is huge and we need to reduce the time consumed by the garbage collector, also when an application uses more memory than the available physical and using disk space is an option. However, it is worthy to remind that working directly to memory allocation is not an easy task and it can bring difficult issues to deal with.&lt;/p&gt;

&lt;p&gt;In what other cases do you think off-heap memory can be used ?&lt;/p&gt;

&lt;p&gt;If you like this post you can find more in &lt;a href="https://jeisson.dev/blog/" rel="noopener noreferrer"&gt;https://jeisson.dev/blog/&lt;/a&gt; and follow me in twitter &lt;a class="mentioned-user" href="https://dev.to/jeissonflorez29"&gt;@jeissonflorez29&lt;/a&gt; 👋&lt;/p&gt;

</description>
      <category>java</category>
      <category>jvm</category>
      <category>programming</category>
      <category>performance</category>
    </item>
    <item>
      <title>Project Loom &amp; Virtual Threads in Java</title>
      <dc:creator>Jeisson Florez</dc:creator>
      <pubDate>Mon, 22 Mar 2021 22:58:41 +0000</pubDate>
      <link>https://dev.to/jeissonflorez29/project-loom-virtual-threads-in-java-418b</link>
      <guid>https://dev.to/jeissonflorez29/project-loom-virtual-threads-in-java-418b</guid>
      <description>&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: This post will mention some terms such as concurrency, threads, multitasking, and others that will be not explained in a detailed way, but will try to add references to other posts or pages about them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://coderstower.com/2021/02/15/java-concurrency-concurrency-and-parallelism/" rel="noopener noreferrer"&gt;Concurrency&lt;/a&gt; in Java is  natively managed by using threads (&lt;a href="https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html" rel="noopener noreferrer"&gt;java.lang.Thread&lt;/a&gt;)  which basically is a wrapper/mapper for a native OS thread.  This model fits well in a system that does not need too many threads, however it brings some drawbacks when we want to use them in a large scale, let’s say hundreds or thousands threads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why ?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Native OS threads must support all programming languages, they are not optimised for a specific one (maybe C 🤔).&lt;/li&gt;
&lt;li&gt;Expensive &lt;a href="https://medium.com/runtimeerror/context-switching-in-depth-1d6d4e51ab32" rel="noopener noreferrer"&gt;context switching&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;High memory resource usage (stack size).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These items bring issues to escalate java applications using the thread approach to do concurrent jobs using many threads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;E.g.&lt;/strong&gt; A web server application processing 500 req / sec  -&amp;gt; 500 threads -&amp;gt; 500 Mb. &lt;em&gt;Thinking about only threads created for each request, for sure a web server use other threads and memory.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here is where Project Loom comes as a solution, so first of all let’s define what Project Loom is and what it brings to the Java world. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; Project Loom is still an ongoing project and all the information, names and definitions about it could change and there is not any official JDK released to work with. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Project Loom&lt;/strong&gt; is to intended to explore, incubate and deliver Java VM features and APIs built on top of them for the purpose of supporting easy-to-use, high-throughput lightweight concurrency and new programming models on the Java platform - &lt;a href="https://wiki.openjdk.java.net/display/loom/Main" rel="noopener noreferrer"&gt;Project Loom Wiki&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Project Loom is a platform based solution introducing the concept of &lt;strong&gt;Virtual Thread&lt;/strong&gt; (a.k.a Fiber) that is a lightweight thread managed by the Java Virtual Machine rather than the operating system and it fits with the existing Java APIs allowing synchronous (blocking) code. &lt;/p&gt;

&lt;h2&gt;
  
  
  Using Project Loom in a Java application
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; This post wants to show a general overview and some notions about how project  loom and virtual threads perform rather than showing any kind of micro benchmark or something deeper. &lt;/p&gt;

&lt;p&gt;We will use jconsole to monitor the performance and then check how many threads are created, how much memory is used and how the CPU is behaving. &lt;/p&gt;

&lt;p&gt;For these tests a MacBook Pro 15” 2018 will be used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;16Gb&lt;/li&gt;
&lt;li&gt;2,2 GHz 6-Core Intel Core i7&lt;/li&gt;
&lt;li&gt;Mac OS Catalina&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since there is not any official release of the JDK including Project Loom, we must use the early-access binaries provided by the project. &lt;/p&gt;

&lt;p&gt;We can download them from the official page of the project, these binaries are based on JDK 17 and there are options for Linux, MacOS and Windows binaries. &lt;br&gt;
&lt;a href="https://jdk.java.net/loom/" rel="noopener noreferrer"&gt;Project Loom Early-Access Builds&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the binaries are downloaded and set in the PATH we can use the JDK Project Loom:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ java &lt;span class="nt"&gt;--version&lt;/span&gt;
openjdk 17-loom 2021-09-14
OpenJDK Runtime Environment &lt;span class="o"&gt;(&lt;/span&gt;build 17-loom+2-42&lt;span class="o"&gt;)&lt;/span&gt;
OpenJDK 64-Bit Server VM &lt;span class="o"&gt;(&lt;/span&gt;build 17-loom+2-42, mixed mode, sharing&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Threads
&lt;/h3&gt;

&lt;p&gt;Let’s do a naive test creating an app that creates 1000 threads and each thread run some random math operations between two numbers during a couple of minutes, and then compare the performance using the usual native threads vs virtual threads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RandomNumbers&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;Random&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Random&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// during 120 seconds aprox&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"c = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// print to avoid compiler remove the operation&lt;/span&gt;
                &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// each operation every second&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then let’s create the threads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

      &lt;span class="c1"&gt;// Create 1000 native threads &lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RandomNumbers&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;120000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Native threads results
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Around 1000 threads.&lt;/li&gt;
&lt;li&gt;CPU usage between 2 and 3 %.&lt;/li&gt;
&lt;li&gt;Constant memory usage around 150 Mb.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2F854quw0ae4s4n0ejzguc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F854quw0ae4s4n0ejzguc.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.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%2F5wbtzlqb7nxxgqsrakpp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5wbtzlqb7nxxgqsrakpp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.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%2Fm9ew3io83njpk421zgtk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fm9ew3io83njpk421zgtk.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s do the same operation using virtual threads&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

      &lt;span class="c1"&gt;// Create 1000 virtual threads &lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startVirtualThread&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RandomNumbers&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;120000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Virtual threads results
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Around 30 threads&lt;/li&gt;
&lt;li&gt;CPU usage under 2%&lt;/li&gt;
&lt;li&gt;Incremental memory usage from 20Mb to 60 Mb. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fsjg7o5z40q6u25imrtk9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fsjg7o5z40q6u25imrtk9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.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%2Fdgj603lddopv44jp7085.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fdgj603lddopv44jp7085.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.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%2F6v83uga72s68iwrepayf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F6v83uga72s68iwrepayf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Executor services
&lt;/h3&gt;

&lt;p&gt;Now let’s do a test using something more elaborate using Executor service to schedule the threads .&lt;/p&gt;

&lt;h4&gt;
  
  
  CachedThreadPool Executor service
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;ExecutorService&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Executors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newCachedThreadPool&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RandomNumbers&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shutdown&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;awaitTermination&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TimeUnit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SECONDS&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shutdownNow&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This implementation of executor service uses a new thread (native) per task scheduled unless there is a free thread to take it. &lt;/p&gt;

&lt;p&gt;These results look pretty similar to the threads approach&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Around 1000 threads.&lt;/li&gt;
&lt;li&gt;CPU usage around 2 %.&lt;/li&gt;
&lt;li&gt;Constant memory usage around 130 Mb.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fk09foymzwufbk1gmniba.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fk09foymzwufbk1gmniba.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.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%2Frgh29cxywc07bdxczuev.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Frgh29cxywc07bdxczuev.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.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%2Fsjqjepecjij76fdhkag5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fsjqjepecjij76fdhkag5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  VirtualThreadExecutor Executor service
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;ExecutorService&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Executors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newVirtualThreadExecutor&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RandomNumbers&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shutdown&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;awaitTermination&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TimeUnit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SECONDS&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shutdownNow&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These results show a light decrease of memory and CPU usage. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Around 30 threads.&lt;/li&gt;
&lt;li&gt;CPU usage between 1 and 2 %.&lt;/li&gt;
&lt;li&gt;Incremental memory usage from 30Mb up to 40 Mb. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fu93e760quf37bsz1ebbo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fu93e760quf37bsz1ebbo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.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%2F7p9in3mzwntg2s00eh5v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F7p9in3mzwntg2s00eh5v.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.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%2F0ejr92kvv1a68oc58dgx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F0ejr92kvv1a68oc58dgx.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We can see how the use of virtual threads could help us when we need to use concurrency using thousands of threads without compromising performance and making optimal use of resources. &lt;/p&gt;

&lt;p&gt;Project Loom is promising a good future to Java and its concurrency API to be at the level of other languages that already have lightweight concurrency models. &lt;/p&gt;

&lt;p&gt;_If you like this post you can find more in &lt;a href="https://jeisson.dev/blog/" rel="noopener noreferrer"&gt;https://jeisson.dev/blog/&lt;/a&gt; and follow me in twitter &lt;a class="mentioned-user" href="https://dev.to/jeissonflorez29"&gt;@jeissonflorez29&lt;/a&gt; 👋&lt;/p&gt;

&lt;p&gt;&lt;a href="https://openjdk.java.net/projects/loom/" rel="noopener noreferrer"&gt;OpenJDK: Loom&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>concurrency</category>
      <category>loom</category>
      <category>threads</category>
    </item>
    <item>
      <title>MacOS Development workspace 2023</title>
      <dc:creator>Jeisson Florez</dc:creator>
      <pubDate>Mon, 08 Mar 2021 17:31:33 +0000</pubDate>
      <link>https://dev.to/jeissonflorez29/macos-development-workspace-2021-2ld6</link>
      <guid>https://dev.to/jeissonflorez29/macos-development-workspace-2021-2ld6</guid>
      <description>&lt;p&gt;It is a fact that there are many guides out there about how to set up a dev workspace, however, some of them are outdated or no longer fit my needs, I have collected a lot of information from some of them and created a new guide that I want to share.&lt;/p&gt;

&lt;p&gt;As developers we need to install almost always the same set of tools for our daily basis, so this guide will go throught a list of apps, sdks, commands and many others tools that I found useful. &lt;/p&gt;

&lt;p&gt;I have created a repository on &lt;a href="https://github.com/jflorez29/dotfiles" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; to store the dotfiles and the installation script in case anyone wants to go straight to use it,  I recommend to read the guide before though.&lt;/p&gt;

&lt;p&gt;With this guide we will assume a clean installation of MacOs and go step by step through the installation process and a short description of each app/command/tool. &lt;/p&gt;

&lt;p&gt;Let's open a new terminal and get started ...&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://developer.apple.com/xcode/features/" rel="noopener noreferrer"&gt;Xcode&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Xcode is a large suite of software development tools and libraries from Apple, even if we are not iOS/MacOs developers, this step is necessary to install &lt;strong&gt;Xcode command line tools&lt;/strong&gt; which includes MacOs SDK, and many other common tools, compilers, and commands that we will need in the whole guide.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Input the following command in a Terminal
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xcode-select &lt;span class="nt"&gt;--install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;A system popup will appear to confirm the installation, click &lt;strong&gt;Install&lt;/strong&gt; and agree the terms.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fc9p2a033gsrsjfgu9346.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fc9p2a033gsrsjfgu9346.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;After the process is finished, the pop-up window will look like this. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fn43lxftyfnh23da3rzvx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fn43lxftyfnh23da3rzvx.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://brew.sh/" rel="noopener noreferrer"&gt;Homebrew&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Homebrew is in general words a package manager for MacOs that allow us to install software that does not come installed by default. It works as a command tool, although there are some apps to use it with a graphical user interface like &lt;a href="https://www.cakebrew.com/" rel="noopener noreferrer"&gt;Cakebrew&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Furthermore the default formulae, &lt;code&gt;brew&lt;/code&gt; is able to track and use third parties repos, we need to add some repos and we can do it using the &lt;code&gt;brew tap 'repo'&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew tap homebrew/cask
brew tap homebrew/cask-fonts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/Homebrew/homebrew-cask" rel="noopener noreferrer"&gt;homebrew/cask&lt;/a&gt; brings simplicity, and speed to the installation and management of GUI macOS applications such as Atom and Google Chrome.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Homebrew/homebrew-cask-fonts" rel="noopener noreferrer"&gt;homebrew/cask-fonts&lt;/a&gt; As we can imagin it contains free distributed fonts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I recommend visiting and reading &lt;a href="https://docs.brew.sh/" rel="noopener noreferrer"&gt;Hombew documentation page&lt;/a&gt; to solve any doubt about brew.&lt;/p&gt;

&lt;p&gt;Let's move to install brew packages&lt;/p&gt;

&lt;h3&gt;
  
  
  Fonts
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;font-meslo-lg-nerd-font
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This font comes from the awesome fonts package &lt;a href="https://www.nerdfonts.com/" rel="noopener noreferrer"&gt;Nerd fonts&lt;/a&gt; that includes developer targeted fonts such as Font Awesome, Powerline, and others. We will use this one to make our terminal pretty using icons.&lt;/p&gt;

&lt;p&gt;By the way, we can search which fonts are included in this package by &lt;code&gt;brew search nerd&lt;/code&gt; and then install any other we want just changing the name of the font in the command used before. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fcc0uiww8pvnukkvf04cg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fcc0uiww8pvnukkvf04cg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  GNU Utilities
&lt;/h3&gt;

&lt;p&gt;MacOs command line tools are based on FreeBSD instead of GNU, so this could be a challenge when we want to script something supported by both platforms or if we are used to gnu commands. brew can help us installing the GNU tools, however, they come with a prefixed &lt;code&gt;g&lt;/code&gt; by default. We will install following tools &lt;a href="https://www.gnu.org/software/coreutils/" rel="noopener noreferrer"&gt;coreutils&lt;/a&gt;, &lt;a href="https://joeyh.name/code/moreutils/" rel="noopener noreferrer"&gt;moreutils&lt;/a&gt;, &lt;a href="https://www.gnu.org/software/findutils/" rel="noopener noreferrer"&gt;findutils&lt;/a&gt;, &lt;a href="https://www.gnu.org/software/sed/" rel="noopener noreferrer"&gt;gnu-sed&lt;/a&gt;, &lt;a href="https://www.gnu.org/software/gawk/" rel="noopener noreferrer"&gt;gawk&lt;/a&gt;, &lt;a href="https://www.gnu.org/software/tar/" rel="noopener noreferrer"&gt;gnu-tar&lt;/a&gt;, &lt;a href="https://www.gnu.org/software/grep/" rel="noopener noreferrer"&gt;grep&lt;/a&gt;, &lt;a href="https://www.gnu.org/software/make/" rel="noopener noreferrer"&gt;make&lt;/a&gt;, check their pages and decide if you want/need all of them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;coreutils moreutils findutils gnu-sed gawk gnu-tar &lt;span class="nb"&gt;grep &lt;/span&gt;make
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Other Command Utilities
&lt;/h3&gt;

&lt;p&gt;In this section we will install other commands and utilities. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.geeksforgeeks.org/htop-command-in-linux-with-examples/" rel="noopener noreferrer"&gt;htop&lt;/a&gt;: A better option than top to monitor the system.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.geeksforgeeks.org/tree-command-unixlinux/" rel="noopener noreferrer"&gt;tree&lt;/a&gt; It's useful to list directories and files recursively.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ogham/exa" rel="noopener noreferrer"&gt;exa&lt;/a&gt;: It's an alternative to the default listing command &lt;code&gt;ls&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://alligator.io/workflow/cowsay/" rel="noopener noreferrer"&gt;cowsay&lt;/a&gt;: Generates an ASCCI picture of a cow with a message passed by string.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/sharkdp/bat" rel="noopener noreferrer"&gt;bat&lt;/a&gt;: A cat clone with syntax highlighting and Git integration.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ClementTsang/bottom" rel="noopener noreferrer"&gt;clementtsang/bottom/bottom&lt;/a&gt;: A graphical process/system monitor with a customizable interface and a multitude of features.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://tldr.sh/" rel="noopener noreferrer"&gt;tldr&lt;/a&gt;: It's an option to get the the command options and practical examples.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/simeji/jid" rel="noopener noreferrer"&gt;jid&lt;/a&gt;: An utility to view and interact JSON content with a terminal.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/sharkdp/hyperfine" rel="noopener noreferrer"&gt;hiperfine&lt;/a&gt;: A command-line benchmarking tool.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.andre-simon.de/doku/highlight/en/highlight.php" rel="noopener noreferrer"&gt;highlight&lt;/a&gt;: Converts sourcecode to HTML, XHTML, RTF, LaTeX, TeX, SVG, BBCode and terminal escape sequences with coloured syntax highlighting.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://neovim.io/" rel="noopener noreferrer"&gt;nvim&lt;/a&gt;: It's an alternative vim-based editor with lots of plugins and programming languages supported.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ytdl-org.github.io/youtube-dl/" rel="noopener noreferrer"&gt;youtube-dl&lt;/a&gt;: A command-line program to download videos from YouTube and other sites.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/wting/autojump" rel="noopener noreferrer"&gt;autojump&lt;/a&gt;: A faster way to navigate your filesystem&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://httpie.io/" rel="noopener noreferrer"&gt;httpie&lt;/a&gt;: It's a user-friendly command-line HTTP client, it comes with JSON support, syntax highlighting, persistent sessions, wget-like downloads, plugins, and more.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/nvbn/thefuck" rel="noopener noreferrer"&gt;thefuck&lt;/a&gt;: It's an app able to correct errors in previous console commands.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://golang.org/" rel="noopener noreferrer"&gt;golang&lt;/a&gt;, &lt;a href="https://www.python.org/" rel="noopener noreferrer"&gt;python&lt;/a&gt;, &lt;a href="https://www.python.org/" rel="noopener noreferrer"&gt;python3&lt;/a&gt;: Programming languages.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://getkap.co/" rel="noopener noreferrer"&gt;kap&lt;/a&gt;: It's an screen recorder built with web technology.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;htop tree exa cowsay bat clementtsang/bottom/bottom &lt;span class="se"&gt;\&lt;/span&gt;
vim tldr jid hyperfine highlight nvim youtube-dl autojump &lt;span class="se"&gt;\&lt;/span&gt;
httpie thefuck golang python python3 git kap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  GUI Apps
&lt;/h3&gt;

&lt;p&gt;Some of the applications that we will install do not need a description, we will explain those that are probably not common or deserve to be listed. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://iterm2.com/" rel="noopener noreferrer"&gt;iterm2&lt;/a&gt;: An alternative to the default terminal app brings an amazing performance and customization.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.expressrefer.com/refer-friend?locale=es&amp;amp;referrer_id=47839744&amp;amp;utm_campaign=referrals&amp;amp;utm_medium=copy_link&amp;amp;utm_source=referral_dashboard" rel="noopener noreferrer"&gt;expressvpn&lt;/a&gt;: It's the best vpn service I have tried with lot of servers around the world and good performance.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.alfredapp.com/" rel="noopener noreferrer"&gt;alfred&lt;/a&gt;: An app that allow to be more efficient with shortcuts, searches and own workflows.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://bitwarden.com" rel="noopener noreferrer"&gt;bitwarden&lt;/a&gt;: Service of security for passwords, files, credit cards, it has a nice integration and synchronization in wide list of devices.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/exelban/stats" rel="noopener noreferrer"&gt;stats&lt;/a&gt;: A pretty macOS system monitor in the menu bar, includes CPU, Memory, disk, network, fans.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.notion.so/" rel="noopener noreferrer"&gt;notion&lt;/a&gt;: The app to create boards, take notes, track tasks, get organized and many othe features.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.ticktick.com/home" rel="noopener noreferrer"&gt;ticktick&lt;/a&gt;: A To-do and habit tracker app.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://authy.com/" rel="noopener noreferrer"&gt;authy&lt;/a&gt;: 2nd Factor authentication app, it's able to get syncronized in cloud.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kapeli.com/dash" rel="noopener noreferrer"&gt;dash&lt;/a&gt;: Useful to download and store api documentation sets.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://insomnia.rest/" rel="noopener noreferrer"&gt;insomnia&lt;/a&gt;: An alternative to postman for design and test apis.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/hatashiro/kawa" rel="noopener noreferrer"&gt;kawa&lt;/a&gt;: A macOS input source switcher with user-defined shortcuts.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://hluk.github.io/CopyQ/" rel="noopener noreferrer"&gt;copyq&lt;/a&gt;: CopyQ is advanced clipboard manager with editing and scripting features.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://calibre-ebook.com/" rel="noopener noreferrer"&gt;calibre&lt;/a&gt;: It's an open source e-book manager.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; firefox spotify iterm2 expressvpn &lt;span class="se"&gt;\&lt;/span&gt;
alfred the-unarchiver visual-studio-code docker &lt;span class="se"&gt;\&lt;/span&gt;
postman atom stats notion telegram ticktick zoom vlc &lt;span class="se"&gt;\&lt;/span&gt;
intellij-idea whatsapp authy &lt;span class="se"&gt;\&lt;/span&gt;
dash insomnia kawa copyq calibre &lt;span class="se"&gt;\&lt;/span&gt;
microsoft-office brave-browser discord virtualbox skype
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Iterm 2
&lt;/h2&gt;

&lt;p&gt;Iterm2 provides a lot of features and customization is one of them, for people who have gotten used to dark mode like me, we have a lot of themes to choose from.&lt;/p&gt;

&lt;p&gt;We will use &lt;a href="https://draculatheme.com/iterm" rel="noopener noreferrer"&gt;dracula theme&lt;/a&gt;, for that we need to download the &lt;code&gt;.itermcolors&lt;/code&gt; file either by cloning the repo or downloading the zip.&lt;/p&gt;

&lt;p&gt;Once we have the file in our filesystem we need to open Iterm2 preferences -&amp;gt; profile -&amp;gt;  colors&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fgy8qcmuv09wv00k0mxt7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fgy8qcmuv09wv00k0mxt7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Import the &lt;code&gt;Dracula.itermcolors&lt;/code&gt; downloaded before and then choose Dracula as theme&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F6zeo1wv9xyrvz3o5qu7j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F6zeo1wv9xyrvz3o5qu7j.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we will change the font to &lt;strong&gt;MesloLGS Nerd Font Mono&lt;/strong&gt; the one installed in a previous step to make iterm able to show icons with powerline fonts. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fzv2fz5sklzvau9uwv6uh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fzv2fz5sklzvau9uwv6uh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;P.S. Oh-my-zsh and powerlevel10k still need to be installed for Iterm to look like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F1mms898qbc5d7fdv911m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F1mms898qbc5d7fdv911m.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://ohmyz.sh/" rel="noopener noreferrer"&gt;Oh-My-Zsh&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Since MacOs Catalina, zsh is the default shell on MacOs, zsh provides over 200 plugin integrations and is very similar to bash. There is a good comparison between the two &lt;a href="https://sunlightmedia.org/bash-vs-zsh/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Oh-my-zsh is an open source and powerful community framework for managing zsh.&lt;/p&gt;

&lt;p&gt;We can install oh-my-zsh with following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or this one if we like wget&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh &lt;span class="nt"&gt;-O&lt;/span&gt; -&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Plugins
&lt;/h3&gt;

&lt;p&gt;Oh-my-zsh provides &lt;a href="https://github.com/ohmyzsh/ohmyzsh/wiki/Plugins" rel="noopener noreferrer"&gt;too many useful plugins&lt;/a&gt;, we are going to install a few of them. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/zsh-users/zsh-autosuggestions" rel="noopener noreferrer"&gt;zsh-autosuggestion&lt;/a&gt;: It suggests commands as you type based on history and completions.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/zsh-users/zsh-syntax-highlighting.git" rel="noopener noreferrer"&gt;zsh-syntax-highlighting&lt;/a&gt;: provides syntax highlighting for command type in the prompt of zsh terminal. &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/junegunn/fzf.git" rel="noopener noreferrer"&gt;fzf&lt;/a&gt;: It's a powerful command line finder. &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/romkatv/powerlevel10k.git" rel="noopener noreferrer"&gt;powerlevel10k&lt;/a&gt;: It's a theme for Zsh. It emphasizes speed, flexibility and out-of-the-box experience.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;### Install zsh-autosuggestions&lt;/span&gt;
git clone &lt;span class="nt"&gt;--depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 https://github.com/zsh-users/zsh-autosuggestions &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ZSH_CUSTOM&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="p"&gt;/.oh-my-zsh/custom&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/plugins/zsh-autosuggestions
&lt;span class="c"&gt;### Install zsh-syntax-highlighting&lt;/span&gt;
git clone &lt;span class="nt"&gt;--depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 https://github.com/zsh-users/zsh-syntax-highlighting.git &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ZSH_CUSTOM&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="p"&gt;/.oh-my-zsh/custom&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/plugins/zsh-syntax-highlighting
&lt;span class="c"&gt;### Install fzf&lt;/span&gt;
git clone &lt;span class="nt"&gt;--depth&lt;/span&gt; 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
&lt;span class="c"&gt;### Install powerlevel10k theme&lt;/span&gt;
git clone &lt;span class="nt"&gt;--depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 https://github.com/romkatv/powerlevel10k.git &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ZSH_CUSTOM&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="p"&gt;/.oh-my-zsh/custom&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/themes/powerlevel10k
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the plugins are installed, we must activate them by modifying the &lt;code&gt;~/.zshrc&lt;/code&gt; file wich is the zsh configuration file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;....
plugins=(git zsh-syntax-highlighting zsh-autosuggestions fzf)
....
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this will activate powerlevel10k theme&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ZSH_THEME="powerlevel10k/powerlevel10k"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally the &lt;code&gt;.zshrc&lt;/code&gt; file should looks like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
  source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi

export ZSH="/Users/user/.oh-my-zsh"

ZSH_THEME="powerlevel10k/powerlevel10k"

plugins=(git zsh-syntax-highlighting zsh-autosuggestions fzf)

source $ZSH/oh-my-zsh.sh

# fzf plugin
[ -f ~/.fzf.zsh ] &amp;amp;&amp;amp; source ~/.fzf.zsh

# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to restart the terminal and then the powerlevel10k configuration wizard will start. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/nvm-sh/nvm" rel="noopener noreferrer"&gt;NVM&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Nvm is a version manager for node js, it helps us to install different versions of node and change it easily. &lt;/p&gt;

&lt;p&gt;We will install it by executing next command in the terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-o-&lt;/span&gt; https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.0/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During the installation process it will try to add some exports to &lt;code&gt;.zshrc&lt;/code&gt; file to be able to use it. the file should include some lines like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;NVM_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.nvm"&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NVM_DIR&lt;/span&gt;&lt;span class="s2"&gt;/nvm.sh"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NVM_DIR&lt;/span&gt;&lt;span class="s2"&gt;/nvm.sh"&lt;/span&gt;  &lt;span class="c"&gt;# This loads nvm&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NVM_DIR&lt;/span&gt;&lt;span class="s2"&gt;/bash_completion"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NVM_DIR&lt;/span&gt;&lt;span class="s2"&gt;/bash_completion"&lt;/span&gt;  &lt;span class="c"&gt;# This loads nvm bash_completio&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we have verified that the lines are included, we should reload the session with &lt;code&gt;source ~/.zshrc&lt;/code&gt; or open a new terminal window.&lt;/p&gt;

&lt;p&gt;Now we can install any node version we want, in this case we will install the most recent lts version released&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nvm &lt;span class="nb"&gt;install &lt;/span&gt;node lts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then we can check that node is installed properly&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;a href="https://sdkman.io/" rel="noopener noreferrer"&gt;SDKMAN&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;SDKMAN is a tool for managing parallel versions of multiple Software Development Kits on most Unix based systems, It provides a convenient Command Line Interface (CLI) and API for installing, switching, removing and listing Candidates.&lt;/p&gt;

&lt;p&gt;To install sdkman input the following command in a new terminal&lt;/p&gt;

&lt;p&gt;P.S. In this case we don't want to let it modify our bash files because we will do it by ourself for that we add the query param &lt;code&gt;rcupdate=false&lt;/code&gt;, we can remove it if we want update the files with the installation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://get.sdkman.io?rcupdate=false"&lt;/span&gt; | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the process is finished we need to add the following lines to our &lt;code&gt;~/.zshrc&lt;/code&gt; file and reload the shell by &lt;code&gt;source ~/.zshrc&lt;/code&gt; to be able to use it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;SDKMAN_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.sdkman"&lt;/span&gt;
&lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SDKMAN_DIR&lt;/span&gt;&lt;span class="s2"&gt;/bin/sdkman-init.sh"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SDKMAN_DIR&lt;/span&gt;&lt;span class="s2"&gt;/bin/sdkman-init.sh"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can install any sdk availble into sdman. We will install JDK, to know which versions are available we can use the &lt;code&gt;list&lt;/code&gt; option &lt;code&gt;sdk list java&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fejap51fz50im6sldwua3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fejap51fz50im6sldwua3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the list obtained before we should use the column &lt;strong&gt;Identifier&lt;/strong&gt; to indicare what version we want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sdk &lt;span class="nb"&gt;install &lt;/span&gt;java 11.0.10.j9-adpt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we should be able to use java JDK.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ffikq27l1a580b76q6ycp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ffikq27l1a580b76q6ycp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are many other sdks, we can check them here &lt;a href="https://sdkman.io/sdks" rel="noopener noreferrer"&gt;https://sdkman.io/sdks&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  dotfiles
&lt;/h2&gt;

&lt;p&gt;These dotfiles consist of 7 files, each one with an specific purpose. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/kmiloflorez2/dotfiles/blob/master/.aliases" rel="noopener noreferrer"&gt;&lt;code&gt;.aliases&lt;/code&gt;&lt;/a&gt;: All the shortcuts for most used commands.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/kmiloflorez2/dotfiles/blob/master/.functions" rel="noopener noreferrer"&gt;&lt;code&gt;.functions&lt;/code&gt;&lt;/a&gt;: A set of useful bash functions.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/kmiloflorez2/dotfiles/blob/master/.exports" rel="noopener noreferrer"&gt;&lt;code&gt;.exports&lt;/code&gt;&lt;/a&gt;: All the exports needed for the software installed in this guide.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/kmiloflorez2/dotfiles/blob/master/.gitconfig" rel="noopener noreferrer"&gt;&lt;code&gt;.gitconfig&lt;/code&gt;&lt;/a&gt;: Git configuration&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/kmiloflorez2/dotfiles/blob/master/.gitignore" rel="noopener noreferrer"&gt;&lt;code&gt;.gitignore&lt;/code&gt;&lt;/a&gt;: General git ignore configuration.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/kmiloflorez2/dotfiles/blob/master/.p10k.zsh" rel="noopener noreferrer"&gt;&lt;code&gt;.p10k.zsh&lt;/code&gt;&lt;/a&gt;: powerlevel10k theme configuration, this is the file generated by the theme installation.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/kmiloflorez2/dotfiles/blob/master/.zshrc" rel="noopener noreferrer"&gt;&lt;code&gt;.zshrc&lt;/code&gt;&lt;/a&gt;: zsh file configuration, includes plugins declaration, theme, and imports of other dotfiles.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Defaults write commands
&lt;/h2&gt;

&lt;p&gt;Commands for change default MacOs preferences&lt;/p&gt;

&lt;h3&gt;
  
  
  Finder
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Show file extensions &lt;/span&gt;
defaults write NSGlobalDomain AppleShowAllExtensions &lt;span class="nt"&gt;-bool&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="c"&gt;# Disable the warning before emptying the Trash&lt;/span&gt;
defaults write com.apple.finder WarnOnEmptyTrash &lt;span class="nt"&gt;-bool&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;span class="c"&gt;# Use list view in all Finder windows by default&lt;/span&gt;
&lt;span class="c"&gt;# Four-letter codes for the other view modes: `icnv`, `clmv`, `Flwv`&lt;/span&gt;
defaults write com.apple.finder FXPreferredViewStyle &lt;span class="nt"&gt;-string&lt;/span&gt; &lt;span class="s2"&gt;"Nlsv"&lt;/span&gt;
&lt;span class="c"&gt;# When performing a search, search the current folder by default&lt;/span&gt;
defaults write com.apple.finder FXDefaultSearchScope &lt;span class="nt"&gt;-string&lt;/span&gt; &lt;span class="s2"&gt;"SCcf"&lt;/span&gt;
&lt;span class="c"&gt;# Disable the warning when changing a file extension&lt;/span&gt;
defaults write com.apple.finder FXEnableExtensionChangeWarning &lt;span class="nt"&gt;-bool&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dock
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Set the icon size of Dock items to 48 pixels&lt;/span&gt;
defaults write com.apple.dock tilesize &lt;span class="nt"&gt;-int&lt;/span&gt; 48
&lt;span class="c"&gt;# Show indicator lights for open applications in the Dock&lt;/span&gt;
defaults write com.apple.dock show-process-indicators &lt;span class="nt"&gt;-bool&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="c"&gt;# Speed up Mission Control animations&lt;/span&gt;
defaults write com.apple.dock expose-animation-duration &lt;span class="nt"&gt;-float&lt;/span&gt; 0.1
&lt;span class="c"&gt;# Remove the auto-hiding Dock delay&lt;/span&gt;
defaults write com.apple.dock autohide-delay &lt;span class="nt"&gt;-float&lt;/span&gt; 0
&lt;span class="c"&gt;# Remove the animation when hiding/showing the Dock&lt;/span&gt;
defaults write com.apple.dock autohide-time-modifier &lt;span class="nt"&gt;-float&lt;/span&gt; 0.1
&lt;span class="c"&gt;# Automatically hide and show the Dock&lt;/span&gt;
defaults write com.apple.dock autohide &lt;span class="nt"&gt;-bool&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Activity Monitor
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Show the main window when launching Activity Monitor&lt;/span&gt;
defaults write com.apple.ActivityMonitor OpenMainWindow &lt;span class="nt"&gt;-bool&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="c"&gt;# Visualize CPU usage in the Activity Monitor Dock icon&lt;/span&gt;
defaults write com.apple.ActivityMonitor IconType &lt;span class="nt"&gt;-int&lt;/span&gt; 5
&lt;span class="c"&gt;# Show all processes in Activity Monitor&lt;/span&gt;
defaults write com.apple.ActivityMonitor ShowCategory &lt;span class="nt"&gt;-int&lt;/span&gt; 0
&lt;span class="c"&gt;# Sort Activity Monitor results by CPU usage&lt;/span&gt;
defaults write com.apple.ActivityMonitor SortColumn &lt;span class="nt"&gt;-string&lt;/span&gt; &lt;span class="s2"&gt;"CPUUsage"&lt;/span&gt;
defaults write com.apple.ActivityMonitor SortDirection &lt;span class="nt"&gt;-int&lt;/span&gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Others
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Disable the sound effects on boot&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nvram &lt;span class="nv"&gt;SystemAudioVolume&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;" "&lt;/span&gt;
&lt;span class="c"&gt;# Don’t display the annoying prompt when quitting iTerm&lt;/span&gt;
defaults write com.googlecode.iterm2 PromptOnQuit &lt;span class="nt"&gt;-bool&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Other Apps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://totalfinder.binaryage.com/" rel="noopener noreferrer"&gt;Total finder&lt;/a&gt;: Plugin for add tabs, tags and other features to finder.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cleanmymac.com" rel="noopener noreferrer"&gt;Clean my mac&lt;/a&gt;: Cleaner app for MacOs.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://getpocket.com" rel="noopener noreferrer"&gt;Pocket&lt;/a&gt;: App to save content to check later.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://apps.apple.com/es/app/magnet/id441258766" rel="noopener noreferrer"&gt;Magnet&lt;/a&gt;: Window manager app.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/donnemartin/dev-setup" rel="noopener noreferrer"&gt;donnemartin - dev setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jaywcjlove/awesome-mac" rel="noopener noreferrer"&gt;Awesome Mac&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rgomezcasas/dotfiles" rel="noopener noreferrer"&gt;rgomezcasas - dotfiles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/alrra/dotfiles" rel="noopener noreferrer"&gt;alrra - dotfiles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://abawchen.gitlab.io/chore/2018/03/28/setup-zsh-environment-on-mac.html" rel="noopener noreferrer"&gt;setup zsh environment on Mac&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hackernoon.com/personal-macos-workspace-setup-adf61869cd79" rel="noopener noreferrer"&gt;personal workspace setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ryanparman.com/posts/2019/using-gnu-command-line-tools-in-macos-instead-of-freebsd-tools/" rel="noopener noreferrer"&gt;using GNU command line tools in Mac&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>showdev</category>
      <category>setup</category>
      <category>2023</category>
    </item>
  </channel>
</rss>
