<?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: Andrey Goncharov</title>
    <description>The latest articles on DEV Community by Andrey Goncharov (@aigoncharov).</description>
    <link>https://dev.to/aigoncharov</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%2F126320%2Fe882c779-2517-459e-b3f8-058433c1b5e6.jpg</url>
      <title>DEV Community: Andrey Goncharov</title>
      <link>https://dev.to/aigoncharov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aigoncharov"/>
    <language>en</language>
    <item>
      <title>How I got multiple FAANG offers in Europe</title>
      <dc:creator>Andrey Goncharov</dc:creator>
      <pubDate>Tue, 31 Aug 2021 09:20:17 +0000</pubDate>
      <link>https://dev.to/aigoncharov/how-i-got-multiple-faang-offers-in-europe-3g48</link>
      <guid>https://dev.to/aigoncharov/how-i-got-multiple-faang-offers-in-europe-3g48</guid>
      <description>&lt;p&gt;Yet another story of how an ordinary guy from the middle of nowhere in Russia managed to get multiple FAANG offers. This time, in Europe. &lt;br&gt;
I'll tell you a little about my background, share several tips and tricks that helped me to land the interviews and prepare for them, talk about the interviewing process, reveal my final choice.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TL;DR. Sent hundreds of CVs. Solved 100 challenges on Leetcode. Read a book on system design. Went through 9 interviews. Got 4 offers. Accepted 1. Lived happily ever after. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;I guess I shed some light on this already, didn't I? We have a guy in his late twenties from the middle of nowhere in Russia. In fact, it is Voronezh, Russia, but have you ever heard about it? My point exactly. 6-ish years of professional commercial experience. Some degree in CS. For simplicity, let's call it a Master's. It is not a true Master's, but this article is not about the system of education in Russia, right? 4 out of these 6 years I spent working at IT outsourcing companies. For the rest of 2 years, I worked remotely for US-based startups. I have a couple of &lt;a href="https://github.com/aigoncharov" rel="noopener noreferrer"&gt;small libraries on GH&lt;/a&gt;. Try to do conference talks from time to time. One last thing I tried to leverage to make my CV stand out is this blog. It's, let's face it, tiny, but better than nothing. Hopefully, it shows the world my love for tech. Oh, yeah, I am also pursuing my proper Master's from Georgia Tech online. I think this nicely wraps up my life story. By the way, my name is Andrey G. Nice to meet you! &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;G. stands for Goncharov. I wanted to spare you the pain of trying to read it. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I like thinking of myself as a bit of an adventurer. One adventure I nourished in my mind for a long time was to move to another country. A year ago, this desire matured into concrete actions. I did a &lt;a href="https://blog.goncharov.page/immigration-with-numbers" rel="noopener noreferrer"&gt;research and outlined a list of countries for the relocation&lt;/a&gt;. Once I had the list of countries identified, I decided to give myself a break until the end of the year. At the end of January, after a week of snowboarding, I felt energized enough to get back to the relocation mission. &lt;/p&gt;

&lt;h2&gt;
  
  
  Sending out applications
&lt;/h2&gt;

&lt;p&gt;Timeline: January - February 2021.&lt;/p&gt;

&lt;p&gt;Time to send the actual applications. At first, I thought about applying to only well-known companies. Well-known to me. As I started going through the list of companies in my head, the "to me" part of the previous sentence raised more and more doubts. First, there are great companies out there I haven't even heard of, or, at least, can't remember right away. Second, surprise-surprise, human memory is not perfect. I wrote down the companies I know by heart, and went on with the search. I tried googling various lists of great companies to work at. I browsed dozens of vacancies on LinkedIn. While it all helped my list to grow, the ultimate solution I came up with was to go through the &lt;a href="https://www.slickcharts.com/sp500" rel="noopener noreferrer"&gt;list of S&amp;amp;P 500 companies&lt;/a&gt;. If that's not enough for you, you can add &lt;a href="https://www.nasdaq.com/market-activity/stocks/screener" rel="noopener noreferrer"&gt;NASDAQ&lt;/a&gt; on top of it. &lt;br&gt;
A natural question here is why only publicly trading companies? First, I had already tried working for small and medium-sized businesses, wanted to try what it feels like to work for a proper corporation at a proper corporation-sized scale. Second, I figured that a FAANG entry on my resume would act as a quality stamp, opening many doors in the future. Third, I hoped that a rigorous hiring procedure would help to concentrate true talent inside of the company. When you are surrounded by people willing to methodically take a VM apart piece by piece just to figure out why one operation works 5% faster than the other one, it, kind of, becomes a new norm for you, don't you think? At least, it is a heck of a story to tell at a conference. Forth, I figured that larger companies would be less afraid to relocate candidates. Last, my wife is about to start her Master's, and FAANG pays pretty darn well. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip #1. The end of January is too late to start sending out the applications if you consider relocation to the US. Most of the US-based jobs with relocation assume you getting an H1B visa. This type of visa is issued only once a year, and your sponsoring company has to apply all necessary documents by mid-March. FAANG giants rarely operate at this pace.&lt;/p&gt;
&lt;/blockquote&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%2Fxz9ysqgdhuzfxxnjglij.jpg" 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%2Fxz9ysqgdhuzfxxnjglij.jpg" alt="Tip 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As many other articles on the web suggest, I tried to find referrals for some of the biggest companies. I reached out to folks I studied with and met at conferences. I even tried reaching out to people I do not know at all asking for a reference. As one of the Googlers told me, when they refer somebody, they put in how well they know a candidate. If it is a referral for an anonymous on the internet, it is worthless. Apart from referrals, I mostly used companies' own websites to apply for the jobs.&lt;/p&gt;

&lt;p&gt;The first week of February went by. I sent, probably, several hundred applications. My rough estimate is 400. And... nothing. Some of the companies froze their relocation programs due to COVID, some of them silently ignored me. Cosmic powers, my spidey senses, and just common sense came together and hinted that I need either patience or a new strategy. Further thinking transformed it into "patience AND a new strategy". I thought that even I still might see the fruits of my previous work, a new shiny way of getting a one-on-one with a recruiter wouldn't hurt.&lt;/p&gt;

&lt;p&gt;Someone smart once said, "A wise man's question contains half the answer". I wouldn't dare calling myself wise eve remotely, yet when asked myself how I was going to make recruiters notice me, the answer was obvious - send messages to the recruiters, dummy! Without any hesitation, I opened my LinkedIn, found that magical search bar, and started looking for recruiters from the companies I wanted to get in the most.&lt;/p&gt;

&lt;p&gt;Website applications got me interviews with Booking in the Netherlands, JP Morgan in the UK, Amazon in Germany, Microsoft in the US, Lyft in the US. Spamming recruiters worked with Uber in Netherlands and Databricks in the Netherlands. It also kind of worked with Microsoft, but Microsoft in Poland, that was not my area of interest. It was a bit complicated with my referral for Facebook. I reached out to Michel Weststrate, whom I knew as a creator of &lt;a href="https://github.com/immerjs/immer" rel="noopener noreferrer"&gt;immer&lt;/a&gt; and &lt;a href="https://www.mobxjs.com/README.html" rel="noopener noreferrer"&gt;mobx&lt;/a&gt;. He was a super-nice guy, and he referred me for a frontend role. I was immediately rejected. I decided not to give up, and asked my ex-colleague from Hazelcast, master of everything distributed, &lt;a href="https://twitter.com/metanet" rel="noopener noreferrer"&gt;Ensar Basri Kahveci&lt;/a&gt;, for help. I sent him 3 different roles at Facebook I wanted to try - frontend in the UK, generic software engineer in the UK, and something else I don't even remember now. My thinking was that even if my first application for the frontend role was rejected, on a different day a different recruiter might be looking at a new pile of applications, and he might make a different decision about mine. As to the generic software engineer role, I thought that a totally different recruiter might deal with that role, so it was worth a try. On the next day, I connected on LinkedIn to a recruiter from Facebook in London. To my surprise and joy, he read my message! He told me that he saw the referral in the system, and initiated a call.&lt;br&gt;
My last referral that eventually worked came from &lt;a href="https://www.linkedin.com/in/alexsalo/" rel="noopener noreferrer"&gt;Alex Salo&lt;/a&gt; - a god of math I met back in my uni days, who now works at Google. I say eventually because I did not have a reliable way to contact Alex, so by the time he referred me, I already maxed out the number of applications one could send to Google in a month. My website applications to Google, US, did not work. So after a month, in March, I tried to apply to Google, Germany, and Google, Switzerland, via Alex's link, and I got the interview!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip #2. Big corporations are gigantic monsters. Every limb of that monster usually functions independently. Apply to different positions in the same region, apply to different regions, apply at different dates. You may fail to pass the filter for 99 job ads, but you will be selected for the 100th.&lt;/p&gt;
&lt;/blockquote&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%2F9440abpnktqsolm55wg3.jpg" 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%2F9440abpnktqsolm55wg3.jpg" alt="Tip 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the end, I interviewed with Booking, JP Morgan, Amazon (twice!), Microsoft, Lyft, Databricks, Uber, Google, and Facebook.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparation
&lt;/h2&gt;

&lt;p&gt;Most of the big tech companies (if not all) are going to assess your skills based on 3 criteria:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Domain-specific knowledge&lt;/li&gt;
&lt;li&gt;Data structures and algorithms&lt;/li&gt;
&lt;li&gt;System design&lt;/li&gt;
&lt;li&gt;Soft skills / cultural fit&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Domain-specific knowledge
&lt;/h3&gt;

&lt;p&gt;You probably won't see it if you apply for a generic software engineer role. These questions will arise if you apply for more specific roles like fullstack engineer, frontend engineer, and etc. I saw them when I tried myself for a fullstack role at Uber and Booking, a frontend role at JP Morgan.&lt;br&gt;
I did not invest any time into preparation for domain-specific questions hoping that my entire career prepared me for them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data structures and algorithms
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://leetcode.com/" rel="noopener noreferrer"&gt;Leetcode&lt;/a&gt;. Lots of leetcode.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip #3. I would advise choosing a language you are most comfortable with, even if it does not have all the necessary data structures out-of-the-box. I am most fluent in JavaScript/TypeScript. It lacks many popular data structures like heaps. Every time I needed to use a heap in my solution, my interviewer and I just imagined that I had a library with a reasonable API. From my experience, it is never going to be a problem. Worst case scenario, they ask you to write a heap from scratch. Practice it a couple of times, and it should not present a problem for you.&lt;/p&gt;
&lt;/blockquote&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%2F8gs2pb4dvnlrymbra31y.jpg" 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%2F8gs2pb4dvnlrymbra31y.jpg" alt="Tip 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you did not touch algorithmic challenges for a while, I would suggest starting with &lt;a href="https://leetcode.com/explore/featured/card/top-interview-questions-easy/" rel="noopener noreferrer"&gt;the easy collection of top interview questions&lt;/a&gt;. Do not do all of them. Just the recommended ones in each section. After that, I would suggest moving to &lt;a href="https://leetcode.com/explore/interview/card/top-interview-questions-medium/" rel="noopener noreferrer"&gt;the medium collection of top interview questions&lt;/a&gt;. Like before, go only through the recommended challenges in each section. At this point, you should be able to tell which sections are easier for you, and which are the most problematic. Spend extra time on the sections you find the hardest. Now would be a good time for your first coding interview.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip #4. It is ok to be overwhelmed with the complexity. I spent days and weeks feeling utterly stupid. It gets easier once accumulate the critical amount of knowledge. Set for yourself a strict schedule and follow it. I committed to spending up to 2 hours a day going through one section at a time. Leetcode has 6 coding-related sections in each group. This routine gave me an opportunity to more-or-less evenly progress through each section with one extra day to focus on my weak points.&lt;/p&gt;
&lt;/blockquote&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%2F621s9a4rrtobtje462o5.jpg" 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%2F621s9a4rrtobtje462o5.jpg" alt="Tip 4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you go through the first coding interviews in several companies, and you identify which companies are still in the game, it might be a good idea to start exploring company-specialized sets of challenges. It is no longer free on Leetcode, but it is worth it. I did not have time to solve the specialized sets for each company I interviewed with, so I decided to focus on Google and Facebook. After all, how different these coding tasks could be in other companies? One week I went through the Facebook set, another week through the Google one. And so on.&lt;/p&gt;

&lt;h3&gt;
  
  
  System design
&lt;/h3&gt;

&lt;p&gt;You will be given a high-level description of a system. You will need to design a high-level architecture for the system by drawing boxes and explaining how they are interconnected and why you need them. &lt;/p&gt;

&lt;p&gt;At some interviews you will be asked to focus more on the API design, at others, you will need to provide more insight on how you plan to make the system reliable, going into the depth of availability and performance.&lt;/p&gt;

&lt;p&gt;One book that helped me the most was &lt;a href="https://www.amazon.co.uk/gp/product/B08CMF2CQF/ref=as_li_tl?ie=UTF8&amp;amp;camp=1634&amp;amp;creative=6738&amp;amp;creativeASIN=B08CMF2CQF&amp;amp;linkCode=as2&amp;amp;tag=bloggoncharov-21&amp;amp;linkId=c65b5e6991ad601e89f93ac232260167" rel="noopener noreferrer"&gt;"System Design Interview – An insider's guide" by Alex Xu&lt;/a&gt;. It is concise, yet covers a dozen typical systems. As I had a chance to do some system design on my daily job, it was the only book I read. I wanted to spend more time on the algorithms. If you want to dig a bit deeper, check out &lt;a href="https://blog.pragmaticengineer.com/preparing-for-the-systems-design-and-coding-interviews/#systems-design-interviews" rel="noopener noreferrer"&gt;this great blog post by Gergely Orosz&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Soft skills / cultural fit
&lt;/h3&gt;

&lt;p&gt;It was probably the easiest part for me. I went through &lt;a href="https://leetcode.com/explore/interview/card/leapai/" rel="noopener noreferrer"&gt;"Rock the behavioral interview" card on Leetcode&lt;/a&gt;, and wrote down the answers for their questions from my own life and work experience. Do not rely on your memory! Human memory sucks. Write it down.&lt;/p&gt;

&lt;h3&gt;
  
  
  Preparation recap
&lt;/h3&gt;

&lt;p&gt;I started sending out applications at the end of January. My last interview was in mid-April just like I planned. It gave me 10 weeks of preparation. The first 2 weeks I spent doing only leetcode for 2 hours a day on workdays, 4 hours on Saturdays, leaving Sunday off. Around that time I had my first technical interview. I kept on going through leetcode at the same pace, but without a day off, for 2 more weeks. Next, I started reading one chapter from "System Design Interview – An insider's guide" every workday in addition to leetcode. Once I finished it, I returned to the old leetcode-only routine. It was not easy. I had a full-time job. I needed to work on my Master's from Georgia Tech. I had to ruthlessly prioritize and make sacrifices. I fell in love with to-do lists. I think what helped me the most is starting my day with the preparation and then gradually going through my to-do list starting with the most important tasks. &lt;/p&gt;

&lt;h2&gt;
  
  
  Interviews
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip #5. If your interviewing skills are a bit rusty, most likely, you are going to bomb your first couple of interviews. Engage with all the companies from your list as soon as possible, but try to schedule the technical interview for your dream companies at a later point.&lt;/p&gt;
&lt;/blockquote&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%2Fu9p9ctuwgq8fbtarwbli.jpg" 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%2Fu9p9ctuwgq8fbtarwbli.jpg" alt="Tip 5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would be thrilled to work at any of the companies from my list above, so I had a really hard time following the advice from "Tip #4". I slightly preferred some of them over the others, but to be respectful to all of them, I am going to tell you about my interview experience at each one of the companies in no particular order.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lyft
&lt;/h3&gt;

&lt;p&gt;I managed to get a call with a recruiter only. It was the end of February, and we just had no time to go through all tech interviews by the time they would have to file for my H1B visa. See "Tip #1". End of story.&lt;/p&gt;

&lt;p&gt;Score: 0 / 9.&lt;/p&gt;

&lt;h3&gt;
  
  
  Microsoft
&lt;/h3&gt;

&lt;p&gt;I passed the phone call, where I had a leetcode-medium coding challenge. Then after a week of silence, they told me they thought I had a work permit in the US, and they were not willing to sponsor an H1B at that moment. I guess I forgot to click on a non-resident checkbox in my application. Sorry, Microsoft!&lt;/p&gt;

&lt;p&gt;Score: 0 / 9.&lt;/p&gt;

&lt;h3&gt;
  
  
  Databaricks
&lt;/h3&gt;

&lt;p&gt;I failed on the first coding interview. They asked me a medium-complexity leetcode-like question. I did not find the optimal solution. Well, you live, you learn. That's why it is crucial to have several interviews lined up.&lt;/p&gt;

&lt;p&gt;Score: 0 / 9.&lt;/p&gt;

&lt;h3&gt;
  
  
  Booking
&lt;/h3&gt;

&lt;p&gt;I got two domain-specific interviews. Another interview was split in half. First, it was an easy leetcode-like question, then they extended it to a system design question. At the moment, I was working on an offline-first application with multi-user collaboration. I guess it made me over-engineer my final design. After that, I had a behavioral interview with a manager. In the end, I was told that all went well, but the system design. My recruiter offered me to try for a different team, which I did. It was just another behavioral interview. As result, they told me I did not show enough passion.&lt;/p&gt;

&lt;p&gt;Score: 0 / 9.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uber
&lt;/h3&gt;

&lt;p&gt;After a quick call with a recruiter, I got my first domain-specific coding interview. At that moment Uber hired for middle-level and senior-level roles. That interview was supposed to put me either on a middle-level track or on a senior one. After the first round, I was evaluated as a middle-level engineer. Subsequently, I had two more leetcode-like algorithmic challenges, a classical system-design interview, and a behavioral interview with a manager. The results were inconclusive. Uber was not ready to offer me a senior role as they thought my coding was weaker than necessary. They were not ready to offer me a middle-level role as they liked my soft and system design skills. They figured I would be bored without constant exposure to architecture-related tasks, and that's something they provide for their seniors. &lt;/p&gt;

&lt;p&gt;Score: 0 / 9.&lt;/p&gt;

&lt;h3&gt;
  
  
  JP Morgan
&lt;/h3&gt;

&lt;p&gt;After a call with a recruiter, I was up for a full day of interviews. This time no first screening with a coding challenge. I got two domain-specific sessions with more-or-less standard questions about JS and React. After that, I had a behavioral interview with a manager. They really liked that I managed my own portfolio at that time. It was one of the least stressful interview loops. As result, I got an offer for a senior position with relocation to London!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip #6. If you have experience in the company domain, do not be shy and talk about it! Surprise-surprise, it matters.&lt;/p&gt;
&lt;/blockquote&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%2Fe4be3vtyhlt9o7f8vugs.jpg" 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%2Fe4be3vtyhlt9o7f8vugs.jpg" alt="Tip 6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Score: 1 / 9.&lt;/p&gt;

&lt;h3&gt;
  
  
  Amazon
&lt;/h3&gt;

&lt;p&gt;It is a twisted story that proves tip #2. FAANG corporations do not function as a holistic unit with regard to hiring. You can be rejected in one region, but accepted in a different one!&lt;br&gt;
My first interview was with Amazon in Munich. They sent an online screening test with a couple of easy leetcode-like tasks. Shortly after, I was on a call with an engineer solving a medium leetcode challenge. It took about 30% of the interview, while the majority of the time went into the behavioral part of the interview. I thought I did well... and I was wrong. A few days later, I got a rejection letter.&lt;/p&gt;

&lt;p&gt;Be prepared! Amazon asks behavioral questions on every call. Interviews are no longer exclusive to checking one area of knowledge like algorithms or system design. They always check two - your soft skills and either algorithms or system design.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip #7. It is OK to use the same story for all your interviews. Usually, a good life story covers several leadership principles they want to hear.&lt;/p&gt;
&lt;/blockquote&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%2Fl50m3a39h8i84cl80fpp.jpg" 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%2Fl50m3a39h8i84cl80fpp.jpg" alt="Tip 7"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Luckily, it was not the end of the story. I did not stop applying for various vacancies at Amazon. About a week later I got a call from Amazon Cambridge. They did not seem to know or care about my previous failure with Amazon Munich. They did not even mention it. I got the same online screening test. It had different tasks, but the structure was the same - a couple of easy leetcode challenges and forms to explain why I solved them the way I did. A few days later, I jumped on a call with an engineer from the team. This time it was a bit different - same behavioral questions, but two medium leetcodes. I found the optimal solution for the first but did not manage to do the same for the second one. Nevertheless, I passed. &lt;/p&gt;

&lt;p&gt;After a month of preparation, I met the team over 4 interviews. 2 medium leetcodes, one system design, and one coding task that I would describe as application/API design. The last one presented me with a vague list of business requirements. I had to clarify them, set meaningful constraints, and then code a class implementing the logic. In the end, they loved my algorithms, my application/API design, but did not meet expectations with my system design skills. If only a guy from Uber could have called and told them about my mad system design skills. It could have been the end of the story, but it was far from over. I auditioned for the backend role in Cambridge, and the guys thought that even though I lacked the necessary system design skills for their team, I still could be a good match for a frontend role. The thing was that they did not have any frontend roles in Cambridge. I had another call with a recruiter, and she redirected me to... surprise-surprise, Germany! There and back again.&lt;/p&gt;

&lt;p&gt;They set another loop on interviews. This time much shorter. As far as I remember, it was only a single medium leetcode and another system design. This time they loved it and I got an offer. Offer for a middle-level position. Still counts as an offer though, doesn't it? &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip #8. Be proactive and talk to your recruiter about the level you are interviewing for. Make convincing arguments, share that you have interviews with other companies for a higher level. The bottom line, do anything to be put in a loop for a higher position.&lt;/p&gt;
&lt;/blockquote&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%2F1dz6962x1z2syph14bq0.jpg" 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%2F1dz6962x1z2syph14bq0.jpg" alt="Tip 8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Score: 2 / 9.&lt;/p&gt;

&lt;h3&gt;
  
  
  Google
&lt;/h3&gt;

&lt;p&gt;I received a standard FAANG interview package. One phone screener with a medium leetcode. After 2 weeks of prep, an exhausting day with 5 interviews - 1 behavioral, 1 system design, 3 algorithms. Each algorithmic interview was an easy leetcode followed up by a medium leetcode. System design and behavioral were canonical. I got positive feedback. Positive feedback and approval of the committee! Yes, before you get an offer you need to go through a team matching process. To get there, first, some mysterious committee needs to approve your level. In my case, it was L4 - yet another middle level. Remember, tip #8? I wish I knew it back then.&lt;/p&gt;

&lt;p&gt;Score: 3 / 9.&lt;/p&gt;

&lt;h3&gt;
  
  
  Facebook
&lt;/h3&gt;

&lt;p&gt;At first, it seemed like another standard FAANG interview package. However, there was a small catch. They were on a hiring freeze for E4 (middle level). So I had to pass the bar for E5 (senior) without a possible downgrade. A first screening interview with one easy and one medium leetcode. A month of preparation. Finally, 2 days of interviews. 2 algorithmic interviews on day 1. 1 system design and 1 behavioral on day 2. As Mr. Eminem sang, his palms are sweaty, knees weak, arms are heavy... Both algorithmic interviews were "easy leetcode with a medium leetcode followup". I did well on the first one, and absolutely horribly on the second. System design was focused mostly on the API and the DB schema. The behavioral one was more or less standard. They went without a hitch. I heard multiple times about rigorous requirements at FAANG. I was almost ready to say goodbye to this opportunity. Luckily, Facebook was super nice and gave me another chance. They set up another coding interview. If you recollect what Mr. Eminem sang in that song later, it is "There's vomit on his sweater already, mom's spaghetti. He's nervous, but on the surface, he looks calm and ready". Well, I was as far from calm as possible. As result, on the call, I calculated big O for the easy leetcode wrong, but I realized it only after the interview. The interviewer did not seem to notice it or decided not to mention it. However, he thought my solution had a bug. After running various test cases out loud without any luck of finding that bug, I switched to the second part of the interview with the medium leetcode. For that one, I found the best solution and did my math well. I knew that it was my last chance of getting in, and I like thinking of myself as of someone who does not give up that easily. I asked the interviewer to copy-paste my solution for the first task to debug it at home. I created an online test suite with that very implementation and a variety of edge cases. There wasn't a bug! I desperately needed to somehow communicate that sacred knowledge to my interviewer! But how? Facebook does not reveal emails of your interviewers. What it does is reveals their names. It was my lucky day. The guy was an active open source contributor. I found his email in his commits and emailed him the test suite and the correct big O calculation. I do not know if that email had any effect. I never got a reply. At least, I knew I did everything I could. And it worked! A few days later, I received a call from the recruiter with an offer for a senior role in London!&lt;/p&gt;

&lt;p&gt;Score: 4 / 9.&lt;/p&gt;

&lt;h2&gt;
  
  
  Grand finale
&lt;/h2&gt;

&lt;p&gt;After interviews with 9 different well-known prestigious companies, I got 4 offers. After a week of negotiations (&lt;a href="https://haseebq.com/my-ten-rules-for-negotiating-a-job-offer/" rel="noopener noreferrer"&gt;here&lt;/a&gt; is a great guide on how to do it) and hesitations, I happily decided to move to London with Facebook. I now hope for two things. First, that my story helps someone else in the middle of nowhere in a non-English-speaking country realize that they do not need to be a super extraordinary genius to get to FAANG in a major city. All they need is hard work and dedication. Second, that this is the end of a chapter, not the end of a story :) &lt;br&gt;
Stay tuned for new articles by following me on &lt;a href="https://twitter.com/ai_goncharov" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/aigoncharov/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;! Subscribe to my &lt;a href="https://blog.goncharov.page/" rel="noopener noreferrer"&gt;newsletter&lt;/a&gt; or &lt;a href="https://blog.goncharov.page/rss.xml" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;. Drop me an &lt;a href="//mailto:andrey@goncharov.page"&gt;email&lt;/a&gt; if you have any questions.&lt;/p&gt;

</description>
      <category>career</category>
      <category>tech</category>
      <category>interview</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Immigration in IT: Choosing your new home objectively</title>
      <dc:creator>Andrey Goncharov</dc:creator>
      <pubDate>Mon, 26 Oct 2020 13:59:42 +0000</pubDate>
      <link>https://dev.to/aigoncharov/immigration-with-numbers-44bj</link>
      <guid>https://dev.to/aigoncharov/immigration-with-numbers-44bj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;I now have a new shiny blog. Read this article with the latest updates there &lt;a href="https://blog.goncharov.page/immigration-with-numbers"&gt;https://blog.goncharov.page/immigration-with-numbers&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, you have decided to move your ass someplace else, seeking a better life. The whole world is at your feet, but "the whole world" is not a specific place where you can be. You have to choose, if not a city, at least a country. Nowadays, there are plenty of places where your career can skyrocket, and you can have a great quality of life. Of course, it depends on your definition of the "quality of life". In this article, we will try to set subjective factors that drive your decision aside. We will look at the numbers in different areas to rate and, later on, filter our potential relocation prospects for the next X years.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are more comfortable reading in Russian check out &lt;a href="https://habr.com/ru/post/510610/"&gt;this article on habr.com&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Criteria
&lt;/h2&gt;

&lt;p&gt;Before we do the measurement itself, we need to know what to measure. So what do we expect from our new home?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Freedom! Freedom of speech, freedom of political and religious views, functional democratic institutes.&lt;/li&gt;
&lt;li&gt;No corruption... Ok, let's leave ponies and unicorns in our hopefully happy childhood memories. As little corruption as possible. I would like to see where my taxes go.&lt;/li&gt;
&lt;li&gt;Powerful economy. Free market, relaxed regulations, highly diversified high-tech economy. Living off oil and gas is not a good long-term vision.&lt;/li&gt;
&lt;li&gt;Wealth, comfort, safety. As software engineers, we can make decent money at any point of the globe. However, our well-being is not everything. Well-being of our neighbors, who are not software engineers, matters as well. Let's just suppose that when the basic needs are satisfied, human beings tend to get creative, self-improve, create new breakthrough companies, and, therefore, lead the nation to new highs. I am not a socialist in any way. I am just saying that your new Tesla might not make you half as happy if dozens of people next to you barely make enough money for food and clothes.&lt;/li&gt;
&lt;li&gt;Soft immigration policy. Permanent residence in X years. Passport in X + Y years. Work permit for your spouse. &lt;/li&gt;
&lt;li&gt;Moderate taxes. Who wants to pay more, right?&lt;/li&gt;
&lt;li&gt;Hot IT job market. Yes, there are plenty of remote opportunities, but, most probably, you will need a local job to get that work visa.&lt;/li&gt;
&lt;li&gt;Science. Well-developed and well-sponsored science. Let's just suppose it will lead to more innovation in the technological sector of the economy. Moreover, I, personally, would love to believe that at some point in my life I will do research. After all, I might get tired of making my React application draw just another form to save just another JSON with user data to the database.&lt;/li&gt;
&lt;li&gt;Strong army. "People who do not want to feed their own army will soon be forced to feed someone else's." That is, allegedly, Mr. Napoleon Bonaparte, not me.&lt;/li&gt;
&lt;li&gt;Immigrant integration and language. Ideally, people should care not where you come from, but what human being are you. Ideally, they should speak English. I can barely come up with a 10-word sentence without 10 mistakes in it, please, do not make me learn another language!&lt;/li&gt;
&lt;li&gt;Strong passport that allows as many visa-free entries to different countries as possible.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Approach
&lt;/h2&gt;

&lt;p&gt;To be at least relatively object we will not base our judgment on beautiful or not so beautiful stories and videos of various bloggers, vloggers, and who-knows-what-loggers. Instead, I suggest using indices by, in most cases, non-profit independent organizations.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Freedom

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://freedomhouse.org/countries/freedom-world/scores?sort=desc&amp;amp;order=Total%20Score%20and%20Status"&gt;Freedom House&lt;/a&gt;. Locates in the USA. They promise a rating of political and civil liberties in 210 countries. Founded in &lt;a href="https://freedomhouse.org/about-us/our-history"&gt;1941&lt;/a&gt;. &lt;a href="https://freedomhouse.org/sites/default/files/2020-02/FINAL_Freedom_House_Financial%20Statements_2018.pdf"&gt;Funded, mostly, with US federal grants&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Corruption

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.transparency.org/en/cpi/2019/results/table"&gt;Transparency International Corruption Perceptions Index&lt;/a&gt;. Located in Berlin, Germany. Transparent, publish &lt;a href="https://www.transparency.org/en/the-organisation/our-operating-budget"&gt;annual budget reports&lt;/a&gt;. There is &lt;a href="https://www.transparency.org/en/the-organisation/who-supports-us"&gt;a huge list&lt;/a&gt; of those, who chip in for the research. &lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Economy

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.heritage.org/index/ranking"&gt;Index of Economic Freedom&lt;/a&gt; by American &lt;a href="https://www.heritage.org/about-heritage/mission"&gt;Heritage Foundation&lt;/a&gt;. Mostly funded by &lt;a href="https://thf-reports.s3.amazonaws.com/Financial/2019_AnnualReport_Financials.pdf"&gt;individuals&lt;/a&gt;. Who exactly? I wish I knew.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www3.weforum.org/docs/WEF_TheGlobalCompetitivenessReport2019.pdf"&gt;The Global Competitiveness Report&lt;/a&gt; by &lt;a href="https://www.weforum.org/"&gt;World Economic Forum&lt;/a&gt;. Powerful community with &lt;a href="https://www.weforum.org/about/history"&gt;50-year history&lt;/a&gt;. They claim a &lt;a href="https://www.weforum.org/about/our-members-and-partners"&gt;remarkable list&lt;/a&gt; of partners. They publish &lt;a href="http://www3.weforum.org/docs/WEF_Annual_Report_18-19.pdf"&gt;an annual report&lt;/a&gt; on how they spend the money. However, it is unclear how much they get from each partner.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://atlas.cid.harvard.edu/rankings"&gt;Atlas of Economic Complexity&lt;/a&gt; by &lt;a href="https://growthlab.cid.harvard.edu/"&gt;Growth Lab in Harvard&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Wealth, comfort, and safety

&lt;ol&gt;
&lt;li&gt;
&lt;a href="http://hdr.undp.org/en/content/2019-human-development-index-ranking"&gt;Human Development Index&lt;/a&gt; by &lt;a href="https://www.undp.org/content/undp/en/home/"&gt;United Nations Development Programme&lt;/a&gt;. &lt;a href="https://www.undp.org/content/undp/en/home/funding/core-donors.html"&gt;Funded mostly by European Union and North America&lt;/a&gt;. 100% &lt;a href="//file:///home/andreygoncharov/Downloads/UNDP-Funding-Compendium-2018.pdf"&gt;transparent&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://data.oecd.org/natincome/gross-national-income.htm"&gt;Gross National Income per Capita&lt;/a&gt; and &lt;a href="https://stats.oecd.org/Index.aspx?DataSetCode=AV_AN_WAGE"&gt;Average Annual Wages&lt;/a&gt; by &lt;a href="http://www.oecd.org/"&gt;OECD&lt;/a&gt;. Funded by &lt;a href="http://www.oecd.org/about/members-and-partners/"&gt;37 countries&lt;/a&gt;. Transparent &lt;a href="http://www.oecd.org/about/document/list-of-departments-and-special-bodies.htm"&gt;structure&lt;/a&gt; and &lt;a href="http://www.oecd.org/about/budget/"&gt;budget&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dataunodc.un.org/content/homicide-rate-option-2"&gt;Victims of Intentional Homicide&lt;/a&gt; by &lt;a href="https://dataunodc.un.org/"&gt;UNODC&lt;/a&gt;. Yep. United Nations itself. Lots of &lt;a href="https://research.un.org/en/docs/budget/documents"&gt;docs&lt;/a&gt; on where the money comes from.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Army

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.sipri.org/databases/milex"&gt;SIPRI Military Expenditure&lt;/a&gt; by &lt;a href="https://www.sipri.org/"&gt;Stockholm International Peace Research Institute&lt;/a&gt;. It is unclear how exactly they spend their budget, but they have &lt;a href="https://www.sipri.org/"&gt;a detailed list&lt;/a&gt; of those, who provide it.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;IT job market

&lt;ol&gt;
&lt;li&gt;Let's take a number of job openings on &lt;a href="https://www.linkedin.com/jobs/search/?f_F=it"&gt;LinkedIn&lt;/a&gt; and divide it by &lt;a href="https://www.census.gov/popclock/world/"&gt;the population&lt;/a&gt; in millions. For Russia, we will get the vacancies from the local resource - &lt;a href="https://hh.ru/search/vacancy?st=searchVacancy&amp;amp;text=&amp;amp;specialization=1&amp;amp;salary=&amp;amp;currency_code=RUR&amp;amp;experience=doesNotMatter&amp;amp;order_by=relevance&amp;amp;search_period=&amp;amp;items_on_page=50&amp;amp;no_magic=true&amp;amp;L_save_area=true"&gt;hh.ru&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Immigrant integration and language

&lt;ol&gt;
&lt;li&gt;
&lt;a href="http://www.mipex.eu/play/"&gt;Migrant IntegrationPolicy Index&lt;/a&gt;. There is &lt;a href="http://www.mipex.eu/who-produces-mipex"&gt;a list of partners and experts&lt;/a&gt;. I could not find the detailed info on the budget.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.ef.com/wwen/epi/"&gt;EF English Proficiency Index&lt;/a&gt;. Since there is no huge "Donate" button on the website, I assume the organization is commercial. Private commercial organization. So no reports. Sorry, I could not find anything better. At least they &lt;a href="https://www.ef.com/wwen/about-us/our-history/"&gt;sponsored the Olympics&lt;/a&gt; several times.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Passport strength

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.passportindex.org/byRank.php?f="&gt;Passport Index&lt;/a&gt; by &lt;a href="https://www.artoncapital.com/"&gt;Arton Capital&lt;/a&gt;. "Capital", kind of, gives us a hint about the commercial nature of the organization. Unfortunately, nothing better.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Science

&lt;ol&gt;
&lt;li&gt;Let's take &lt;a href="https://www.natureindex.com/country-outputs/generate/All/global/All/score"&gt;"Share" value from Nature Index&lt;/a&gt; and divide it by &lt;a href="https://www.census.gov/popclock/world/"&gt;the population&lt;/a&gt; in millions. Published by &lt;a href="https://www.nature.com/"&gt;Nature&lt;/a&gt;. Commercial. If we trust Wikipedia it is extremely &lt;a href="https://ru.wikipedia.org/wiki/Nature"&gt;respectable&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Taxes

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://taxfoundation.org/publications/international-tax-competitiveness-index/"&gt;International Tax Competitiveness Index&lt;/a&gt; by American &lt;a href="https://taxfoundation.org/"&gt;Tax Foundation&lt;/a&gt;. Finally, another non-profit! They publish &lt;a href="https://files.taxfoundation.org/20200422120938/TaxFoundation_2019AnnualReport1.pdf"&gt;a financial report&lt;/a&gt;, but it is still unclear how exactly it is funded.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://stats.oecd.org/index.aspx?DataSetCode=TABLE_I6#"&gt;All-in average personal income tax rates at average wage by family type&lt;/a&gt; by good old &lt;a href="http://www.oecd.org/"&gt;OECD&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Immigration policy

&lt;ol&gt;
&lt;li&gt;There are some indices trying to somehow rate the migration by people inflow and outflow, but it is not what we are after. We need to rate based on the following criteria:

&lt;ol&gt;
&lt;li&gt;Requirements for immigration visa.&lt;/li&gt;
&lt;li&gt;Requirements for permanent residence.&lt;/li&gt;
&lt;li&gt;Work permit for spouse.&lt;/li&gt;
&lt;li&gt;Requirements for naturalization.&lt;/li&gt;
&lt;li&gt;Multiple citizenship, i.e. if we need to give up an existing passport to be naturalized.
Since there is no easy way to assess these factors, we will, first, filter the countries by other indices, and then have a detailed look at the immigration policy of the finalists.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want to play with the data right away &lt;a href="https://docs.google.com/spreadsheets/d/1ptwI1So-BxxeGKyoMaIHlFm-AjsxjTXu0tZkkGjqlv0/edit?usp=sharing"&gt;here is the link to the Google Spreadsheet&lt;/a&gt;. I am currently located in Russia. So do not get surprised with a separate bottom row with the numbers for Russia. Feel free to clone the table and replace it with the country you want.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Filter by freedom
&lt;/h2&gt;

&lt;p&gt;We will use the &lt;a href="https://freedomhouse.org/countries/freedom-world/scores?sort=desc&amp;amp;order=Total%20Score%20and%20Status"&gt;Freedom House Index&lt;/a&gt;. They rate political and civil liberties. We could have simply taken all the countries marked as &lt;code&gt;Free&lt;/code&gt; (rating above 70 with a few exceptions). Immigration is a big deal. Let's shoot for the stars and raise the bar to &lt;code&gt;80&lt;/code&gt;. Results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Netherlands&lt;/li&gt;
&lt;li&gt;Germany&lt;/li&gt;
&lt;li&gt;Luxembourg&lt;/li&gt;
&lt;li&gt;Switzerland&lt;/li&gt;
&lt;li&gt;Singapore&lt;/li&gt;
&lt;li&gt;France&lt;/li&gt;
&lt;li&gt;Ireland&lt;/li&gt;
&lt;li&gt;United States&lt;/li&gt;
&lt;li&gt;Belgium&lt;/li&gt;
&lt;li&gt;United Kingdom&lt;/li&gt;
&lt;li&gt;Austria&lt;/li&gt;
&lt;li&gt;Canada&lt;/li&gt;
&lt;li&gt;Sweden&lt;/li&gt;
&lt;li&gt;Australia&lt;/li&gt;
&lt;li&gt;Czech Republic&lt;/li&gt;
&lt;li&gt;Denmark&lt;/li&gt;
&lt;li&gt;Spain&lt;/li&gt;
&lt;li&gt;Italy&lt;/li&gt;
&lt;li&gt;Finland&lt;/li&gt;
&lt;li&gt;New Zealand&lt;/li&gt;
&lt;li&gt;Japan&lt;/li&gt;
&lt;li&gt;Norway&lt;/li&gt;
&lt;li&gt;South Korea&lt;/li&gt;
&lt;li&gt;Iceland&lt;/li&gt;
&lt;li&gt;Slovenia&lt;/li&gt;
&lt;li&gt;Cyprus&lt;/li&gt;
&lt;li&gt;Poland&lt;/li&gt;
&lt;li&gt;Greece&lt;/li&gt;
&lt;li&gt;Lithuania&lt;/li&gt;
&lt;li&gt;Slovakia&lt;/li&gt;
&lt;li&gt;Latvia&lt;/li&gt;
&lt;li&gt;Portugal&lt;/li&gt;
&lt;li&gt;Chile&lt;/li&gt;
&lt;li&gt;Croatia&lt;/li&gt;
&lt;li&gt;Argentina&lt;/li&gt;
&lt;li&gt;Estonia&lt;/li&gt;
&lt;li&gt;Romania&lt;/li&gt;
&lt;li&gt;Bulgaria&lt;/li&gt;
&lt;li&gt;Uruguay&lt;/li&gt;
&lt;li&gt;Trinidad and Tobago&lt;/li&gt;
&lt;li&gt;Panama&lt;/li&gt;
&lt;li&gt;Costa Rica&lt;/li&gt;
&lt;li&gt;Mongolia&lt;/li&gt;
&lt;li&gt;Ghana&lt;/li&gt;
&lt;li&gt;Taiwan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here we face the first evidence that humans can never stay 100% objective. I've heard so much nice stuff about Singapore, so I decided to let it pass trough to see how it performs by other criteria.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filter by &lt;a href="http://hdr.undp.org/en/content/2019-human-development-index-ranking"&gt;Human Development Index&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Truly remarkable rating built on 3 pillars: life expectancy, education, and wealth.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DfFDnakc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4exbyy17vejyw0i86td2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DfFDnakc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4exbyy17vejyw0i86td2.jpg" alt="Human Development Index decomposed"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I had to use a single index, I would choose this one. Multi-factor ratings rule!&lt;br&gt;
Let's sort the countries in descending order by Human Development Index.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Country&lt;/th&gt;
&lt;th&gt;Human Development Index&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Norway&lt;/td&gt;
&lt;td&gt;0.954&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switzerland&lt;/td&gt;
&lt;td&gt;0.946&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ireland&lt;/td&gt;
&lt;td&gt;0.942&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Germany&lt;/td&gt;
&lt;td&gt;0.939&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Iceland&lt;/td&gt;
&lt;td&gt;0.938&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sweden&lt;/td&gt;
&lt;td&gt;0.937&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Singapore&lt;/td&gt;
&lt;td&gt;0.935&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Netherlands&lt;/td&gt;
&lt;td&gt;0.933&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Denmark&lt;/td&gt;
&lt;td&gt;0.93&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finland&lt;/td&gt;
&lt;td&gt;0.925&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canada&lt;/td&gt;
&lt;td&gt;0.922&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New Zealand&lt;/td&gt;
&lt;td&gt;0.921&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United States&lt;/td&gt;
&lt;td&gt;0.92&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United Kingdom&lt;/td&gt;
&lt;td&gt;0.92&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Belgium&lt;/td&gt;
&lt;td&gt;0.919&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Japan&lt;/td&gt;
&lt;td&gt;0.915&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Austria&lt;/td&gt;
&lt;td&gt;0.914&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Australia&lt;/td&gt;
&lt;td&gt;0.914&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Luxembourg&lt;/td&gt;
&lt;td&gt;0.909&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;South Korea&lt;/td&gt;
&lt;td&gt;0.906&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Slovenia&lt;/td&gt;
&lt;td&gt;0.902&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spain&lt;/td&gt;
&lt;td&gt;0.893&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;France&lt;/td&gt;
&lt;td&gt;0.891&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Czech Republic&lt;/td&gt;
&lt;td&gt;0.891&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Italy&lt;/td&gt;
&lt;td&gt;0.883&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cyprus&lt;/td&gt;
&lt;td&gt;0.873&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Poland&lt;/td&gt;
&lt;td&gt;0.872&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Greece&lt;/td&gt;
&lt;td&gt;0.872&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lithuania&lt;/td&gt;
&lt;td&gt;0.869&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Slovakia&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Latvia&lt;/td&gt;
&lt;td&gt;0.854&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Portugal&lt;/td&gt;
&lt;td&gt;0.85&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chile&lt;/td&gt;
&lt;td&gt;0.847&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Croatia&lt;/td&gt;
&lt;td&gt;0.837&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Argentina&lt;/td&gt;
&lt;td&gt;0.83&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Estonia&lt;/td&gt;
&lt;td&gt;0.822&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Romania&lt;/td&gt;
&lt;td&gt;0.816&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bulgaria&lt;/td&gt;
&lt;td&gt;0.816&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uruguay&lt;/td&gt;
&lt;td&gt;0.808&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trinidad and Tobago&lt;/td&gt;
&lt;td&gt;0.799&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Panama&lt;/td&gt;
&lt;td&gt;0.795&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Costa Rica&lt;/td&gt;
&lt;td&gt;0.794&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mongolia&lt;/td&gt;
&lt;td&gt;0.735&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ghana&lt;/td&gt;
&lt;td&gt;0.596&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Look at that! My bet on Singapore paid off!&lt;br&gt;
I love simplicity, so I would like to take &lt;code&gt;0.9&lt;/code&gt; as the bottom line. One thing stopping me is that Microsoft has an office in Prague. I do not want to discard a chance to work there just because the number was slightly lower than I wanted. So let's take &lt;code&gt;0.891&lt;/code&gt; as the bottom line to let Czech Republic pass to the next stage.&lt;/p&gt;

&lt;p&gt;We are now left with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Norway&lt;/li&gt;
&lt;li&gt;Switzerland&lt;/li&gt;
&lt;li&gt;Ireland&lt;/li&gt;
&lt;li&gt;Germany&lt;/li&gt;
&lt;li&gt;Iceland&lt;/li&gt;
&lt;li&gt;Sweden&lt;/li&gt;
&lt;li&gt;Singapore&lt;/li&gt;
&lt;li&gt;Netherlands&lt;/li&gt;
&lt;li&gt;Denmark&lt;/li&gt;
&lt;li&gt;Finland&lt;/li&gt;
&lt;li&gt;Canada&lt;/li&gt;
&lt;li&gt;New Zealand&lt;/li&gt;
&lt;li&gt;United States&lt;/li&gt;
&lt;li&gt;United Kingdom&lt;/li&gt;
&lt;li&gt;Belgium&lt;/li&gt;
&lt;li&gt;Japan&lt;/li&gt;
&lt;li&gt;Austria&lt;/li&gt;
&lt;li&gt;Australia&lt;/li&gt;
&lt;li&gt;Luxembourg&lt;/li&gt;
&lt;li&gt;South Korea&lt;/li&gt;
&lt;li&gt;Slovenia&lt;/li&gt;
&lt;li&gt;Spain&lt;/li&gt;
&lt;li&gt;France&lt;/li&gt;
&lt;li&gt;Czech Republic&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Filter by population
&lt;/h2&gt;

&lt;p&gt;Luxembourg and Iceland show great results so far. Population there is &lt;code&gt;0.62&lt;/code&gt; and &lt;code&gt;0.35&lt;/code&gt; millions of people respectfully. I reckon these countries might easily be by-invitation-only clubs that do not welcome new members. To make filtering a bit easier, let's assume that we will only consider countries with 5 million of people and greater. Time to say goodbye to Luxembourg, Iceland, Slovenia, and New Zealand.&lt;/p&gt;

&lt;p&gt;Here is what is left:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Norway&lt;/li&gt;
&lt;li&gt;Switzerland&lt;/li&gt;
&lt;li&gt;Ireland&lt;/li&gt;
&lt;li&gt;Germany&lt;/li&gt;
&lt;li&gt;Sweden&lt;/li&gt;
&lt;li&gt;Singapore&lt;/li&gt;
&lt;li&gt;Netherlands&lt;/li&gt;
&lt;li&gt;Denmark&lt;/li&gt;
&lt;li&gt;Finland&lt;/li&gt;
&lt;li&gt;Canada&lt;/li&gt;
&lt;li&gt;United States&lt;/li&gt;
&lt;li&gt;United Kingdom&lt;/li&gt;
&lt;li&gt;Belgium&lt;/li&gt;
&lt;li&gt;Japan&lt;/li&gt;
&lt;li&gt;Austria&lt;/li&gt;
&lt;li&gt;Australia&lt;/li&gt;
&lt;li&gt;South Korea&lt;/li&gt;
&lt;li&gt;Spain&lt;/li&gt;
&lt;li&gt;France&lt;/li&gt;
&lt;li&gt;Czech Republic&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Filter by corruption
&lt;/h2&gt;

&lt;p&gt;We will rely on the data by &lt;a href="https://www.transparency.org/en/cpi/2019/results/table"&gt;Transparency International Corruption Perceptions Index&lt;/a&gt;. &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Country&lt;/th&gt;
&lt;th&gt;Corruption Perceptions Index&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Denmark&lt;/td&gt;
&lt;td&gt;87&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finland&lt;/td&gt;
&lt;td&gt;86&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switzerland&lt;/td&gt;
&lt;td&gt;85&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Singapore&lt;/td&gt;
&lt;td&gt;85&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sweden&lt;/td&gt;
&lt;td&gt;85&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Australia&lt;/td&gt;
&lt;td&gt;85&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Norway&lt;/td&gt;
&lt;td&gt;84&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Netherlands&lt;/td&gt;
&lt;td&gt;82&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Germany&lt;/td&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United Kingdom&lt;/td&gt;
&lt;td&gt;77&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Austria&lt;/td&gt;
&lt;td&gt;77&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canada&lt;/td&gt;
&lt;td&gt;77&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Belgium&lt;/td&gt;
&lt;td&gt;75&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ireland&lt;/td&gt;
&lt;td&gt;74&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Japan&lt;/td&gt;
&lt;td&gt;73&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;France&lt;/td&gt;
&lt;td&gt;69&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United States&lt;/td&gt;
&lt;td&gt;69&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spain&lt;/td&gt;
&lt;td&gt;62&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;South Korea&lt;/td&gt;
&lt;td&gt;59&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Czech Republic&lt;/td&gt;
&lt;td&gt;56&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I wish I could take &lt;code&gt;75&lt;/code&gt; as the bottom line, but it would effectively filter out the USA with tons of amazing work opportunities. Let's adapt our wishes to reality and say that &lt;code&gt;69&lt;/code&gt; also sounds not that bad.&lt;/p&gt;

&lt;p&gt;We now have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Denmark&lt;/li&gt;
&lt;li&gt;Finland&lt;/li&gt;
&lt;li&gt;Switzerland&lt;/li&gt;
&lt;li&gt;Singapore&lt;/li&gt;
&lt;li&gt;Sweden&lt;/li&gt;
&lt;li&gt;Australia&lt;/li&gt;
&lt;li&gt;Norway&lt;/li&gt;
&lt;li&gt;Netherlands&lt;/li&gt;
&lt;li&gt;Germany&lt;/li&gt;
&lt;li&gt;United Kingdom&lt;/li&gt;
&lt;li&gt;Austria&lt;/li&gt;
&lt;li&gt;Canada&lt;/li&gt;
&lt;li&gt;Belgium&lt;/li&gt;
&lt;li&gt;Ireland&lt;/li&gt;
&lt;li&gt;Japan&lt;/li&gt;
&lt;li&gt;France&lt;/li&gt;
&lt;li&gt;United States&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Economy
&lt;/h2&gt;

&lt;p&gt;As the primary economic filter, we will use &lt;a href="https://www.heritage.org/index/ranking"&gt;Index of Economic Freedom&lt;/a&gt;. It rates inviolability of private property, the effectiveness of the jurisdictional system, the amount of national debt, taxes, business opportunities, and my beloved market freedom.&lt;br&gt;
The creators of the index mark countries as &lt;code&gt;Free&lt;/code&gt; if they score over &lt;code&gt;80&lt;/code&gt;. They say the countries are &lt;code&gt;Mostly Free&lt;/code&gt; if they score over &lt;code&gt;70&lt;/code&gt;. Let's leave only &lt;code&gt;Free&lt;/code&gt; and &lt;code&gt;Mostly Free&lt;/code&gt; ones.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Country&lt;/th&gt;
&lt;th&gt;Economic Freedom&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Singapore&lt;/td&gt;
&lt;td&gt;89.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Australia&lt;/td&gt;
&lt;td&gt;82.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switzerland&lt;/td&gt;
&lt;td&gt;82&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ireland&lt;/td&gt;
&lt;td&gt;80.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United Kingdom&lt;/td&gt;
&lt;td&gt;79.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Denmark&lt;/td&gt;
&lt;td&gt;78.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canada&lt;/td&gt;
&lt;td&gt;78.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Netherlands&lt;/td&gt;
&lt;td&gt;77&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United States&lt;/td&gt;
&lt;td&gt;76.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finland&lt;/td&gt;
&lt;td&gt;75.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sweden&lt;/td&gt;
&lt;td&gt;74.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Germany&lt;/td&gt;
&lt;td&gt;73.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Norway&lt;/td&gt;
&lt;td&gt;73.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Austria&lt;/td&gt;
&lt;td&gt;73.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Japan&lt;/td&gt;
&lt;td&gt;73.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Belgium&lt;/td&gt;
&lt;td&gt;68.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;France&lt;/td&gt;
&lt;td&gt;66&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Farewell, Belgium, and France.&lt;/p&gt;

&lt;p&gt;Nd to the next stage pass:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Singapore&lt;/li&gt;
&lt;li&gt;Australia&lt;/li&gt;
&lt;li&gt;Switzerland&lt;/li&gt;
&lt;li&gt;Ireland&lt;/li&gt;
&lt;li&gt;United Kingdom&lt;/li&gt;
&lt;li&gt;Denmark&lt;/li&gt;
&lt;li&gt;Canada&lt;/li&gt;
&lt;li&gt;Netherlands&lt;/li&gt;
&lt;li&gt;United States&lt;/li&gt;
&lt;li&gt;Finland&lt;/li&gt;
&lt;li&gt;Sweden&lt;/li&gt;
&lt;li&gt;Germany&lt;/li&gt;
&lt;li&gt;Norway&lt;/li&gt;
&lt;li&gt;Austria&lt;/li&gt;
&lt;li&gt;Japan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You will be surprised, but even at this stage no poor countries left. In all of the above gross national income per capita (smart word for "person") is over $40000. Average salary is also above $40000.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Country&lt;/th&gt;
&lt;th&gt;&lt;a href="https://data.oecd.org/natincome/gross-national-income.htm"&gt;Gross National Income&lt;/a&gt;&lt;/th&gt;
&lt;th&gt;&lt;a href="https://stats.oecd.org/Index.aspx?DataSetCode=AV_AN_WAGE"&gt;Average Salary&lt;/a&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Singapore&lt;/td&gt;
&lt;td&gt;91557&lt;/td&gt;
&lt;td&gt;53244&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Norway&lt;/td&gt;
&lt;td&gt;70525&lt;/td&gt;
&lt;td&gt;50956&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switzerland&lt;/td&gt;
&lt;td&gt;69545&lt;/td&gt;
&lt;td&gt;64109&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United States&lt;/td&gt;
&lt;td&gt;66637&lt;/td&gt;
&lt;td&gt;63093&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ireland&lt;/td&gt;
&lt;td&gt;66342&lt;/td&gt;
&lt;td&gt;47952&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Denmark&lt;/td&gt;
&lt;td&gt;58700&lt;/td&gt;
&lt;td&gt;55253&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Netherlands&lt;/td&gt;
&lt;td&gt;58135&lt;/td&gt;
&lt;td&gt;54262&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Austria&lt;/td&gt;
&lt;td&gt;56733&lt;/td&gt;
&lt;td&gt;50868&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Germany&lt;/td&gt;
&lt;td&gt;55979&lt;/td&gt;
&lt;td&gt;49813&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sweden&lt;/td&gt;
&lt;td&gt;54742&lt;/td&gt;
&lt;td&gt;44196&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Australia&lt;/td&gt;
&lt;td&gt;51924&lt;/td&gt;
&lt;td&gt;53349&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finland&lt;/td&gt;
&lt;td&gt;49540&lt;/td&gt;
&lt;td&gt;44111&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canada&lt;/td&gt;
&lt;td&gt;49431&lt;/td&gt;
&lt;td&gt;48849&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United Kingdom&lt;/td&gt;
&lt;td&gt;46253&lt;/td&gt;
&lt;td&gt;44770&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Japan&lt;/td&gt;
&lt;td&gt;42872&lt;/td&gt;
&lt;td&gt;40573&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As you might remember, Japan scored poorly on corruption (&lt;code&gt;73&lt;/code&gt;). Let's leave it out by the confluence of factors.&lt;/p&gt;

&lt;h2&gt;
  
  
  IT job market
&lt;/h2&gt;

&lt;p&gt;Let's take a number of job openings on &lt;a href="https://www.linkedin.com/jobs/search/?f_F=it"&gt;LinkedIn&lt;/a&gt; and divide it by &lt;a href="https://www.census.gov/popclock/world/"&gt;the population&lt;/a&gt; in millions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Country&lt;/th&gt;
&lt;th&gt;Total number of IT job openings&lt;/th&gt;
&lt;th&gt;Number of IT job openings per one million people&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Netherlands&lt;/td&gt;
&lt;td&gt;128194&lt;/td&gt;
&lt;td&gt;7410&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Germany&lt;/td&gt;
&lt;td&gt;480737&lt;/td&gt;
&lt;td&gt;5994&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switzerland&lt;/td&gt;
&lt;td&gt;37043&lt;/td&gt;
&lt;td&gt;4410&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Singapore&lt;/td&gt;
&lt;td&gt;22105&lt;/td&gt;
&lt;td&gt;3565&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ireland&lt;/td&gt;
&lt;td&gt;12972&lt;/td&gt;
&lt;td&gt;2495&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United States&lt;/td&gt;
&lt;td&gt;804444&lt;/td&gt;
&lt;td&gt;2439&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United Kingdom&lt;/td&gt;
&lt;td&gt;159013&lt;/td&gt;
&lt;td&gt;2417&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Austria&lt;/td&gt;
&lt;td&gt;16237&lt;/td&gt;
&lt;td&gt;1824&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canada&lt;/td&gt;
&lt;td&gt;49320&lt;/td&gt;
&lt;td&gt;1308&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sweden&lt;/td&gt;
&lt;td&gt;11453&lt;/td&gt;
&lt;td&gt;1123&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Australia&lt;/td&gt;
&lt;td&gt;20313&lt;/td&gt;
&lt;td&gt;797&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Denmark&lt;/td&gt;
&lt;td&gt;3695&lt;/td&gt;
&lt;td&gt;626&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finland&lt;/td&gt;
&lt;td&gt;2244&lt;/td&gt;
&lt;td&gt;401&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Norway&lt;/td&gt;
&lt;td&gt;1334&lt;/td&gt;
&lt;td&gt;243&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Based on the numbers, I feel the urge to discard Norway, Finland, Denmark, and Australia. However, Australia has offices of several major IT corporations at once - Amazon, Google, Microsoft, Atlassian. So we will let Australia keep its place.&lt;/p&gt;

&lt;p&gt;Results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Netherlands&lt;/li&gt;
&lt;li&gt;Germany&lt;/li&gt;
&lt;li&gt;Switzerland&lt;/li&gt;
&lt;li&gt;Singapore&lt;/li&gt;
&lt;li&gt;Ireland&lt;/li&gt;
&lt;li&gt;United States&lt;/li&gt;
&lt;li&gt;United Kingdom&lt;/li&gt;
&lt;li&gt;Austria&lt;/li&gt;
&lt;li&gt;Canada&lt;/li&gt;
&lt;li&gt;Sweden&lt;/li&gt;
&lt;li&gt;Australia&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Science
&lt;/h2&gt;

&lt;p&gt;Let's take the adjusted number of articles (Share) from, &lt;a href="https://www.natureindex.com/country-outputs/generate/All/global/All/score"&gt;Nature Index&lt;/a&gt; and divide it by the population in millions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Country&lt;/th&gt;
&lt;th&gt;Total number of articles&lt;/th&gt;
&lt;th&gt;NUmber of articles per one million people&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Switzerland&lt;/td&gt;
&lt;td&gt;1467.12&lt;/td&gt;
&lt;td&gt;175&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Singapore&lt;/td&gt;
&lt;td&gt;632.26&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United States&lt;/td&gt;
&lt;td&gt;20462.07&lt;/td&gt;
&lt;td&gt;62&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sweden&lt;/td&gt;
&lt;td&gt;637.11&lt;/td&gt;
&lt;td&gt;62&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Germany&lt;/td&gt;
&lt;td&gt;4602.86&lt;/td&gt;
&lt;td&gt;57&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United Kingdom&lt;/td&gt;
&lt;td&gt;3762&lt;/td&gt;
&lt;td&gt;57&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Netherlands&lt;/td&gt;
&lt;td&gt;963.86&lt;/td&gt;
&lt;td&gt;56&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Australia&lt;/td&gt;
&lt;td&gt;1275.34&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canada&lt;/td&gt;
&lt;td&gt;1635.2&lt;/td&gt;
&lt;td&gt;43&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Austria&lt;/td&gt;
&lt;td&gt;363.05&lt;/td&gt;
&lt;td&gt;41&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ireland&lt;/td&gt;
&lt;td&gt;122.23&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Ireland - you are the weakest link. Bye! &lt;/p&gt;

&lt;p&gt;Our finalists:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Switzerland&lt;/li&gt;
&lt;li&gt;Singapore&lt;/li&gt;
&lt;li&gt;United States&lt;/li&gt;
&lt;li&gt;Sweden&lt;/li&gt;
&lt;li&gt;Germany&lt;/li&gt;
&lt;li&gt;United Kingdom&lt;/li&gt;
&lt;li&gt;Netherlands&lt;/li&gt;
&lt;li&gt;Australia&lt;/li&gt;
&lt;li&gt;Canada&lt;/li&gt;
&lt;li&gt;Austria&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apart from data we have used for filtering, let's add a few other sources::&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www3.weforum.org/docs/WEF_TheGlobalCompetitivenessReport2019.pdf"&gt;Economic Competitiveness&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://atlas.cid.harvard.edu/rankings"&gt;Economic Complexity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dataunodc.un.org/content/homicide-rate-option-2"&gt;Homicide rate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sipri.org/databases/milex"&gt;Military budget&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ef.com/wwen/epi/"&gt;English proficiency&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mipex.eu/play/"&gt;Migrant Integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.passportindex.org/byRank.php?f="&gt;Passport Power&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://taxfoundation.org/publications/international-tax-competitiveness-index/"&gt;Tax Competitiveness&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stats.oecd.org/index.aspx?DataSetCode=TABLE_I6#"&gt;Tax (%) for average income&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stats.oecd.org/index.aspx?DataSetCode=TABLE_I6#"&gt;Tax (%) for 133% of average income&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stats.oecd.org/index.aspx?DataSetCode=TABLE_I6#"&gt;Tax (%) for 166% of average income&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://docs.google.com/spreadsheets/d/1ptwI1So-BxxeGKyoMaIHlFm-AjsxjTXu0tZkkGjqlv0/edit#gid=0&amp;amp;fvid=1982795853"&gt;Finalists as a filtered view in Google Docs&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Country&lt;/th&gt;
&lt;th&gt;Freedom House&lt;/th&gt;
&lt;th&gt;Corruption Perceptions&lt;/th&gt;
&lt;th&gt;Economic Freedom&lt;/th&gt;
&lt;th&gt;Economic Competitiveness&lt;/th&gt;
&lt;th&gt;Economic Complexity&lt;/th&gt;
&lt;th&gt;Human Development&lt;/th&gt;
&lt;th&gt;Gross National Income per capita ($)&lt;/th&gt;
&lt;th&gt;Average wage&lt;/th&gt;
&lt;th&gt;Homicide rate&lt;/th&gt;
&lt;th&gt;Military budget ($m)&lt;/th&gt;
&lt;th&gt;Population (millions)&lt;/th&gt;
&lt;th&gt;Total number of IT jobs&lt;/th&gt;
&lt;th&gt;Number of IT jobs per 1 million people&lt;/th&gt;
&lt;th&gt;English proficiency&lt;/th&gt;
&lt;th&gt;Migrant Integration&lt;/th&gt;
&lt;th&gt;Passport Power&lt;/th&gt;
&lt;th&gt;Total number of scientific articles&lt;/th&gt;
&lt;th&gt;Number of scientific jobs per 1 million people&lt;/th&gt;
&lt;th&gt;Tax Competitiveness&lt;/th&gt;
&lt;th&gt;Tax (%) for average income&lt;/th&gt;
&lt;th&gt;Tax (%) for 133% of average income&lt;/th&gt;
&lt;th&gt;Tax (%) for 166% of average income&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Netherlands&lt;/td&gt;
&lt;td&gt;99&lt;/td&gt;
&lt;td&gt;82&lt;/td&gt;
&lt;td&gt;77&lt;/td&gt;
&lt;td&gt;82.4&lt;/td&gt;
&lt;td&gt;0.98&lt;/td&gt;
&lt;td&gt;0.933&lt;/td&gt;
&lt;td&gt;58135&lt;/td&gt;
&lt;td&gt;54262&lt;/td&gt;
&lt;td&gt;0.58&lt;/td&gt;
&lt;td&gt;12059&lt;/td&gt;
&lt;td&gt;17.3&lt;/td&gt;
&lt;td&gt;128194&lt;/td&gt;
&lt;td&gt;7410&lt;/td&gt;
&lt;td&gt;70.27&lt;/td&gt;
&lt;td&gt;61&lt;/td&gt;
&lt;td&gt;115&lt;/td&gt;
&lt;td&gt;963.86&lt;/td&gt;
&lt;td&gt;56&lt;/td&gt;
&lt;td&gt;72.5&lt;/td&gt;
&lt;td&gt;37.3&lt;/td&gt;
&lt;td&gt;39.8&lt;/td&gt;
&lt;td&gt;42.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Germany&lt;/td&gt;
&lt;td&gt;94&lt;/td&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;73.5&lt;/td&gt;
&lt;td&gt;81.8&lt;/td&gt;
&lt;td&gt;2.09&lt;/td&gt;
&lt;td&gt;0.939&lt;/td&gt;
&lt;td&gt;55979&lt;/td&gt;
&lt;td&gt;49813&lt;/td&gt;
&lt;td&gt;0.95&lt;/td&gt;
&lt;td&gt;49276&lt;/td&gt;
&lt;td&gt;80.2&lt;/td&gt;
&lt;td&gt;480737&lt;/td&gt;
&lt;td&gt;5994&lt;/td&gt;
&lt;td&gt;63.77&lt;/td&gt;
&lt;td&gt;63&lt;/td&gt;
&lt;td&gt;116&lt;/td&gt;
&lt;td&gt;4602.86&lt;/td&gt;
&lt;td&gt;57&lt;/td&gt;
&lt;td&gt;66.9&lt;/td&gt;
&lt;td&gt;49.4&lt;/td&gt;
&lt;td&gt;50.8&lt;/td&gt;
&lt;td&gt;51&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switzerland&lt;/td&gt;
&lt;td&gt;96&lt;/td&gt;
&lt;td&gt;85&lt;/td&gt;
&lt;td&gt;82&lt;/td&gt;
&lt;td&gt;82.3&lt;/td&gt;
&lt;td&gt;2.17&lt;/td&gt;
&lt;td&gt;0.946&lt;/td&gt;
&lt;td&gt;69545&lt;/td&gt;
&lt;td&gt;64109&lt;/td&gt;
&lt;td&gt;0.59&lt;/td&gt;
&lt;td&gt;5179&lt;/td&gt;
&lt;td&gt;8.4&lt;/td&gt;
&lt;td&gt;37043&lt;/td&gt;
&lt;td&gt;4410&lt;/td&gt;
&lt;td&gt;60.23&lt;/td&gt;
&lt;td&gt;46&lt;/td&gt;
&lt;td&gt;116&lt;/td&gt;
&lt;td&gt;1467.12&lt;/td&gt;
&lt;td&gt;175&lt;/td&gt;
&lt;td&gt;79.5&lt;/td&gt;
&lt;td&gt;22.3&lt;/td&gt;
&lt;td&gt;24.7&lt;/td&gt;
&lt;td&gt;26.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Singapore&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;85&lt;/td&gt;
&lt;td&gt;89.4&lt;/td&gt;
&lt;td&gt;84.8&lt;/td&gt;
&lt;td&gt;1.85&lt;/td&gt;
&lt;td&gt;0.935&lt;/td&gt;
&lt;td&gt;91557&lt;/td&gt;
&lt;td&gt;53244&lt;/td&gt;
&lt;td&gt;0.16&lt;/td&gt;
&lt;td&gt;11211&lt;/td&gt;
&lt;td&gt;6.2&lt;/td&gt;
&lt;td&gt;22105&lt;/td&gt;
&lt;td&gt;3565&lt;/td&gt;
&lt;td&gt;66.82&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;81&lt;/td&gt;
&lt;td&gt;632.26&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United States&lt;/td&gt;
&lt;td&gt;86&lt;/td&gt;
&lt;td&gt;69&lt;/td&gt;
&lt;td&gt;76.6&lt;/td&gt;
&lt;td&gt;83.7&lt;/td&gt;
&lt;td&gt;1.55&lt;/td&gt;
&lt;td&gt;0.92&lt;/td&gt;
&lt;td&gt;66637&lt;/td&gt;
&lt;td&gt;63093&lt;/td&gt;
&lt;td&gt;4.96&lt;/td&gt;
&lt;td&gt;731751&lt;/td&gt;
&lt;td&gt;329.8&lt;/td&gt;
&lt;td&gt;804444&lt;/td&gt;
&lt;td&gt;2439&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;83&lt;/td&gt;
&lt;td&gt;20462.07&lt;/td&gt;
&lt;td&gt;62&lt;/td&gt;
&lt;td&gt;63.7&lt;/td&gt;
&lt;td&gt;29.8&lt;/td&gt;
&lt;td&gt;32.5&lt;/td&gt;
&lt;td&gt;34.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United Kingdom&lt;/td&gt;
&lt;td&gt;94&lt;/td&gt;
&lt;td&gt;77&lt;/td&gt;
&lt;td&gt;79.3&lt;/td&gt;
&lt;td&gt;81.2&lt;/td&gt;
&lt;td&gt;1.51&lt;/td&gt;
&lt;td&gt;0.92&lt;/td&gt;
&lt;td&gt;46253&lt;/td&gt;
&lt;td&gt;44770&lt;/td&gt;
&lt;td&gt;1.2&lt;/td&gt;
&lt;td&gt;48650&lt;/td&gt;
&lt;td&gt;65.8&lt;/td&gt;
&lt;td&gt;159013&lt;/td&gt;
&lt;td&gt;2417&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;56&lt;/td&gt;
&lt;td&gt;116&lt;/td&gt;
&lt;td&gt;3762&lt;/td&gt;
&lt;td&gt;57&lt;/td&gt;
&lt;td&gt;60.1&lt;/td&gt;
&lt;td&gt;30.9&lt;/td&gt;
&lt;td&gt;33.9&lt;/td&gt;
&lt;td&gt;37.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Austria&lt;/td&gt;
&lt;td&gt;93&lt;/td&gt;
&lt;td&gt;77&lt;/td&gt;
&lt;td&gt;73.3&lt;/td&gt;
&lt;td&gt;76.6&lt;/td&gt;
&lt;td&gt;1.81&lt;/td&gt;
&lt;td&gt;0.914&lt;/td&gt;
&lt;td&gt;56733&lt;/td&gt;
&lt;td&gt;50868&lt;/td&gt;
&lt;td&gt;0.97&lt;/td&gt;
&lt;td&gt;3237&lt;/td&gt;
&lt;td&gt;8.9&lt;/td&gt;
&lt;td&gt;16237&lt;/td&gt;
&lt;td&gt;1824&lt;/td&gt;
&lt;td&gt;64.11&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;116&lt;/td&gt;
&lt;td&gt;363.05&lt;/td&gt;
&lt;td&gt;41&lt;/td&gt;
&lt;td&gt;71.4&lt;/td&gt;
&lt;td&gt;47.9&lt;/td&gt;
&lt;td&gt;50.8&lt;/td&gt;
&lt;td&gt;51&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canada&lt;/td&gt;
&lt;td&gt;98&lt;/td&gt;
&lt;td&gt;77&lt;/td&gt;
&lt;td&gt;78.2&lt;/td&gt;
&lt;td&gt;79.6&lt;/td&gt;
&lt;td&gt;0.65&lt;/td&gt;
&lt;td&gt;0.922&lt;/td&gt;
&lt;td&gt;49431&lt;/td&gt;
&lt;td&gt;48849&lt;/td&gt;
&lt;td&gt;1.76&lt;/td&gt;
&lt;td&gt;22197&lt;/td&gt;
&lt;td&gt;37.7&lt;/td&gt;
&lt;td&gt;49320&lt;/td&gt;
&lt;td&gt;1308&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;70&lt;/td&gt;
&lt;td&gt;115&lt;/td&gt;
&lt;td&gt;1635.2&lt;/td&gt;
&lt;td&gt;43&lt;/td&gt;
&lt;td&gt;67&lt;/td&gt;
&lt;td&gt;30.5&lt;/td&gt;
&lt;td&gt;31.2&lt;/td&gt;
&lt;td&gt;31.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sweden&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;85&lt;/td&gt;
&lt;td&gt;74.9&lt;/td&gt;
&lt;td&gt;81.2&lt;/td&gt;
&lt;td&gt;1.7&lt;/td&gt;
&lt;td&gt;0.937&lt;/td&gt;
&lt;td&gt;54742&lt;/td&gt;
&lt;td&gt;44196&lt;/td&gt;
&lt;td&gt;1.08&lt;/td&gt;
&lt;td&gt;5290&lt;/td&gt;
&lt;td&gt;10.2&lt;/td&gt;
&lt;td&gt;11453&lt;/td&gt;
&lt;td&gt;1123&lt;/td&gt;
&lt;td&gt;68.74&lt;/td&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;115&lt;/td&gt;
&lt;td&gt;637.11&lt;/td&gt;
&lt;td&gt;62&lt;/td&gt;
&lt;td&gt;75.5&lt;/td&gt;
&lt;td&gt;42.7&lt;/td&gt;
&lt;td&gt;46.8&lt;/td&gt;
&lt;td&gt;51&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Australia&lt;/td&gt;
&lt;td&gt;97&lt;/td&gt;
&lt;td&gt;85&lt;/td&gt;
&lt;td&gt;82.6&lt;/td&gt;
&lt;td&gt;78.7&lt;/td&gt;
&lt;td&gt;1.81&lt;/td&gt;
&lt;td&gt;0.914&lt;/td&gt;
&lt;td&gt;51924&lt;/td&gt;
&lt;td&gt;53349&lt;/td&gt;
&lt;td&gt;0.89&lt;/td&gt;
&lt;td&gt;25912&lt;/td&gt;
&lt;td&gt;25.5&lt;/td&gt;
&lt;td&gt;20313&lt;/td&gt;
&lt;td&gt;797&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;66&lt;/td&gt;
&lt;td&gt;116&lt;/td&gt;
&lt;td&gt;1275.34&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;76.4&lt;/td&gt;
&lt;td&gt;27.9&lt;/td&gt;
&lt;td&gt;32.1&lt;/td&gt;
&lt;td&gt;34.4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Immigration policy
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Information below applies to Russian citizens only! Please, double-check it for your country!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Europe
&lt;/h3&gt;

&lt;p&gt;They have the coolest thing ever - &lt;a href="https://en.wikipedia.org/wiki/Blue_Card_(European_Union)"&gt;Blue Card&lt;/a&gt;. It is a work permit that works across whole European Union except Denmark and Ireland. You need to have a bachelor's degree. There is a solid salary threshold. Spouse CAN work or study.&lt;br&gt;
Apart from the Blue card, each country has its own program for skilled immigrants with lower thresholds. However, the primary benefit of the Blue Card is that you will be able to relocate inside of the European Union and still meet the requirements of &lt;a href="https://www.eubluecard.nl/comparison/benefits-eu-blue-card"&gt;EC-long term resident&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Blu Card works for the following countries out of our list of finalists:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Netherlands&lt;/li&gt;
&lt;li&gt;Germany&lt;/li&gt;
&lt;li&gt;Austria&lt;/li&gt;
&lt;li&gt;Sweden&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that Switzerland does not want your Blue Card! To work there you need to get the local Swiss Work Permit. Your spouse sill CAN work or study.&lt;/p&gt;

&lt;h3&gt;
  
  
  Singapore
&lt;/h3&gt;

&lt;p&gt;They have &lt;code&gt;Employment Pass&lt;/code&gt;. You need to have a job with the local company. Spouse CAN work or study.&lt;/p&gt;

&lt;h3&gt;
  
  
  UK
&lt;/h3&gt;

&lt;p&gt;The most common way to enter the country is via &lt;code&gt;General work visa (Tier 2)&lt;/code&gt;. You need a contract with an employer. Your spouse CAN work or study.&lt;br&gt;
There is another option - &lt;code&gt;Global talent visa&lt;/code&gt;. If you are a conference star, a book author, regularly publish research papers, you have a shot if you find a good lawyer. You do not need to win a Nobel, but have to have something that makes you stand out. With &lt;code&gt;Global talent visa&lt;/code&gt; you will no longer depend on your employer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Australia
&lt;/h3&gt;

&lt;p&gt;If you get an offer from a major corporation, you will, most probably, wind up with &lt;code&gt;TSS 482&lt;/code&gt; visa. It is a work permit linked to your employer. You can try to work around it by getting &lt;code&gt;Skilled independent visa&lt;/code&gt;, but it has an extensive limited queue. With &lt;code&gt;Skilled independent visa&lt;/code&gt; you will no longer be linked to your employer. It is no uncommon to enter the country with &lt;code&gt;TSS 482&lt;/code&gt; and get &lt;code&gt;Skilled independent visa&lt;/code&gt; later. This way you will have a higher chance of getting the one because the previous experience of working for an Australian employer moves you up the queue.&lt;br&gt;
For both visas, your spouse CAN work or study.&lt;/p&gt;

&lt;h3&gt;
  
  
  USA
&lt;/h3&gt;

&lt;p&gt;Most of the alien talent comes via &lt;code&gt;H1-B&lt;/code&gt; visa. It has a yearly limit. If the number of applications exceeds it, almighty random decides who gets a visa. There are plenty of stories where people tell they got an offer, but could not get in because of this limit.&lt;br&gt;
You could get in via &lt;code&gt;O1&lt;/code&gt;, but it has more or less the same requirements as &lt;code&gt;Global talent visa&lt;/code&gt; in the UK.&lt;br&gt;
With both of these options, your spouse CANNOT work or study.&lt;br&gt;
There is the only way not to make your spouse give up their career when you move - &lt;code&gt;L1&lt;/code&gt; visa, but there is a catch. The visa is meant for corporations to move their existing employees from one location to another within the US. You have to work for at least 1 year in a different office of the company outside the US to be eligible for &lt;code&gt;L1&lt;/code&gt; visa. The visa is linked to your employer.&lt;br&gt;
This is not the end of the story. The USA is the only country from the list, where you will need your employer to sponsor your permanent residence permit (&lt;code&gt;Green card&lt;/code&gt;). It is not true for all cases, but for over 70% of them.&lt;br&gt;
To get your &lt;code&gt;Green card&lt;/code&gt;, with a few exceptions, you, as a skilled professional, have 3 options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EB1 (Priority Workers)&lt;/li&gt;
&lt;li&gt;EB2 (Professionals Holding Advanced Degrees or Persons of Exceptional Ability)&lt;/li&gt;
&lt;li&gt;EB3 (Skilled Workers, Professionals, and Other Workers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can apply for &lt;code&gt;EB1&lt;/code&gt; and &lt;code&gt;EB2&lt;/code&gt; yourself. At the same time, your employer can sponsor them for you. &lt;code&gt;EB3&lt;/code&gt; can only be sponsored.&lt;br&gt;
Let's take a look at &lt;a href="https://travel.state.gov/content/dam/visas/Statistics/AnnualReports/FY2019AnnualReport/FY19AnnualReport-TableVI-Part2.pdf"&gt;the numbers of issued visas in 2019&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EB1 - 2,223 &lt;/li&gt;
&lt;li&gt;EB2 - 3,497&lt;/li&gt;
&lt;li&gt;EB3 - 13,028&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if all &lt;code&gt;EB1&lt;/code&gt; and &lt;code&gt;EB2&lt;/code&gt; applications were self-petitioned, it means that the percentage of self-petitions is &lt;code&gt;30.5%&lt;/code&gt;. In real world, it should be even less.&lt;/p&gt;

&lt;h3&gt;
  
  
  Immigration policy cheatsheet
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Country&lt;/th&gt;
&lt;th&gt;Program&lt;/th&gt;
&lt;th&gt;Work permit for spouse&lt;/th&gt;
&lt;th&gt;Years to citizenship&lt;/th&gt;
&lt;th&gt;Multiple citizenship allowed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Netherlands&lt;/td&gt;
&lt;td&gt;Blue Card&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Germany&lt;/td&gt;
&lt;td&gt;Blue Card&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switzerland&lt;/td&gt;
&lt;td&gt;Swiss Work Permit&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Singapore&lt;/td&gt;
&lt;td&gt;Employment Pass&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;td&gt;~3&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United States&lt;/td&gt;
&lt;td&gt;H1-B or O-1 or L1&lt;/td&gt;
&lt;td&gt;--+&lt;/td&gt;
&lt;td&gt;~8&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;United Kingdom&lt;/td&gt;
&lt;td&gt;General work visa (Tier 2) or Global Talent visa&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Austria&lt;/td&gt;
&lt;td&gt;Blue Card&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canada&lt;/td&gt;
&lt;td&gt;Express Entry&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sweden&lt;/td&gt;
&lt;td&gt;Blue Card&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Australia&lt;/td&gt;
&lt;td&gt;TSS 482 or Skilled independent visa&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  For freelancers and contractors
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://immi.homeaffairs.gov.au/visas/getting-a-visa/visa-listing/skilled-independent-189/points-tested#Overview"&gt;Skilled independent visa in Australia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.migrationsverket.se/English/Private-individuals/Working-in-Sweden/Self-employment.html#"&gt;Self-employment residence permit in Sweden&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@yaminivongotham/german-self-employment-visa-for-non-eu-nationals-do-you-meet-all-the-requirements-c4b584ba88de"&gt;German Self-Employment Visa For Non-EU Nationals in Germany&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other countries have some programs for startups, but, as far as I understand, they are meant for bigger companies that create new jobs, not for lonely contractors and freelancers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;A few years ago, after several business trips, I was under the spell of the USA. At this moment, after visiting some other European countries, having collected objective numbers, having studied their immigration policies, I am doubtful I will try moving to the USA over the next years.&lt;/p&gt;

&lt;p&gt;Another important factor for me, personally, is the language you can get your Master's in. Next year my wife is going to graduate from the local Russian university with her Bachelor's in Architecture. Unfortunately, Switzerland does not provide a whole lot of Master's in Architecture in English. So we decide to rule it out.&lt;/p&gt;

&lt;p&gt;Here is my personal list of finalists:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Netherlands&lt;/li&gt;
&lt;li&gt;United Kingdom&lt;/li&gt;
&lt;li&gt;Canada&lt;/li&gt;
&lt;li&gt;Australia&lt;/li&gt;
&lt;li&gt;Sweden&lt;/li&gt;
&lt;li&gt;Singapore&lt;/li&gt;
&lt;li&gt;Germany&lt;/li&gt;
&lt;li&gt;Austria&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://docs.google.com/spreadsheets/d/1ptwI1So-BxxeGKyoMaIHlFm-AjsxjTXu0tZkkGjqlv0/edit#gid=0&amp;amp;fvid=188422351"&gt;Here is the same list as a filtered view in Google Spreadsheet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Title image is based on &lt;a href="https://www.deviantart.com/gio0989/art/World-map-wallpaper-127690139"&gt;https://www.deviantart.com/gio0989/art/World-map-wallpaper-127690139&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>immigration</category>
    </item>
    <item>
      <title>balalaika IT newsletter #12</title>
      <dc:creator>Andrey Goncharov</dc:creator>
      <pubDate>Sat, 17 Oct 2020 12:49:00 +0000</pubDate>
      <link>https://dev.to/balalaikait/balalaika-it-newsletter-12-5c0k</link>
      <guid>https://dev.to/balalaikait/balalaika-it-newsletter-12-5c0k</guid>
      <description>&lt;p&gt;&lt;strong&gt;This is our 12th newsletter. It means we are exploring the world of web development together for half a year. Sad to say, but there will not be any new issues of the newsletter for a long while. This is not a goodbye, rather a see you later. In the meantime, feel free to subscribe to the personal blogs of our curators: &lt;a href="https://medium.com/@apechkurov"&gt;https://medium.com/@apechkurov&lt;/a&gt; and &lt;a href="https://blog.goncharov.page/"&gt;https://blog.goncharov.page/&lt;/a&gt;. Let's stay in touch!&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  General
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://brandonharris.io/redshift-clickhouse-time-series/"&gt;In this post&lt;/a&gt; Brandon Harris shows us how to synthesize billions of rows of true time series data with an autoregressive component, and then explore it with ClickHouse, a big data scale OLAP RDBMS, all on AWS.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://duckdb.org/"&gt;DuckDB&lt;/a&gt; - an embeddable database for analytical workloads. &lt;/li&gt;
&lt;li&gt;Do you think mmap is faster than syscalls? Well, mmap could make your app run faster, but with strings attached. Sasha Fedorova gives us a &lt;a href="https://medium.com/@sasha_f/why-mmap-is-faster-than-system-calls-24718e75ab37"&gt;great in-depth explanation of how it works&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Distributed transactions are hard to implement right. In fact, many modern databases do not even bother with supporting them. FaunaDB is not one of those, as it builds transactions on top of &lt;a href="https://blog.acolyer.org/2019/03/29/calvin-fast-distributed-transactions-for-partitioned-database-systems/"&gt;Calvin&lt;/a&gt; algorithm.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Java
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Tiered JIT compilation can be found in multiple modern runtimes and JVM is no difference. Some time ago Rafael Winterhalter gave a nice &lt;a href="https://youtu.be/hjpzLXoUu1Y"&gt;talk&lt;/a&gt; on basic principles behind C2 compiler in HotSpot.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ForkJoinPool&lt;/code&gt; is available since Java 7 and used in several places within standard library, like parallel streams. It embeds many good ideas, like queue per worker and work stealing. If you are not familiar with these details, you may find them in the original &lt;a href="http://gee.cs.oswego.edu/dl/papers/fj.pdf"&gt;paper&lt;/a&gt; by Doug Lea.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  JavaScript
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Monomorphism is a very important definition for JIT compilation in JavaScript (and not only - see the above Rafael Winterhalter's talk). Several years ago, Vyacheslav Egorov wrote a brilliant &lt;a href="https://mrale.ph/blog/2015/01/11/whats-up-with-monomorphism.html"&gt;post&lt;/a&gt; to explain how V8's JIT compiler makes use of monomorphism.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/evanw/esbuild"&gt;esbuild&lt;/a&gt; - a new kid in the family of bundlers and minifiers. Written in Go. Claims to be extremely fast.&lt;/li&gt;
&lt;li&gt;NPM 7 is out. Lots of new goodies. Read more about them &lt;a href="https://dev.to/ruyadorno/announcing-npm7-16j0"&gt;here&lt;/a&gt;. &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>node</category>
      <category>java</category>
      <category>webdev</category>
    </item>
    <item>
      <title>balalaika IT newsletter #11</title>
      <dc:creator>Andrey Goncharov</dc:creator>
      <pubDate>Sat, 03 Oct 2020 09:23:14 +0000</pubDate>
      <link>https://dev.to/balalaikait/balalaika-it-newsletter-11-l86</link>
      <guid>https://dev.to/balalaikait/balalaika-it-newsletter-11-l86</guid>
      <description>&lt;p&gt;&lt;em&gt;If you like this newsletter subscribe to our new issues at &lt;a href="https://balalaikait.com/"&gt;https://balalaikait.com/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  General
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Joseph Gentle &lt;a href="https://josephg.com/blog/crdts-are-the-future/"&gt;tells us&lt;/a&gt; about the rise of CRDTs and why he thinks in could beat Operational Transform in many aspects.&lt;/li&gt;
&lt;li&gt;One who wants to write fast code has to understand weak and strong points of modern HW. Cliff Click gave a brilliant &lt;a href="https://youtu.be/OFgxAFdxYAQ"&gt;talk&lt;/a&gt; where he explains those points.&lt;/li&gt;
&lt;li&gt;Thread-Per-Core (TPC) is a valid approach for building high-performance server-side software. Yet, it is not trivial to build it right and has a lot of quirks. Some time ago, Redpanda team managed to use TCP architecture on top of Seastar framework and &lt;a href="https://vectorized.io/tpc-buffers/"&gt;shared&lt;/a&gt; their experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Java
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;James Gosling recently gave a lengthy &lt;a href="https://youtu.be/IT__Nrr3PNI"&gt;interview&lt;/a&gt; on Java, JVM, Emacs, and the early days of software engineering.&lt;/li&gt;
&lt;li&gt;Kotlin gets more and more popular among the JVM community. In this &lt;a href="https://blog.jetbrains.com/kotlin/2020/09/the-dark-secrets-of-fast-compilation-for-kotlin/"&gt;post&lt;/a&gt; Andrey Breslav sheds some light on the secrets of fast compilation in Kotlin.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  JavaScript
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Atomics module, which holds low-level synchronization primitives useful for Web Workers, keeps getting new features, like &lt;code&gt;Atomics.waitAsync&lt;/code&gt; method, which is currently at TC39's stage 3. V8 team wrote this &lt;a href="https://v8.dev/features/atomics"&gt;blog post&lt;/a&gt; to explain how Atomics can be used to write sync and async lock primitives.&lt;/li&gt;
&lt;li&gt;A great reminder that even high-level languages like JavaScript still suffer from memory leaks. &lt;a href="https://web.dev/detached-window-memory-leaks/"&gt;This time&lt;/a&gt; the case is kind of unusual  - detached windows. Be a good engineer and clean up after yourself!&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  React
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Kent C. Dodds &lt;a href="https://epicreact.dev/myths-about-useeffect/"&gt;tells us&lt;/a&gt; about common pitfalls and myths related to &lt;code&gt;useEffect&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>node</category>
      <category>java</category>
      <category>webdev</category>
    </item>
    <item>
      <title>balalaika IT newsletter #10</title>
      <dc:creator>Andrey Goncharov</dc:creator>
      <pubDate>Sat, 19 Sep 2020 14:26:41 +0000</pubDate>
      <link>https://dev.to/balalaikait/balalaika-it-newsletter-10-gf0</link>
      <guid>https://dev.to/balalaikait/balalaika-it-newsletter-10-gf0</guid>
      <description>&lt;p&gt;&lt;em&gt;If you like this newsletter subscribe to our new issues at &lt;a href="http://balalaikait.com/"&gt;http://balalaikait.com/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  General
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Back to basics. Do you remember how NAT traversal works? David Anderson wrote a &lt;a href="https://tailscale.com/blog/how-nat-traversal-works/"&gt;lengthy post&lt;/a&gt; with great visuals to remind you.&lt;/li&gt;
&lt;li&gt;Steve Yegge &lt;a href="https://medium.com/@steve.yegge/dear-google-cloud-your-deprecation-policy-is-killing-you-ee7525dc05dc"&gt;explains&lt;/a&gt; why vendor locks mixed with poor backward compatibility could make anyone question the benefits of a cloud. &lt;/li&gt;
&lt;li&gt;CockroachDB team recently introduced Pebble, an open-source K/V store inspired by RocksDB. Read this &lt;a href="https://www.cockroachlabs.com/blog/pebble-rocksdb-kv-store/"&gt;blog post&lt;/a&gt; to learn why they decided to do write it.&lt;/li&gt;
&lt;li&gt;Here is a great &lt;a href="https://idndx.com/2014/09/01/the-implementation-of-epoll-1/"&gt;series&lt;/a&gt; of blog posts on implementation of Linux &lt;code&gt;epoll&lt;/code&gt; for those of you who enjoy learning about kernel.&lt;/li&gt;
&lt;li&gt;If you're not familiar with Log-structured merge-tree data structure (aka LSM tree), but want to learn it, Tarantool DB team did a great job on documenting their &lt;a href="https://www.tarantool.io/en/doc/2.2/book/box/engines/#storing-data-with-vinyl"&gt;implementation&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Java
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Java 15 is &lt;a href="https://mail.openjdk.java.net/pipermail/announce/2020-September/000291.html"&gt;GA&lt;/a&gt;. It brings internal JVM changes (say, it disables biased locking), stable releases of low-latency garbage collectors (ZGC and Shenandoah), experimental APIs (such as Foreign-Memory Access API), and some more goodies.&lt;/li&gt;
&lt;li&gt;JNI has a fame of being "slow". But where the JNI overhead comes from and how critical it is? If you want to hear an explanation with all low-level details, here is a great &lt;a href="https://youtu.be/LoyBTqkSkZk"&gt;talk&lt;/a&gt; by Cliff Click.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  JavaScript
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Moment.js team now considers the library to be a legacy project in maintenance mode.  It is not dead, but it is indeed done. Read more about the reasoning &lt;a href="https://momentjs.com/docs/#/-project-status/"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  React
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Animations can make a site stand out. Or, they can just as easily kill the experience. Prasanjit Singh presents us with &lt;a href="https://css-tricks.com/ground-rules-for-web-animations/"&gt;the ground rules&lt;/a&gt; to master web animations.&lt;/li&gt;
&lt;li&gt;AVIF is a fairly new kid on the block and it promises us a new future of the leaner web with smaller images. JPEG is not dead yet, but we keep our fingers crossed. Here is a &lt;a href="https://jakearchibald.com/2020/avif-has-landed/"&gt;concise read&lt;/a&gt; from Jake Archibald on the new image format.&lt;/li&gt;
&lt;li&gt;Wondering how Facebook's Recoil works? Bennett Hardwick &lt;a href="https://bennetthardwick.com/blog/recoil-js-clone-from-scratch-in-100-lines/"&gt;explained it for you&lt;/a&gt; in 100 lines of code. &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>node</category>
      <category>java</category>
      <category>webdev</category>
    </item>
    <item>
      <title>balalaika IT newsletter #9</title>
      <dc:creator>Andrey Goncharov</dc:creator>
      <pubDate>Sat, 05 Sep 2020 10:58:01 +0000</pubDate>
      <link>https://dev.to/balalaikait/balalaika-it-newsletter-9-3h2e</link>
      <guid>https://dev.to/balalaikait/balalaika-it-newsletter-9-3h2e</guid>
      <description>&lt;p&gt;&lt;em&gt;If you like this newsletter subscribe to our new issues at &lt;a href="http://balalaikait.com/"&gt;http://balalaikait.com/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  General
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;CPU caching 101 from Nick Evanson. A &lt;a href="https://www.techspot.com/article/2066-cpu-l1-l2-l3-cache/"&gt;concise read&lt;/a&gt; about the fundamentals to get you started on how it works and why we need it. &lt;/li&gt;
&lt;li&gt;Over the last two years, Uber has attempted to reduce microservice complexity while still maintaining the benefits of a microservice architecture. With &lt;a href="https://eng.uber.com/microservice-architecture/"&gt;this blog post&lt;/a&gt; we hope to introduce our generalized approach to microservice architectures, which we refer to as “Domain-Oriented Microservice Architecture” (DOMA).&lt;/li&gt;
&lt;li&gt;Distributed locks are infamous for being hard to use right. Some time ago Hazelcast team introduced locks as a part of CP Subsystem based on Raft, a well-known consensus algorithm. This &lt;a href="https://hazelcast.com/blog/long-live-distributed-locks/"&gt;blog post&lt;/a&gt; describes potential pitfalls of distributed lock and how FencedLock solves them.&lt;/li&gt;
&lt;li&gt;Great engineers of the past have a lot to learn from. In &lt;a href="https://youtu.be/bo5WL5IQAd0"&gt;this talk&lt;/a&gt; explains how Erlang was designed to scale well on multicore machines.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  JavaScript
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;ES6 introduced many nice built-in collections, such as Map, Set, WeakMap, and WeakSet. Unfortunately, the spec does not put many requirements for concrete implementations. If you want to learn practical details of Maps and Sets implementation in V8, read this &lt;a href="https://itnext.io/v8-deep-dives-understanding-map-internals-45eb94a183df"&gt;blog post&lt;/a&gt; by Andrey P.&lt;/li&gt;
&lt;li&gt;JIT compiler is what makes V8 and other JS engines blazing fast. But exactly does it do? Watch this &lt;a href="https://youtu.be/p-iiEDtpy6I"&gt;talk&lt;/a&gt; by Franziska Hinkelmann to learn the answer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  React
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Is it possible to build SPAs purely in Rust and without writing a single line of JavaScript? The short answer is YES! Read about the experiment &lt;a href="http://www.sheshbabu.com/posts/rust-wasm-yew-single-page-application/"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Node.js
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;a href="https://httptoolkit.tech/blog/how-to-debug-node-segfaults"&gt;concise guide&lt;/a&gt; on how to debug segmentation faults in Node.js.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Java
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Did you know that &lt;code&gt;java.security.SecureRandom&lt;/code&gt; may be more or less secure depending on the configuration? This &lt;a href="https://tersesystems.com/blog/2015/12/17/the-right-way-to-use-securerandom/"&gt;blog post&lt;/a&gt; explains how to use it in the right way.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>node</category>
      <category>java</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to display a gazillion of metrics and keep your sanity</title>
      <dc:creator>Andrey Goncharov</dc:creator>
      <pubDate>Wed, 02 Sep 2020 12:29:06 +0000</pubDate>
      <link>https://dev.to/itnext/how-to-display-a-gazillion-of-metrics-and-keep-your-sanity-474b</link>
      <guid>https://dev.to/itnext/how-to-display-a-gazillion-of-metrics-and-keep-your-sanity-474b</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;I now have a new shiny blog. Read this article with the latest updates there &lt;a href="https://blog.goncharov.page/how-to-display-a-gazillion-of-metrics-and-keep-your-sanity"&gt;https://blog.goncharov.page/how-to-display-a-gazillion-of-metrics-and-keep-your-sanity&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Large scale equals distributed. Distributed equals inevitable complexity. Complexity at runtime equals extensive monitoring. At Hazelcast, doing distributed systems well is our bread and butter. It means we have no choice but to be huge fans of collecting all kinds of metrics to stay on guard of the data our users trust us with.&lt;br&gt;&lt;br&gt;
In Management Center &lt;code&gt;4.2020.08&lt;/code&gt;, we drastically changed the model of how we transfer the metric data from the cluster members to the Management Center, how we store it, and how we display it. In this post, we are going to talk about the latter bit of the triad.&lt;br&gt;&lt;br&gt;
We will discuss what to do when you want to display all the data at once, but your users have a limited number of monitors and only one pair of eyes. We will speculate about what users actually want to see when they look at a chart of a monitoring web app. We will go over different approaches to filter the data, and how an average, a median, and a definite integral play their key roles.    &lt;/p&gt;
&lt;h2&gt;
  
  
  4.2020.08! 4.2020.08! 4.2020.08! Why are we so excited?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are not interested in the new features of 4.2020.08 you can jump straight to what users want to see and why.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This release stands on 3 pillars:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enhanced UX for developers&lt;/li&gt;
&lt;li&gt;Unification with the Jet Management Center&lt;/li&gt;
&lt;li&gt;New metric engine&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Pillar 1. Enhanced UX for developers.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a6RLM0nE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/nze4wv0q3dmk8rtvsby5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a6RLM0nE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/nze4wv0q3dmk8rtvsby5.jpg" alt="UX meme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We love developers and loathe unnecessarily complex UIs. As you might know, Hazelcast Management Center supports &lt;a href="https://docs.hazelcast.org/docs/management-center/latest/manual/html/index.html#authentication-options"&gt;numerous security providers&lt;/a&gt;. Prior to 4.2020.08, the default choice was to use username/password based authentication, which we called the "Default" authentication. We are happy to present you with the "Dev Mode" security provider! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K1RWi2a9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fchdn8pquutvrkyu9yg3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K1RWi2a9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fchdn8pquutvrkyu9yg3.png" alt="Dev Mode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Internally, we call it "Just click save" security provider. Go ahead and &lt;a href="https://hub.docker.com/r/hazelcast/management-center/"&gt;try it yourself&lt;/a&gt;. We are keen to &lt;a href="https://slack.hazelcast.com/"&gt;hear back from you&lt;/a&gt;!&lt;/p&gt;
&lt;h3&gt;
  
  
  Pillar 2. Unification with the Jet Management Center.
&lt;/h3&gt;

&lt;p&gt;What the heck is Jet? It is a blazing fast distributed computing platform built on top of Hazelcast In-Memory Data Grid. &lt;a href="https://jet-start.sh/"&gt;Here&lt;/a&gt; you can read more about it. Previously, Jet had its own Management Center, but not anymore. One Hazelcast - one Management Center!&lt;/p&gt;
&lt;h3&gt;
  
  
  Pillar 3. New metric engine.
&lt;/h3&gt;

&lt;p&gt;Since the dawn of time we used the "push" model to collect the metric data from the cluster. It is not even entirely correct to use the word "collect" here. Collecting is an active process. We received the metric data from the cluster. Every node had to know the address of the management center, and it pushed its metric data to that address. &lt;br&gt;
With 4.2020.08 we are trilled to reverse that paradigm and start polling cluster members for metric data! It is a huge change but we have not stopped there. Here is a list with new major metric-related features:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The "poll" model instead of the "push" one.&lt;/li&gt;
&lt;li&gt;A new metrics storage for time-series data implemented on top of &lt;a href="https://rocksdb.org/"&gt;RocksDB&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://prometheus.io/"&gt;Prometheus&lt;/a&gt; exporter for the metric data. &lt;/li&gt;
&lt;li&gt;A new customizable UI widget to display the metric data.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Having that said, let's dive deeper in the anatomy of the widget, and what problems we faced while creating it.&lt;/p&gt;
&lt;h2&gt;
  
  
  The widget
&lt;/h2&gt;
&lt;h3&gt;
  
  
  What users want to see and why
&lt;/h3&gt;

&lt;p&gt;What is the purpose of monitoring? One could argue that the whole point is to provide top management with pretty charts and multi-page reports with statistics. Jokes aside. What is the real purpose of monitoring? Why do we stare at all these graphs for ours? The ultimate goal is to detect abnormalities as early as possible. Why? Because any abnormality is a predecessor to potential issues.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ec4DkMh2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3cyvrjjn7i4bmckb1lgn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ec4DkMh2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3cyvrjjn7i4bmckb1lgn.jpg" alt="What users want to see"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Speaking of monitoring in general, we are usually speaking of time series data (a list of data points in time order, in our case they come to the front end as &lt;code&gt;{ time: number; value: number }[]&lt;/code&gt;). Speaking of monitoring of distributed systems, we are usually speaking of multiple time series. Multiple time series cause multiple problems.&lt;/p&gt;
&lt;h4&gt;
  
  
  Problem 1. How do we analyze graphs?
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cfMuoF1R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/la6avjkd14wk1bpuqxjq.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cfMuoF1R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/la6avjkd14wk1bpuqxjq.jpeg" alt="Problem 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have several data points. We use fancy or not so fancy methods of interpolation to draw continuous lines that resemble the original continuous real-world data standing behind the discrete data. How do we detect abnormality there?&lt;/p&gt;

&lt;p&gt;We can analyze graphs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Individually&lt;/li&gt;
&lt;li&gt;As a group&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For individual analysis, we already have the data points containing scalar values. Comparing scalars is, if not simple, at least doable.&lt;/p&gt;

&lt;p&gt;For group analysis, we have to somehow calculate a single scalar out of a time series for each time series, and compare the resulting scalars. There are endless possibilities of how one could do the calculation, depending on the needs of the business. We will go over a small bit of them that we chose for our application down below.&lt;/p&gt;

&lt;p&gt;As we can see, for both methods of analysis we end up with a list of scalars that we need to somehow compare.&lt;/p&gt;
&lt;h4&gt;
  
  
  Problem 2. How do we find an abnormality in a list of scalars?
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ExgxHW4N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pq6zcll97qbndlqsrmmj.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ExgxHW4N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pq6zcll97qbndlqsrmmj.jpeg" alt="Problem 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Generally speaking, we have 4 ways of describing abnormality:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We can define a range a values that are considered normal. If anything falls out of the range then it is abnormal. For example, we can say that &lt;code&gt;[-42,42]&lt;/code&gt; is our normal range. Then &lt;code&gt;7&lt;/code&gt; would be considered normal, and &lt;code&gt;43&lt;/code&gt; would be abnormal.&lt;/li&gt;
&lt;li&gt;We can define a predicate for normality. If a value satisfies the predicate than it is considered normal. Otherwise, it is abnormal. For example, we can say that all integer odd values are normal range. Then &lt;code&gt;7&lt;/code&gt; would be considered normal, and &lt;code&gt;7.5&lt;/code&gt; or &lt;code&gt;42&lt;/code&gt; would be abnormal.&lt;/li&gt;
&lt;li&gt;We can define a range a values that are considered abnormal. If anything falls out of the range then it is normal. Basically, it is a negation of #1.&lt;/li&gt;
&lt;li&gt;We can define a predicate for abnormality. If a value satisfies the predicate than it is considered abnormal. Otherwise, it is normal. Basically, it is a negation of #2.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We can also detect abnormality iteratively, using different methods (listed above) at different stages, chaining them. For example, we could consider abnormal only integer odd values that belong to &lt;code&gt;[0, 42)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With a few exceptions, predicates make the most sense for analyzing potentially infinite lists, as they, usually, require limited processing power and memory.&lt;/p&gt;

&lt;p&gt;Ranges are not that simple. Ranges can be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Static&lt;/li&gt;
&lt;li&gt;Dynamic&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Static range is constant predefined range that does not change when new metrics data comes in. Say, we have a cluster of 30 machines. Every machine has 16 GB of RAM. Knowing the average expected load, we could identify the normal range for the used RAM as &lt;code&gt;[1.6 GB, 14.4 GB]&lt;/code&gt; (from 10% and up to 90%). That would be a perfect example of a static range. It does not depend on the number of machines or the phase of the moon.&lt;/p&gt;

&lt;p&gt;For some metrics and under certain conditions, we could define a range of normal values beforehand, without analyzing the metric data itself. Say, we have a cluster of 30 machines. Every machine has 16 GB of RAM. Knowing the expected load, we could identify the normal range for the used RAM as &lt;code&gt;[1.6 GB, 14.4 GB]&lt;/code&gt; (from 10% and up to 90%). &lt;br&gt;
However, not all metrics have a universal predefined range of possible values that make sense for any system. For those metrics, we have to evaluate them by comparison to their peers, i.e. process the whole list of scalars to define the normal range, and then process the list all over again to identify the abnormal range. We can see that the complexity here scales at least linearly with the size of the list.&lt;/p&gt;

&lt;p&gt;As a result, we see that abnormality could be identified in 2 ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Absolutely&lt;/li&gt;
&lt;li&gt;Relatively&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The absolute abnormality detection is simpler to understand and implement. It also, usually, requires less processing power as it does not require a dynamic range calculation. It could be used on a potentially unlimited list of scalars. However, it has a restricted area of application as not all metrics have a constant predefined range of metrics.&lt;br&gt;
The relative abnormality detection is more complex. It requires a dynamic range calculation and, therefore, could be used only on the limited list of scalars. However, it could be applied to any metric in the cluster.&lt;/p&gt;

&lt;p&gt;The absolute abnormality detection requires users to have deep knowledge of the system to define the normal/abnormal range. In comparison, the relative abnormality detection allows users to easily identify if any metric on any node significantly deviates from the average cluster value without the prior knowledge of the system, or without the expert knowledge of the normal reference range for the system.&lt;/p&gt;
&lt;h4&gt;
  
  
  Problem 3. How do we display the abnormality?
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f25ePGcU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9nnwjte81zrgrlqcpkro.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f25ePGcU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9nnwjte81zrgrlqcpkro.jpeg" alt="Problem 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Say, we have 100 time series. We identified 20 of them as abnormal. How do we display them? &lt;/p&gt;

&lt;p&gt;We could display all 100 graphs, and somehow mark the 20 abnormal ones. For instance, we could color code them, but would you be comfortable browsing through 100 graphs? I certainly would not be. I seriously doubt any living human being could make any sense of that mess.&lt;/p&gt;

&lt;p&gt;We could display only the 20 abnormal ones. But then we wouldn't know what is considered normal. What was the benchmark against which we identified the abnormality?&lt;/p&gt;

&lt;p&gt;Should we display the 20 abnormal ones and additionally draw a graph with the calculated reference value, considered normal? Yes and no! Yes, because it is the correct principal. We should display the abnormal lines along with the reference normal one. No, because 20 graphs are still too much to comprehend. Various studies on how many items a human being can focus on simultaneously show different results on a range from 3 to 7-9. As the final number varies from study to study, it is still a single-digit number everywhere. It means that &lt;code&gt;20&lt;/code&gt; is still not good enough. How do we go from &lt;code&gt;20&lt;/code&gt; to a single-digit number?&lt;/p&gt;

&lt;p&gt;Previously, we said we could detect abnormality iteratively. Why don't we apply that idea here? Once we detect the initial list of abnormal scalars, we could sort them in the ascending order by their deviation from the reference normal scalar, and leave only those with the biggest deviation.&lt;/p&gt;

&lt;p&gt;After experimenting a bit ourselves, we decided that 4 is a good number. So for a single metric we decided to display up to 3 abnormal graphs along with the reference normal one.&lt;/p&gt;
&lt;h3&gt;
  
  
  Filters
&lt;/h3&gt;

&lt;p&gt;Hazelcast cluster could have hundreds of members. It means that for every metric we have hundreds of time series. We could not display all of them. Inevitably, we had to somehow help our users to find the abnormality and filter out the result graphs.&lt;/p&gt;

&lt;p&gt;As of Management Center &lt;code&gt;4.2020.08&lt;/code&gt;, we provide our users with 6 different filters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Peak Top 3&lt;/li&gt;
&lt;li&gt;Peak Bottom 3&lt;/li&gt;
&lt;li&gt;Average Top 3&lt;/li&gt;
&lt;li&gt;Average Bottom 3&lt;/li&gt;
&lt;li&gt;Outliers&lt;/li&gt;
&lt;li&gt;Manual Selection&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Manual Selection
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fK9ksO4m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/49ardlf1rriy2vnfv9iz.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fK9ksO4m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/49ardlf1rriy2vnfv9iz.jpeg" alt="Manual selection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's start with the most boring one - Manual Selection. It allows users to select several members out of the list of cluster members they want to see the metric data for. Our front end receives the data only for those members. Piece of cake.&lt;/p&gt;
&lt;h4&gt;
  
  
  Peak Top 3/Peak Bottom 3
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kyIwZLU8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kq92n2p5jldcmui33bm9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kyIwZLU8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kq92n2p5jldcmui33bm9.png" alt="Peak Filter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do you remember what we have to do to analyze time series as a group? We have to calculate a scalar value for every time series. When you think of a calculation approach, one of the first things that comes to mind is just to take the absolute maximum value of the function. &lt;/p&gt;

&lt;p&gt;Given that every data point is &lt;code&gt;{ time: number; value: number }&lt;/code&gt;, the implementation is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timeSeriesResScalar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Max&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeSeries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, we sort our multiple time series in the descending order by their calculated scalars, and take the first 3 time series. We call this filter &lt;code&gt;Peak Top 3&lt;/code&gt;. For the &lt;code&gt;Peak Bottom 3&lt;/code&gt;, we swap &lt;code&gt;Math.max&lt;/code&gt; for &lt;code&gt;Math.min&lt;/code&gt;, but the idea is the same.&lt;/p&gt;

&lt;p&gt;We do not calculate any average cluster value (a reference normal value) with this approach, leaving the final judgment of normality to the admin. However, we might start doing it if there is a strong demand.     &lt;/p&gt;

&lt;p&gt;Have you noticed any problems with the Peak filter? One data point with an extraordinary value can make the whole time series range higher even though all other data points have rather small values. For some metrics with modest volatility Peak filter is exactly what we need. Those short term surges could indicate a potential abnormality. But what about highly volatile metrics? We need a way to minimize the effect of those short-term spikes on the result scalar. Here is where the story of mean and median begins.&lt;/p&gt;

&lt;h4&gt;
  
  
  Mean and median
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nbv-D0IY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3bil1z1bxtzk9xsxzi2o.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nbv-D0IY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3bil1z1bxtzk9xsxzi2o.jpg" alt="Mean vs median"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Barry has 4 pots of gold. Amy, John and Douglas have 0. The mean value here is 1. The median, however, is 0. How do we calculate them? &lt;/p&gt;

&lt;p&gt;Mean is the average you are used to. Calculate the sum of the items in the list and divide it by the number of the items.&lt;br&gt;
Median is the middle value of the list. Sort the list in the ascending order. If the number of items is odd, the middle item of your sorted list is the median. If the number of items is even, sum two middle numbers and divide them by 2. &lt;/p&gt;

&lt;p&gt;In terms of monitoring it means that mean accounts for extraordinary spikes. Several of them can drastically change the resulting scalar. Median, on the contrary, filters out the surges. &lt;/p&gt;

&lt;p&gt;Should we stop at the mean and the median though?&lt;/p&gt;
&lt;h4&gt;
  
  
  Average by integral
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WyTi6GcS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6cxjxddphfpso0umhy40.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WyTi6GcS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6cxjxddphfpso0umhy40.jpg" alt="Arithmetic mean is not enough"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me rephrase it. Should we stop at the arithmetic mean and the median though? After all, we are not calculating an average of a list of simple numbers, these are data points of a time series. By extracting only values and operating only on the values we simply disregard the time factor.    &lt;/p&gt;

&lt;p&gt;Consider these two graphs:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--77DF14sA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rsmqg8196unb6agaxco4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--77DF14sA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rsmqg8196unb6agaxco4.jpg" alt="Mean time factor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The arithmetic means for their values are the same. Do you think they adequately represent the average value for both functions? What scalar value could be used to describe a function?&lt;/p&gt;

&lt;p&gt;It is the area under the curve. Ladies and gentlemen, please, give your warmest welcome to the definite integral!    &lt;/p&gt;

&lt;p&gt;Usually, we are speaking of a definite integral of a function, but with a time series we do not have a function. Instead, we have a list of discrete data points. Luckily, we do not have to reinvent the wheel. There is an area of study in math researching specifically this problem called numerical integration of discrete data or discrete data integration.    &lt;/p&gt;

&lt;p&gt;There are various methods of discrete data integration. We will consider only one of them. The one we used for the widget - the trapezoidal rule.    &lt;/p&gt;

&lt;p&gt;Consider the following graph:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wyqof3ze--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0qsv0wjvxcbx0emxv46z.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wyqof3ze--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0qsv0wjvxcbx0emxv46z.jpg" alt="Graph with trapezoids"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see how the data points of the time series form 3 trapezoids. To find the area under the interpolated curve we need to find areas of those 3 trapezoids and sum them up.&lt;/p&gt;

&lt;p&gt;For trapezoid &lt;code&gt;A&lt;/code&gt; it is &lt;code&gt;((2+4)/2)*(2-1)&lt;/code&gt; and equals &lt;code&gt;3&lt;/code&gt;. For trapezoid &lt;code&gt;B&lt;/code&gt; it is &lt;code&gt;((1+4)/2)*(2.5-2)&lt;/code&gt; and equals &lt;code&gt;1.25&lt;/code&gt;. For trapezoid &lt;code&gt;C&lt;/code&gt; it is &lt;code&gt;((1+1.5)/2)*(7-2.5)&lt;/code&gt; and equals &lt;code&gt;5.625&lt;/code&gt;. So the final square is &lt;code&gt;3+1.25+5.625&lt;/code&gt; and equals &lt;code&gt;9.875&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To find the average value of the function we now only need to divide its area by its projection on the &lt;code&gt;x&lt;/code&gt; axis. Imagine it as if we are trying to find the height of a rectangle with the same length as the projection of the function and with the same area.    &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HD81zCNR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/604frwuucij9otcnz458.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HD81zCNR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/604frwuucij9otcnz458.jpg" alt="Function average"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the TypeScript function to find the average could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;averageByTrapezoidalRule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}[],&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;totalArea&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&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="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;point1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;point2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="nx"&gt;totalArea&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;point2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;point1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;point2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;point1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;average&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;totalArea&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;average&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Average Top 3/Average Bottom 3
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U1u5dAka--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/45xvstjdczx5ujc2y3p8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U1u5dAka--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/45xvstjdczx5ujc2y3p8.png" alt="Average Filter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With all that knowledge, let's now build an algorithm for the &lt;code&gt;Average Top 3&lt;/code&gt; filter:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For every time series calculate its average by the trapezoidal rule.&lt;/li&gt;
&lt;li&gt;Sort the multiple time series in the descending order.&lt;/li&gt;
&lt;li&gt;Take the first 3 of them.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the &lt;code&gt;Average Bottom 3&lt;/code&gt; we just reverse the sorting.&lt;/p&gt;

&lt;p&gt;For both of these filters, we still do not calculate any average cluster value (a reference normal value) leaving the final judgment of normality to the admin.    &lt;/p&gt;

&lt;h4&gt;
  
  
  Outliers
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d2TaX-jg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/egwxw5w6gvv94jf8u87q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d2TaX-jg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/egwxw5w6gvv94jf8u87q.png" alt="Outliers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alrighty, so all previous filters require some expert knowledge of the system to identify if the displayed values are normal or abnormal. Could we create a filter that unleashes the whole power of the relative abnormality detection, and helps us find the abnormal graphs based on the peer values?&lt;/p&gt;

&lt;p&gt;It is our default filter. We call it the &lt;code&gt;Outliers&lt;/code&gt; or simply &lt;code&gt;auto&lt;/code&gt;. The core idea is to calculate the reference normal value based on the multiple time series as some sort of average. Calculate averages for every time series using the trapezoidal rule. Compare their averages with the reference value. If it deviates from the reference value by more than 30%, consider it abnormal.&lt;/p&gt;

&lt;p&gt;The trick is with finding the reference value. Originally, we did it all on the frontend.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We calculated averages for every time series.&lt;/li&gt;
&lt;li&gt;We calculated a median of those averages.&lt;/li&gt;
&lt;li&gt;We used the median as the reference value.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Why the median? Say, you have a cluster of 10 nodes. 2 of those nodes deviate from the median by some extreme value, say, 300%. They could shift the reference value, so one of the normally behaving members could start being an outlier. The median mitigates the effect of outliers on the reference value.&lt;/p&gt;

&lt;p&gt;Later, our backend provided us with a cool aggregation API for the metric time series data. So now we:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Request the &lt;code&gt;MEDIAN&lt;/code&gt; aggregate for all nodes.

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;MEDIAN&lt;/code&gt; aggregate is a time series as well. For its every data point it takes values for all nodes for the timestamp, and returns a median of those values.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Calculate the average of the median time series.&lt;/li&gt;
&lt;li&gt;Use the calculated average as the reference value.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now we disassembled our reference value calculation. Only one last question still stands. What happens when there are too many outliers?&lt;/p&gt;

&lt;p&gt;If we find more than 3 outliers we sort the outliers in the ascending order by their deviation from the reference value, and take only the top 3 with the greatest deviation.&lt;/p&gt;

&lt;p&gt;The final &lt;code&gt;Outliers&lt;/code&gt; algorithm looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Request the &lt;code&gt;MEDIAN&lt;/code&gt; aggregate.&lt;/li&gt;
&lt;li&gt;Display it as a dashed graph on the chart.&lt;/li&gt;
&lt;li&gt;Calculate its average by the trapezoidal rule. Consider it a reference value.&lt;/li&gt;
&lt;li&gt;Calculate averages for every time series.&lt;/li&gt;
&lt;li&gt;Leave only ones that deviate from the reference value by more than 30%.&lt;/li&gt;
&lt;li&gt;Sort them in ascending order by the deviation. Display the top 3 time series with the greatest deviation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As you can see, with the &lt;code&gt;Outliers&lt;/code&gt; we have the reference graph, so it is easy to understand what is considered normal at first glance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future plans for the widget
&lt;/h2&gt;

&lt;p&gt;Going further, we would like to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make the outliers threshold adjustable.&lt;/li&gt;
&lt;li&gt;Allow zooming and out for both X and Y axes.&lt;/li&gt;
&lt;li&gt;Make the maximum number of graphs adjustable.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We encourage you &lt;a href="https://hub.docker.com/r/hazelcast/management-center/"&gt;try he new Management Center yourself&lt;/a&gt;, and get back to us with your &lt;a href="http://slack.hazelcast.com/"&gt;feedback&lt;/a&gt;! Stay tuned for the new posts with the lessons we learned a truly distributed enterprise-ready in-memory data grid.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>balalaika IT newsletter #8</title>
      <dc:creator>Andrey Goncharov</dc:creator>
      <pubDate>Sat, 22 Aug 2020 10:24:11 +0000</pubDate>
      <link>https://dev.to/balalaikait/balalaika-it-newsletter-8-5dkj</link>
      <guid>https://dev.to/balalaikait/balalaika-it-newsletter-8-5dkj</guid>
      <description>&lt;h1&gt;
  
  
  General
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Databases are one of the most complex pieces of software ever made by humans, not only in terms of their internals, but also in terms of the behavior for the end-users. This comprehensive &lt;a href="https://medium.com/@rakyll/things-i-wished-more-developers-knew-about-databases-2d0178464f78"&gt;blog post&lt;/a&gt; might help you to avoid common pitfalls when dealing with DBs.&lt;/li&gt;
&lt;li&gt;Designing a successful language is very hard, no doubts. If you are interested in the topic, watch &lt;a href="https://youtu.be/Sg4U4r_AgJU"&gt;this talk&lt;/a&gt; by Brian Kernighan.&lt;/li&gt;
&lt;li&gt;Nowadays application development assumes dealing with distributed systems of various kinds. If you feel that you are at the beginner level in the wild ocean of distributed systems, you should watch this nice &lt;a href="https://youtu.be/Y6Ev8GIlbxc"&gt;overview talk&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Java
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Were you capable to catch up with all the new stuff introduced in Java 9, 10, 11, 12, 13, and beyond? If not, here is a &lt;a href="https://4comprehension.com/busy-developers-guide-to-java-9-10-11-12-13-and-above/"&gt;busy developers’ guide&lt;/a&gt; from Grzegorz Piwowarek.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  JavaScript
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;On August 20, Microsoft announced a new major version of TypeScript - 4.0.  It packs lots of goodies. &lt;a href="https://devblogs.microsoft.com/typescript/announcing-typescript-4-0/"&gt;This lengthy post&lt;/a&gt; goes over them one by one and it is an absolute must-read for every TS developer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  React
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;TypeScript is the official language of frontend web development at Airbnb. Yet, the process of adopting TypeScript and migrating a mature codebase containing thousands of JavaScript files didn’t happen in one day. In &lt;a href="https://medium.com/airbnb-engineering/ts-migrate-a-tool-for-migrating-to-typescript-at-scale-cd23bfeb5cc"&gt;this article&lt;/a&gt; Sergii Rudenko tells us about their TypeScript migration strategy and tools.&lt;/li&gt;
&lt;li&gt;On August 10, React published their first release candidate for React v17. Even though it’s almost three years since a major release of React, surprisingly, there are no new features added for the new version. &lt;a href="https://medium.com/better-programming/the-6-major-changes-in-react-v17-0-d14fed5b0529"&gt;This concise read&lt;/a&gt; covers the major updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Node.js
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Node.js Technical Steering Committee is currently running a survey on unhandled Promise rejections handling. You have a chance to a part and impact the final decision. Here is the &lt;a href="https://medium.com/@nodejs/node-js-promise-reject-use-case-survey-98e3328340c9"&gt;blog post&lt;/a&gt; which explains the rationale behind the survey.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>node</category>
      <category>java</category>
      <category>webdev</category>
    </item>
    <item>
      <title>balalaika IT newsletter #7</title>
      <dc:creator>Andrey Goncharov</dc:creator>
      <pubDate>Sat, 08 Aug 2020 07:58:08 +0000</pubDate>
      <link>https://dev.to/balalaikait/balalaika-it-newsletter-7-1mab</link>
      <guid>https://dev.to/balalaikait/balalaika-it-newsletter-7-1mab</guid>
      <description>&lt;h1&gt;
  
  
  Frontend
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://engineering.fb.com/web/facebook-com-accessibility/"&gt;A short, yet insightful post&lt;/a&gt; about enhanced A11Y at Facebook. You might think it is easy and not a big deal until you have to re-write your whole application to meet the &lt;a href="https://www.w3.org/TR/wai-aria-practices-1.2/"&gt;AIRA guidelines&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Node.js
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;What do you know about the speculative compilation in JavaScript? &lt;a href="https://webkit.org/blog/10308/speculation-in-javascriptcore/"&gt;This lengthy read&lt;/a&gt; goes in-depth of how modern JS VMs make your code run faster.&lt;/li&gt;
&lt;li&gt;There is a certain learning curve related with contributions to the native side of Node.js core. Luckily this great &lt;a href="https://joyeecheung.github.io/blog/2018/12/31/tips-and-tricks-node-core/"&gt;tips and tricks post&lt;/a&gt; from Joyee Cheung is there to help you.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Java
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;It is not a big secret that GC may introduce latency spikes. Such spikes are especially harmful in case of stream processing engine, like Hazelcast Jet or Apache Spark Streaming. Read &lt;a href="https://jet-start.sh/blog/2020/06/09/jdk-gc-benchmarks-part1"&gt;this blog post series&lt;/a&gt; from Jet team to see results of various experiments with modern Java garbage collectors.&lt;/li&gt;
&lt;li&gt;Did you know that there is a Java Engineering Group in Microsoft? Moreover, these guys wrote a &lt;a href="https://github.com/microsoft/openjdk-proposals/blob/master/stack_allocation/Stack_Allocation_JEP.md"&gt;nice JEP&lt;/a&gt; on Stack Allocation support in HotSpot C2 to eliminate non-escaping heap allocations where applicable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  General
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Distributed systems are much more than the AP/CP choice implied by the so called CAP theorem. Conflict-free replicated data types (CRDT) assume eventual consistency, scale really well, and provide math-based way to resolve inconsistencies between replicas. In &lt;a href="https://youtu.be/x7drE24geUw"&gt;this talk&lt;/a&gt; Martin Kleppmann goes beyond the introductory material on CRDTs.&lt;/li&gt;
&lt;li&gt;API seems to be so natural term that we assume it was there since the beginning of computer era. But that is not true. If you want to learn when and how the concept of API was invented, watch &lt;a href="https://youtu.be/LzMp6uQbmns"&gt;this talk&lt;/a&gt; from Joshua Bloch.&lt;/li&gt;
&lt;li&gt;Dropbox migrated from Nginx to Envoy. &lt;a href="https://dropbox.tech/infrastructure/how-we-migrated-dropbox-from-nginx-to-envoy"&gt;In this blogpost&lt;/a&gt; Alexey Ivanov  and Oleg Guba talk about the old Nginx-based traffic infrastructure, its pain points, and the benefits we gained by migrating to Envoy.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>node</category>
      <category>java</category>
      <category>webdev</category>
    </item>
    <item>
      <title>balalaika IT newsletter #6</title>
      <dc:creator>Andrey Goncharov</dc:creator>
      <pubDate>Sat, 25 Jul 2020 16:25:44 +0000</pubDate>
      <link>https://dev.to/balalaikait/balalaika-it-newsletter-6-1m0k</link>
      <guid>https://dev.to/balalaikait/balalaika-it-newsletter-6-1m0k</guid>
      <description>&lt;h1&gt;
  
  
  Frontend
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;a href="https://jkettmann.com/beginners-guide-to-testing-react/"&gt;comprehensive guide&lt;/a&gt; on testing in React from Johannes Kettmann. A single long-read that covers it all.&lt;/li&gt;
&lt;li&gt;Did you ever hear of CSS Houdini? Lisi Linhart did not just hear about it, but went above and beyond and wrote a &lt;a href="https://lisilinhart.info/posts/css-houdini-performance"&gt;great piece&lt;/a&gt; on its performance. &lt;/li&gt;
&lt;li&gt;Adobe open-sourced its own &lt;a href="https://react-spectrum.adobe.com/blog/introducing-react-spectrum.html"&gt;design system and state management library&lt;/a&gt; for React!&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Node.js
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Moment.js, Luxon or date-fns? Hopefully, one day there will be a built-in API that if not removes but at least reduces the need for third-party libraries to manipulate date and time. Here is a &lt;a href="https://tc39.es/proposal-temporal/docs/index.html"&gt;TC39 proposal for the new Temporal API&lt;/a&gt; that is destined to fix JS Date.&lt;/li&gt;
&lt;li&gt;Nowadays almost every Node.js developer has a good understanding of the event loop principles. Yet, only some folks understand how node works from the low-level perspective. If you want to learn more about non-blocking I/O, watch this interesting &lt;a href="https://youtu.be/P9csgxBgaZ8"&gt;talk&lt;/a&gt; by Sam Roberts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Java
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Some of &lt;code&gt;java.util.concurrent.atomic&lt;/code&gt; classes expose &lt;code&gt;#lazySet()&lt;/code&gt; methods which may be a significant performance win for a single writer scenario in the concurrent mode. If you are not familiar with those methods and want to understand how they differ from ordinary &lt;code&gt;volatile&lt;/code&gt; writes take a look at this &lt;a href="http://psy-lob-saw.blogspot.com/2012/12/atomiclazyset-is-performance-win-for.html"&gt;post&lt;/a&gt; and &lt;a href="http://psy-lob-saw.blogspot.com/2016/12/what-is-lazyset-putordered.html"&gt;this&lt;/a&gt; one as well.&lt;/li&gt;
&lt;li&gt;Everyone knows Netty, which is used as a building block in many other frameworks. One of the main reasons behind that popularity is performance. Watch &lt;a href="https://youtu.be/hvYqSz_BgUM"&gt;this talk&lt;/a&gt; to learn about some optimizations inside Netty, including the "do not try this at home" ones.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  General
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Linux kernel scheduler has to make a lot of decisions and it has to make them fast. Here is a &lt;a href="https://helix979.github.io/jkoo/post/os-scheduler/"&gt;detailed explanation&lt;/a&gt; of how the scheduler works.&lt;/li&gt;
&lt;li&gt;Writing correct concurrent code is hard, no doubts. Writing performant concurrent code is even harder. If you aim for both of these goals, read this awesome &lt;a href="https://travisdowns.github.io/blog/2020/07/06/concurrency-costs.html"&gt;blog post&lt;/a&gt; that compares the costs of different concurrent primitives.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>node</category>
      <category>java</category>
      <category>webdev</category>
    </item>
    <item>
      <title>balalaika IT newsletter #5</title>
      <dc:creator>Andrey Goncharov</dc:creator>
      <pubDate>Sat, 11 Jul 2020 09:52:29 +0000</pubDate>
      <link>https://dev.to/balalaikait/balalaika-it-newsletter-5-14ab</link>
      <guid>https://dev.to/balalaikait/balalaika-it-newsletter-5-14ab</guid>
      <description>&lt;h1&gt;
  
  
  Frontend
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Does CSS grid seem kind of complicated to you? Do you find yourself constantly fighting it, endlessly browsing web for yet another hack? Here is &lt;a href="https://yoksel.github.io/grid-cheatsheet/"&gt;a remarkable cheatsheet&lt;/a&gt; destined to keep your sanity.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://css-tricks.com/an-overview-of-scroll-technologies/"&gt;An outstanding overview&lt;/a&gt; of scrolling technologies and approaches by Zach Saucier.&lt;/li&gt;
&lt;li&gt;Security is something frontend engineers are often not thinking about. It seems like a task for the backend team. What possibly could go wrong on the frontend? Here is &lt;a href="https://www.simform.com/react-security-vulnerabilities-solutions/"&gt;a lengthy list&lt;/a&gt; every React developer should keep in mind.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Node.js
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;The TSC is going to have "Next 10 years of Node.js" session on July 16. Here you can find &lt;a href="https://github.com/nodejs/node/issues/34260"&gt;the agenda&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;What exciting things happened in the JavaScript language and the V8 engine in 2019? Shu and Leszek take &lt;a href="https://www.youtube.com/watch?v=TPm-UhWkiq8"&gt;a tour&lt;/a&gt; of some new features and improvements.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Java
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;What may be simpler than measuring time, right? In reality, Java has multiple APIs to do the job and there are some important restrictions related to each one of those. Here is &lt;a href="https://dzone.com/articles/java-advent-calendar-measuring-time-from-java-to-k"&gt;a great deep dive&lt;/a&gt; on the topic.&lt;/li&gt;
&lt;li&gt;Have you ever asked yourself a question of whether the allocation of Java objects on the heap involves any contention? By all means, it should, as multiple threads have to be coordinated during those allocations. Yet, HotSpot JVM has another tricky optimization, called Thread-Local Allocation Buffers which allows avoiding contention in most scenarios. If you want to learn more, here is &lt;a href="https://alidg.me/blog/2019/6/21/tlab-jvm"&gt;an extensive read&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  General
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;At first glance, load balancing seems to be simple as a concept. In fact, it is extremely hard to make it right. Guys from DataStax recently implemented the Power of Two Random Choices algorithm for Apache Cassandra. It showed a sizeable improvement in high load scenarios. Learn more &lt;a href="https://www.datastax.com/blog/2020/06/improved-client-request-routing-apache-cassandratm"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://slack.engineering/a-terrible-horrible-no-good-very-bad-day-at-slack-dfe05b485f82"&gt;The story&lt;/a&gt; of the Slack downtime on May 12th, 2020.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://smist08.wordpress.com/2020/06/24/exciting-days-for-arm-processors/"&gt;ARM is conquering the world&lt;/a&gt;. Soon you will find it in servers, supercomputers, and even your MacBook!&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>node</category>
      <category>java</category>
      <category>webdev</category>
    </item>
    <item>
      <title>balalaika IT newsletter #4</title>
      <dc:creator>Andrey Goncharov</dc:creator>
      <pubDate>Sat, 27 Jun 2020 09:00:04 +0000</pubDate>
      <link>https://dev.to/balalaikait/balalaika-it-newsletter-4-3hj3</link>
      <guid>https://dev.to/balalaikait/balalaika-it-newsletter-4-3hj3</guid>
      <description>&lt;h1&gt;
  
  
  Frontend
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://indepth.dev/solidjs-reactivity-to-rendering/"&gt;An in-depth guide on building your own 100% reactive renderer from scratch&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://calendar.perfplanet.com/2019/javascript-component-level-cpu-costs/"&gt;A must-read research on CPU cost of JavaScript&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blog.getbootstrap.com/2020/06/16/bootstrap-5-alpha/"&gt;Bootstrap 5 alpha is out!&lt;/a&gt; This time no jQuery and no IE11.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/playlist?list=PLo3w8EB99pqJVPhmYbYdInBvAGarDavh-"&gt;A guided tour&lt;/a&gt; of what it is like to work on the SpiderMonkey (JavaScript engine) compiler and improve conformance with ECMA-262, the JavaScript Specification. From Mozilla to people with love.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Node.js
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Sad to say it, but it looks like &lt;a href="https://twitter.com/hapijs/status/1275887984114413569?s=19"&gt;hapi.js project is reaching its end&lt;/a&gt;. If you happen to use hapi.js, you should consider switching to another web framework in the nearest future.&lt;/li&gt;
&lt;li&gt;As of v7 npm support both yarn.lock and package-lock.json. &lt;a href="https://blog.npmjs.org/post/621733939456933888/npm-v7-series-why-keep-package-lockjson"&gt;Here is a great read&lt;/a&gt; on npm v7 treats them and about the future of npm dependency resolution algorithms.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Java
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;HotSpot JVM has tons of optimizations all over the place. For instance, even the default hashCode() hides some secrets. Learn more about this optimization &lt;a href="https://srvaroa.github.io/jvm/java/openjdk/biased-locking/2017/01/30/hashCode.html"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;As an interesting follow-up, you might want to take a look at the j.l.String#hashCode() implementation which caches the hash code in a non-volatile &lt;code&gt;hash&lt;/code&gt; field. This optimization was described in the Java Concurrency in Practice book &lt;a href="http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/String.java#l117"&gt;here&lt;/a&gt; and &lt;a href="http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/String.java#l1452"&gt;here&lt;/a&gt;. Do not do it at home!&lt;/li&gt;
&lt;li&gt;If you are not familiar with the history behind Generics, which have a controversial reputation in Java community, you should read &lt;a href="http://cr.openjdk.java.net/~briangoetz/valhalla/erasure.html"&gt;this post&lt;/a&gt; from Brian Goetz.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  General
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Jepsen team recently did &lt;a href="https://jepsen.io/analyses/redis-raft-1b3fbf6"&gt;an analysis of RedisRaft&lt;/a&gt;, a new module that provides strict serializability for Redis. As usual, some issues were found. As usual, some promises of fixes were made. &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>node</category>
      <category>java</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
