<?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>Forem: OverOps</title>
    <description>The latest articles on Forem by OverOps (@overopshq).</description>
    <link>https://forem.com/overopshq</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%2F51577%2F5a42ba62-b341-43d8-a8cd-2951b1a60f00.jpg</url>
      <title>Forem: OverOps</title>
      <link>https://forem.com/overopshq</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/overopshq"/>
    <language>en</language>
    <item>
      <title>The Slack Outage is a Wake Up Call For All IT Orgs</title>
      <dc:creator>OverOps</dc:creator>
      <pubDate>Wed, 07 Aug 2019 15:35:54 +0000</pubDate>
      <link>https://forem.com/overopshq/the-slack-outage-is-a-wake-up-call-for-all-it-orgs-9d</link>
      <guid>https://forem.com/overopshq/the-slack-outage-is-a-wake-up-call-for-all-it-orgs-9d</guid>
      <description>&lt;p&gt;Slack took quite a beating during and after the service outage that happened last Monday morning. Here’s a small sample of the headlines (before they were updated) that come up on a simple news search of Slack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slack is Experiencing Worldwide Outage, Degraded Performance&lt;/li&gt;
&lt;li&gt;Yes, Slack is Down.&lt;/li&gt;
&lt;li&gt;Happy Monday, Slack is Down&lt;/li&gt;
&lt;li&gt;How Microsoft Teams May Have Caused Today’s Slack Outage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last one stands out from the others - it was the only one that I actually clicked on. What do they mean Microsoft caused the outage? What’s the connection? Upon opening the &lt;a href="https://articles2.marketrealist.com/2019/07/microsoft-teams-todays-slack-outage/"&gt;article&lt;/a&gt;, I realized they weren’t talking about Microsoft teams, they were talking about &lt;a href="https://products.office.com/en-us/microsoft-teams/group-chat-software"&gt;Microsoft Teams&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here’s the timeline they lay out to explain what they’re talking about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;July 11 - Microsoft announces they hit 13 million active daily users in - June (Slack reported 10 million users in January)&lt;/li&gt;
&lt;li&gt;July 22 - Slack relaunches their desktop app to load faster and use less memory&lt;/li&gt;
&lt;li&gt;July 29 - Slack goes down&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Their theory, then, is that at some point Slack started to work on a major upgrade to their backend system. Feeling the pressure after Microsoft’s announcement, Slack pushed the new update to production before it was ready and all hell broke loose. Seems to make sense more or less. &lt;/p&gt;

&lt;p&gt;Of course, engineers have probably been working on this update for several months at least, and it’s hard to say whether that announcement would be enough to interrupt the product roadmap. Still, it’s definitely possible that engineering managers started applying additional pressure on teams to build, test and deploy faster than originally expected. It’s hard to say.&lt;/p&gt;

&lt;p&gt;One thing that is clear is that this outage was caused by changes made to the application's code. Similar outages reported a few days prior, on the 26th, were determined to be a result of changes made to the code the night before. The engineering team rolled back those changes and started to deploy intermittent fixes. &lt;/p&gt;

&lt;p&gt;The latest outage on Monday morning follows the same story. The &lt;a href="https://status.slack.com/2019-07-29"&gt;engineering team reported&lt;/a&gt; that on July 29th, they “made a change that inadvertently caused some performance issues, including messages failing to send.” Roughly an hour after the service went down, Slack had announced that users once again have the “all clear” to use their Slack channels without issue. &lt;/p&gt;

&lt;h2&gt;What caused the recent “Slack-out”?&lt;/h2&gt;

&lt;p&gt;In the space of a week, Slack’s engineering team deployed a massive update to their entire desktop application plus at least 2 other (presumably) smaller code changes. And they aren’t the only ones pushing code at a breakneck pace. &lt;/p&gt;

&lt;p&gt;Over the last half a decade or so, the average release frequency in enterprise IT organizations has plummeted from around 12 months down to just 3 weeks. Many organizations, like Slack, are deploying new code to production weekly or even daily in an effort to out-innovate competitors and to please customers that are jonesing for new features.&lt;/p&gt;

&lt;p&gt;Unfortunately, in many cases the increased pressure and the overall sentiment that “fast isn’t fast enough” comes at the expense of code quality and reliability. New automated testing frameworks and additional tooling have helped to limit the impact, but there’s still no way to account for every possible scenario.&lt;/p&gt;

&lt;h2&gt;How does this impact the company?&lt;/h2&gt;

&lt;p&gt;The most obvious way that application failures affect the business are through negative customer experiences. Unlike with a less critical error that affects only a handful of users, an application outage has the potential to unite the public against the company. As evidenced by this headline from CNN regarding the Slack outage:&lt;br&gt;
Breaking: Slack Is Down, Twitter Goes Berserk&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.overops.com/7-key-lessons-the-latest-slack-outage-taught-us/"&gt;#SlackOutage, #SlackDown and others were trending&lt;/a&gt; last Monday, similar to recent outages from Facebook, Google and Twitter ironically (#TwitterDown was trending once the system was back up). Not only does this help to sway public opinion, it can begin to form a sort of herd mentality against the company. Just think about public opinion of major US airlines… We won’t name names.&lt;/p&gt;

&lt;p&gt;In the short term, negative customer experiences on such a large scale hurt the brand’s reputation. In the long term, brand tarnishment coming from such events hurt the company’s bottom line.&lt;/p&gt;

&lt;p&gt;Poor customer experience isn’t the only way these issues impact a company’s bottom line. Debugging and troubleshooting time means shifting developer and operations resources away from product innovation (which was our original goal…). Contractual SLAs may be breached which could lead to additional financial repercussions.&lt;/p&gt;

&lt;p&gt;Plus, errors in general can contribute to higher log ingestion and storage costs and infrastructure overhead. Here’s a calculator you can use to find out how much your error volume is costing your company each year: &lt;a href="https://calculator.overops.com/"&gt;https://calculator.overops.com/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;How can you stop this from happening to you?&lt;/h2&gt;

&lt;p&gt;Companies like Slack are facing a paradoxical need to build and deploy faster than before while simultaneously improving the quality and reliability of their applications. With less time to write and test the code, improving--or even maintaining--code quality is no easy task.&lt;/p&gt;

&lt;p&gt;In order to succeed, it’s important to track metrics that signal risk to the application and to create automated quality gates based on those metrics. In order to ensure a new release won’t impact customers once deployed to production, here are 4 crucial metrics to track:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New errors&lt;/li&gt;
&lt;li&gt;Increasing errors&lt;/li&gt;
&lt;li&gt;Resurfaced errors&lt;/li&gt;
&lt;li&gt;Slowdowns
In addition to data and metrics, accountability for engineers is incredibly important for ensuring code quality and application health. You can find more information about building a culture of accountability &lt;a href="https://blog.overops.com/changing-the-status-quo-how-to-create-a-culture-of-accountability-in-your-org/"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>slack</category>
      <category>softwarereliability</category>
      <category>applicationfailure</category>
      <category>softwarefailure</category>
    </item>
    <item>
      <title>JVM Architecture 101: Get to Know Your Virtual Machine</title>
      <dc:creator>OverOps</dc:creator>
      <pubDate>Sun, 06 May 2018 08:50:36 +0000</pubDate>
      <link>https://forem.com/overopshq/jvm-architecture-101-get-to-know-your-virtual-machine-1bcd</link>
      <guid>https://forem.com/overopshq/jvm-architecture-101-get-to-know-your-virtual-machine-1bcd</guid>
      <description>&lt;p&gt;Java applications are all around us, they’re on our phones, on our tablets, and on our computers. In many programming languages, this means compiling the code multiple times in order for it to run on different OSes. For us as developers, maybe the coolest thing about Java is that it’s designed to be platform-independent (as the old saying goes, “Write once, run anywhere”), so we only need to write and compile our code once.&lt;/p&gt;

&lt;p&gt;How is this possible? Let’s dig into the Java Virtual Machine (JVM) to find out.&lt;/p&gt;

&lt;h2&gt;
  
  
  The JVM Architecture
&lt;/h2&gt;

&lt;p&gt;It may sound surprising, but the JVM itself knows nothing about the Java programming language. Instead, it knows how to execute its own instruction set, called &lt;strong&gt;Java bytecode&lt;/strong&gt;, which is organized in binary &lt;strong&gt;class files&lt;/strong&gt;. Java code is compiled by the &lt;em&gt;&lt;strong&gt;javac&lt;/strong&gt;&lt;/em&gt; command into Java bytecode, which in turn gets translated into machine instructions by the JVM at runtime.&lt;/p&gt;

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

&lt;h4&gt;
  
  
  Threads
&lt;/h4&gt;

&lt;p&gt;Java is designed to be concurrent, which means that different calculations can be performed at the same time by running several threads within the same process. When a new JVM process starts, a new thread (called the &lt;em&gt;main thread&lt;/em&gt;) is created within the JVM. From this &lt;em&gt;main thread&lt;/em&gt;, the code starts to run and other threads can be spawned. Real applications can have thousands of running threads that serve different purposes. Some serve user requests, others execute asynchronous backend tasks, etc.&lt;/p&gt;

&lt;h4&gt;
  
  
  Stack and Frames
&lt;/h4&gt;

&lt;p&gt;Each Java thread is created along with a frame stack designed to hold method frames and to control method invocation and return. A method frame is used to store data and partial calculations of the method to which it belongs. When the method returns, its frame is discarded. Then, its return value is passed back to the invoker frame that can now use it to complete its own calculation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F111wh4590t4fmcshxw3o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F111wh4590t4fmcshxw3o.png" title="JVM Process Structure" alt="alt text" width="580" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The JVM playground for executing a method is the method frame. The frame consists of two main parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Local Variables Array&lt;/strong&gt; – where the method’s parameters and local variables are stored&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operand Stack&lt;/strong&gt; – where the method’s computations are performed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F089sf8hd7kussvk2m51u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F089sf8hd7kussvk2m51u.png" title="Frame structure" alt="alt text" width="580" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;Let’s go over a simple example to understand how the different elements play together to run our program. Assume we have this simple program that calculates the value of 2+3 and prints the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleExample&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To compile this class we run &lt;em&gt;javac SimpleExample.java&lt;/em&gt;, which results in the compiled file &lt;em&gt;SimpleExample.class&lt;/em&gt;. We already know this is a binary file that contains bytecode. So how can we inspect the class bytecode? Using &lt;strong&gt;javap&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;javap&lt;/em&gt; is a command line tool that comes with the JDK and can disassemble class files. Calling &lt;em&gt;javap -c -p&lt;/em&gt; prints out the disassembled bytecode (-c) of the class, including private (-p) members and methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Compiled from "SimpleExample.java"
class SimpleExample {
  SimpleExample();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."&amp;lt;init&amp;gt;":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_2
       1: iconst_3
       2: invokestatic  #2                  // Method add:(II)I
       5: istore_1
       6: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
       9: iload_1
      10: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V
      13: return

  public static int add(int, int);
    Code:
       0: iload_0
       1: iload_1
       2: iadd
       3: ireturn
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now what happens inside the JVM at runtime? &lt;em&gt;java SimpleExample&lt;/em&gt; starts a new JVM process and the main thread is created. A new frame is created for the main method and pushed into the thread stack.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static void main(java.lang.String[]);
  Code:
     0: iconst_2
     1: iconst_3
     2: invokestatic  #2                  // Method add:(II)I
     5: istore_1
     6: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
     9: iload_1
    10: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V
    13: return
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main method has two variables: &lt;em&gt;args&lt;/em&gt; and &lt;em&gt;result&lt;/em&gt;. Both reside in the local variable table. The first two bytecode commands of main, &lt;em&gt;iconst_2&lt;/em&gt;, and &lt;em&gt;iconst_3&lt;/em&gt;, load the constant values 2 and 3 (respectively) into the operand stack. The next command &lt;em&gt;invokestatic&lt;/em&gt; invokes the static method add. Since this method expects two integers as arguments, &lt;em&gt;invokestatic&lt;/em&gt; pops two elements from the operand stack and passes them to the new frame created by the JVM for &lt;em&gt;add&lt;/em&gt;. &lt;em&gt;main’s&lt;/em&gt; operand stack is empty at this point.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static int add(int, int);
  Code:
     0: iload_0
     1: iload_1
     2: iadd
     3: ireturn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;em&gt;add&lt;/em&gt; frame, these arguments are stored in the local variable array. The first two bytecode commands, &lt;em&gt;iload_0&lt;/em&gt; and &lt;em&gt;iload_1&lt;/em&gt; load the 0th and the 1st local variables into the stack. Next, &lt;em&gt;iadd&lt;/em&gt; pops the top two elements from the operand stack, sums them up, and pushes the result back into the stack. Finally, &lt;em&gt;ireturn&lt;/em&gt; pops the top element and passes it to the calling frame as the return value of the method, and the frame is discarded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static void main(java.lang.String[]);
  Code:
     0: iconst_2
     1: iconst_3
     2: invokestatic  #2                  // Method add:(II)I
     5: istore_1
     6: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
     9: iload_1
    10: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V
    13: return
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;main’s&lt;/em&gt; stack now holds the return value of &lt;em&gt;add&lt;/em&gt;. &lt;em&gt;istore_1&lt;/em&gt; pops it and sets it as the value of the variable at index 1, which is &lt;em&gt;result&lt;/em&gt;. &lt;em&gt;getstatic&lt;/em&gt; pushes the static field &lt;em&gt;java/lang/System.out&lt;/em&gt; of type &lt;em&gt;java/io/PrintStream&lt;/em&gt; onto the stack. &lt;em&gt;iload_1&lt;/em&gt; pushes the variable at index 1, which is the value of result that now equals 5, onto the stack.&lt;/p&gt;

&lt;p&gt;So at this point the stack holds 2 values: the ‘out’ field and the value 5. Now &lt;em&gt;invokevirtual&lt;/em&gt; is about to invoke the &lt;em&gt;PrintStream.println&lt;/em&gt; method. It pops two elements from the stack: the first one is a reference to the object for which the println method is going to be invoked. The second element is an integer argument to be passed to the println method, that expects a single argument. This is where the &lt;em&gt;main&lt;/em&gt; method prints the result of &lt;em&gt;add&lt;/em&gt;. Finally, the &lt;em&gt;return&lt;/em&gt; command finishes the method. The main frame is discarded, and the JVM process ends.&lt;/p&gt;

&lt;h2&gt;
  
  
  “Write Once, Run Anywhere”
&lt;/h2&gt;

&lt;p&gt;So what makes Java platform-independent? It all lies in the bytecode.&lt;/p&gt;

&lt;p&gt;As we saw, any Java program compiles into standard Java bytecode. The JVM then translates it into the specific machine instructions at runtime. We no longer need to make sure our code is machine-compatible. Instead, our application can run on any device equipped with a JVM, and the JVM will do it for us. It’s the job of the JVM’s maintainers to provide different versions of JVMs to support different machines and operating systems.&lt;/p&gt;

&lt;p&gt;This architecture enables any Java program to run on any device having a JVM installed on it. And so the magic happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Java developers can write great applications without understanding how the JVM works.&lt;/p&gt;

&lt;p&gt;However, digging into the JVM architecture, learning its structure, and realizing how it interprets your code will help you become a better developer. It will also help you tackle really complex problem from time to time 🙂&lt;/p&gt;

&lt;p&gt;PS. If you’re looking for a deeper dive into the JVM and how all of this relates to Java exceptions, look no further! (&lt;a href="https://blog.overops.com/the-surprising-truth-of-java-exceptions-what-is-really-going-on-under-the-hood/?utm_source=devto" rel="noopener noreferrer"&gt;It’s all right here&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Written by &lt;a href="https://twitter.com/tzofias" rel="noopener noreferrer"&gt;Tzofia Shiftan&lt;/a&gt;. First published on &lt;a href="https://blog.overops.com/jvm-architecture-101-get-to-know-your-virtual-machine/?utm_source=devto" rel="noopener noreferrer"&gt;The OverOps Blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>jvm</category>
      <category>bytecode</category>
    </item>
    <item>
      <title>Why I Deleted My IDE; and How It Changed My Life For the Better</title>
      <dc:creator>OverOps</dc:creator>
      <pubDate>Wed, 18 Apr 2018 09:16:08 +0000</pubDate>
      <link>https://forem.com/overopshq/why-i-deleted-my-ide-and-how-it-changed-my-life-for-the-better-hli</link>
      <guid>https://forem.com/overopshq/why-i-deleted-my-ide-and-how-it-changed-my-life-for-the-better-hli</guid>
      <description>&lt;p&gt;About 3 years ago, I made a big change in the way that I write code. It occurred to me that in a lot of cases, my IDE was slowing me down more than it was helping me work. So, I made the drastic decision to delete it completely.&lt;/p&gt;

&lt;p&gt;Of course, many people are shocked when they hear about this, and it’s definitely not recommended for every developer. In this post, I’ll share the motivations behind deleting the IDE in the first place, how I moved forward without it and who else may want to consider this as an option.&lt;/p&gt;

&lt;p&gt;Ready?&lt;/p&gt;

&lt;h1&gt;
  
  
  5 Reasons Why I Deleted My IDE
&lt;/h1&gt;

&lt;h3&gt;
  
  
  1. System Performance
&lt;/h3&gt;

&lt;p&gt;I work with many programming languages at the same time: Java for our servers, C++ for some of our clients, JavaScript+CSS+HTML for our frontend, along with Groovy+Bash for some automated tasks. Running multiple IDEs for each language required too many resources (i.e. CPU/RAM) which led to issues running the actual program I was developing. Some of the IDEs froze from time to time while others just crashed. With all of this, it took too long to compile, link and publish the code.&lt;/p&gt;

&lt;p&gt;Plus, it took it a long time to warm up everytime I would reboot my computer because it was trying to run so many IDEs. To avoid the long wait, I started to put my computer in sleep mode for months instead of shutting down which caused the OS to become slower over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. System Reliability – “Voodoo”
&lt;/h3&gt;

&lt;p&gt;As mentioned above, when you work with an IDE, you have to deal with it just crashing for no reason. It happened to me especially with Eclipse and XCode but also with other IDEs.&lt;/p&gt;

&lt;p&gt;Other times, exceptions in your program cause bugs in the IDE or unexpected behavior. Most of the time either clean+build or clean+publish solves it, other times you have to close the IDE, clean its metadata and configure it from scratch.&lt;/p&gt;

&lt;p&gt;For example, there were times I just couldn’t stop the server, probably because of a bug in my code, however it’s reasonable to expect the IDE to understand that I’m in the middle of development and allow me to kill the process if bugs occur.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Multiple Environments
&lt;/h3&gt;

&lt;p&gt;My day-to-day work requires me to switch between building features, code reviews and bug fixing. I want the action of switching between tasks to be cheap (in time) and to be able to work on many things in parallel. With an IDE this is much harder to achieve. And there are two reasons why. First, because it uses a lot of CPU, RAM, etc.. And second, multiple instances of the same IDE might interfere with each other.&lt;/p&gt;

&lt;p&gt;On top of that, when switching between branches during work, which happens a lot because I work on features and bugs at the same time, it took it forever to re-index the code and get ready for work.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Working on Remote Servers
&lt;/h3&gt;

&lt;p&gt;For my work, I sometimes have to run multiple servers on multiple remote machines and run tests against them. I don’t like to build a package and install it just for the testing. I prefer to use these machines as if they were mine, and working without an IDE makes this task much easier.&lt;/p&gt;

&lt;p&gt;Still, it’s more comfortable to edit the code using my favorite text editor (Sublime) instead of using vim or other command line-based editors. I overcome this issue by using a combination of rsync, git push/pull, sftp or even just copy/paste into vim.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Accessibility
&lt;/h3&gt;

&lt;p&gt;Even when the IDE is fully configured with custom shortcuts, there are actions that require the use of the mouse. The problem with this is that even just moving your hand from the keyboard to the mouse for ordering, resizing views or moving the keyboard focus to a certain part of the IDE slows you down. This is a matter of personal preference, but I prefer to avoid this as much as possible.&lt;/p&gt;

&lt;p&gt;Another important thing regarding the IDE is the amount of space it takes from the screen: one row for the window title, another one for menus and another for the toolbar. And that’s even before the tab switcher between open files starts. That causes the code itself to be limited to only part of the screen and uncomfortable to work on.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, You Deleted Your IDE — What’s Next?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Learning About IDE Functions
&lt;/h3&gt;

&lt;p&gt;First, you’ll have to learn about what the IDE does for you, how it compiles the code, how it publishes it to the servers, and how the files are organized in the file system. Luckily for me, &lt;a href="https://www.overops.com/?utm_source=dev"&gt;OverOps&lt;/a&gt; uses standard build tools like Gradle, CMake, Bash and Groovy which can be run directly from the command line.&lt;/p&gt;

&lt;p&gt;So, I run these tools from the command line and use a combination of Bash commands in order to publish and run OverOps. Basic file operation commands like cp, mv, rm to manipulate the files and less, nohup, kill, ps, htop, etc can then be used in order to monitor and control the program. Just like it is done in the production environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Building Your Own Tooling
&lt;/h3&gt;

&lt;p&gt;After a while, you will start to realize which commands are used the most and you can start to create some aliases for them.&lt;/p&gt;

&lt;p&gt;For my own work, I put those aliases in a ~/.bashrc file which is included automatically in every Bash session. Once the file got bigger and included more valuable aliases, I decided it was the right time to back it up. I created a new private git repository (used bitbucket for it) and put the file there. I cloned the repository into a local directory and used the &lt;code&gt;source&lt;/code&gt; command to include it from the ~/.bashrc file.&lt;/p&gt;

&lt;p&gt;At this point, I started to really enjoy this way of working, without an IDE. So, I decided it was time to put some extra effort into modularizing this file like I would for normal code. I created one main file to contain smaller files. Each file has a job, like &lt;code&gt;git.sh&lt;/code&gt; contains all the aliases and functions related to working with git, while &lt;code&gt;docker.sh&lt;/code&gt; contains the basic commands to work with docker. There are also some common files which contain aliases and functions unrelated to any specific program, and some families of files related to specific components in projects I work on, like moduleXXX.sh.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Discovering What You Can Do That Your IDE Couldn’t
&lt;/h3&gt;

&lt;p&gt;One interesting thing about this work style, is that you have the power to create scripts that do complicated tasks that you could never imagine having as a part of the IDE. You can create functions which automate the process of building, running, calling some internal code, waiting for close and checking the error code in the end. All of this with one simple command. Of course, this can also be achieved from within the IDE by creating a plugin, but writing a plugin takes much more effort than just writing some Bash function.&lt;/p&gt;

&lt;p&gt;A good example of this is one of the main projects I led in my company. We needed to do a port of our agent to the AIX platform, but at first we couldn’t find an easy way to run X Server with a GUI on it. Without the IDE, though, this wasn’t a problem. I just installed Bash on that machine and worked on it like it was my own development machine.&lt;/p&gt;

&lt;p&gt;At that time, I realized the real power of working without an IDE was with the remote machines. I could run benchmarks on our product across many machines and test network issues like load balancing, firewalls etc. If an error comes up, no problem, I just add a few debug prints and start it over. The cycle of rebuild is reduced to less than a minute instead of rebuilding a debug version using the build machines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Should Consider Working Without an IDE?
&lt;/h2&gt;

&lt;p&gt;Working without an IDE is not an easy task. It requires a deep knowledge of the technology you are working with, plus you will need to be familiar with the shell environment of the OS you use.&lt;/p&gt;

&lt;p&gt;The learning curve of working without an IDE is steeper than working with an IDE, so this isn’t recommended for beginners. Also, the benefits you get by working without an IDE won’t be worth the effort. Usually, there is no need for working on remote machines or jumping between tasks as a beginner.&lt;/p&gt;

&lt;p&gt;This work style is more suitable for technical leads who jump between tasks frequently; the ones who need to run a Proof of Concept (POC) for some new feature, fix a bug in production and review a new developed feature all within a couple of hours. In these cases, the context switching between tasks is much cheaper if working in multiple environments.&lt;/p&gt;

&lt;p&gt;It can also work well for developers who do Ops tasks like benchmarking, bug investigation in production, networking, or any tasks that need to run on remote machines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging in Development Without the IDE
&lt;/h2&gt;

&lt;p&gt;Debugging is another story. Personally, I never was a big fan of IDE debuggers since debugging skills are very specific to the language, IDE and operating system. That’s why even when I worked with an IDE I rarely used the debugger. Instead I prefer to use debug prints. They work for every language, on every platform. The code should be modeled in a way that helps you to run parts of the code easily without needing to run the whole server for it. Some of the things that can help with this is to avoid shared states and to decouple components.&lt;/p&gt;

&lt;p&gt;Luckily, deciding to work without an IDE won’t affect the way you debug in production or pre-production (staging). This will only change your backend development workflow, so all of your current monitoring tools will work as usual (that means you can still use &lt;a href="https://blog.overops.com/the-new-way-of-handling-java-errors-before-they-hit-production/?utm_source=dev"&gt;OverOps&lt;/a&gt;! 😉 ).&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;(Edited) Concerning refactoring, I will say that code refactoring is definitely easier with an IDE since they have a built-in support for it. Without the IDE, I use regexp or some other small dedicated scripts, depending on the specific task. However, refactoring with regexp will make you an expert with them and it is quite a handy tool to master. Sublime, which is the primary text editor I use, can then index thousand of files very quickly and allows you to find/replace in less than a second. (/Edited)&lt;/p&gt;

&lt;p&gt;I won’t try to convince you that every developer should immediately delete their IDE and start working the way I do. Aside from the effort of configuring the environment for the first time (which may take weeks), from time to time you still need to stop for maintenance, add some aliases, remove others, add support for a new deployment mechanism, etc.&lt;/p&gt;

&lt;p&gt;For any developer that works comfortably with the IDE, this isn’t recommended. But, for anyone that is often irritated by the performance and functionality of the IDE, you should know that there is a way forward without it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Written by David Levanon. Originally published on &lt;a href="https://blog.overops.com/why-i-deleted-my-ide-and-how-it-changed-my-life-for-the-better/?utm_source=dev"&gt;The OverOps Blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ide</category>
      <category>java</category>
      <category>performance</category>
    </item>
    <item>
      <title>5 Ways Developers Waste More Than 20% of Their Work Week</title>
      <dc:creator>OverOps</dc:creator>
      <pubDate>Tue, 06 Feb 2018 13:23:22 +0000</pubDate>
      <link>https://forem.com/overopshq/5-ways-developers-waste-more-than-20-of-their-work-week-2nm6</link>
      <guid>https://forem.com/overopshq/5-ways-developers-waste-more-than-20-of-their-work-week-2nm6</guid>
      <description>&lt;p&gt;&lt;strong&gt;We looked into the most time-consuming tasks for developers. It turns out, more than 25% of their time, on average, is spent troubleshooting.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;More than a full day out of a developer’s work week can be spent troubleshooting production errors. In many cases, it’s even more than that. We hear all the time from engineering teams that their developers are spending &lt;strong&gt;at least 25%&lt;/strong&gt; of their time, on average, solving (or trying to solve) production issues. That means they’re dedicating more than a full day of their work week to troubleshooting.&lt;/p&gt;

&lt;p&gt;Where does all of this time come from? And how does it add up so quickly?&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Identifying there was an error
&lt;/h2&gt;

&lt;p&gt;The first step in solving any problem is admitting you have one in the first place. Then, you should probably figure out what the problem is, if you don’t already know. Surprisingly (or not), this is actually one of the parts in the debugging process that gives developers the most trouble.&lt;/p&gt;

&lt;p&gt;How do you first figure out that something isn’t working right?&lt;/p&gt;

&lt;p&gt;From the people that we spoke with, we learned that, on average, well over half of production errors are reported by the end users. Many of those companies rely on users to provide feedback for up to 80-90% of errors.&lt;/p&gt;

&lt;p&gt;Right away, we know that it isn’t good practice to rely on your users to tell you when you have a problem or that something isn’t working right. Even worse, you don’t want to have problems that AREN’T being reported by users, because that will relate directly to low customer satisfaction and customer churn.&lt;/p&gt;

&lt;p&gt;The problem with relying on end users to report errors is that more often than not, their reports are missing critical information about the error. The dialogue, if you’re lucky enough to be able to have one, takes up a lot of time and there’s a lot of back and forth between engineering, support, and QA that sucks up tremendous amounts of time to retrieve information for troubleshooting.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Determining the severity of the error
&lt;/h2&gt;

&lt;p&gt;Whether your information is coming from user feedback or is showing up in the logs, determining the error rate is essential to recognizing if you’re dealing with a critical issue or not. If the error happens infrequently and doesn’t have a large impact on users, dedicating time to reproducing and resolving the problem may not be worth the cost when there are much more critical errors happening.&lt;/p&gt;

&lt;p&gt;When relying on logs and end users, your means for understanding error rates and severity are limited. When looking at exceptions, logged warnings or errors, the error rate is a key metric for triaging the system’s health as a whole. To identify what are the most critical issues that require our developers’ attention, we use &lt;a href="https://www.overops.com"&gt;OverOps&lt;/a&gt; to sort through new errors and their frequency, before zooming in on their root cause analysis. Some of our most successful users are implementing an “Inbox Zero” approach to exceptions, as if they were emails that require handling. &lt;a href="https://blog.overops.com/the-top-5-disadvantages-of-not-implementing-an-exception-inbox-zero-policy/"&gt;Here’s how they do it&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Locating the affected code (or, Sifting through log files)
&lt;/h2&gt;

&lt;p&gt;Once the error has been identified, it’s time to find its actual location in the code and make sure it’s assigned to the right developer. There are a couple of ways to do this, but the most common practice is to spend hours, or even days, sifting through log files and looking for clues. Aside from this being comparable to looking for a needle in a haystack, the developer who is tasked with resolving the issue may not have a clear idea of what he or she is looking for. Plus, the information they need may not have been written to the logs at all.&lt;/p&gt;

&lt;p&gt;Using log management tools, like &lt;a href="https://blog.overops.com/splunk-vs-elk-the-log-management-tools-decision-making-guide/"&gt;Splunk or Elk&lt;/a&gt;, can help cut through the noise, but they can’t help when the piece of information that you’re looking for was never written to the logs to begin with. In that case, the only way to get the information you need is to add logging verbosity and hope that when (if!) the error happens again, you can see what’s going on.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Reproducing the error
&lt;/h2&gt;

&lt;p&gt;If your logs don’t give you a clear answer to why the error happened, and this is highly likely, trying to reproduce it is the next step. Plus, reproducing an error before you attempt to fix it is good practice regardless. After all, if you don’t first reproduce the problem then how can you be sure that you’ve fixed it when you’re done debugging?&lt;/p&gt;

&lt;p&gt;Unfortunately, with vague reports coming from users and unclear logging statements surrounding the error, finding the exact flow of events that caused it takes a lot of time and may even be impossible.&lt;/p&gt;

&lt;p&gt;If you’re lucky, the problem might have occurred in a part of the code that you recently worked on and you can easily deduce the steps that led to it. Otherwise, the most common way of finding the event flow is to try different things and observe the results, send the ticket to QA for more testing, look through the logs or maybe adding additional logging statements. More often than not, failure in this step is what causes tickets to be closed with the infamous… “could not reproduce”.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Entering “war room mode”
&lt;/h2&gt;

&lt;p&gt;It’s hard to dispute the benefits of working in a “war room-like” set-up. It can bring with it project clarity, stronger communication and increased productivity. So, maybe you’re thinking about rearranging the furniture in your office to boost innovation and progress, or maybe your application crashed for some unknown reason and you need to figure out why RIGHT NOW.&lt;/p&gt;

&lt;p&gt;If you’re lucky, you might only have to do a war room once or twice a year when something catastrophic happens. For others, war room situations occur on a weekly, or even daily, basis. With so much time being dedicated to resolve issues, there’s hardly any time left to advance the product roadmap.&lt;/p&gt;

&lt;p&gt;Some of the developers that we’ve spoken with recently described gathering for a war room situation and still not having the information to move forward with a solution. Some described war room situations that lasted for 5 or 6 days. That’s bad. Not only do these situations take time away from the rest of your work tasks, it can hurt the reputation and revenue of the company.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cure
&lt;/h2&gt;

&lt;p&gt;The most effective way that we’ve found to cut down on the time that your team spends debugging is to automate the error resolution process. That means automating not only the identification of errors, but more importantly the automation of root cause analysis, with access to the complete source code and variable state across the entire call stack of every error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.overops.com"&gt;OverOps&lt;/a&gt; created a tool that does just that. Not only does it provide you with the source and full call stack of any exception or error, it reveals the exact variable state at the time of error so teams no longer need to spend endless hours trying to reproduce it. Check out how it works &lt;a href="https://www.overops.com/request-demo"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Production debugging is absolutely necessary, but letting it take up so much time ISN’T! That 25% adds up quickly. It adds up to a full-time salaried developer for every 3 working on new features and projects. That’s crazy!&lt;/p&gt;

&lt;p&gt;It’s time to start automating the production debugging process so that you can get out of the war room and back to your backlog.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Written by &lt;a href="https://twitter.com/TaliSoroker"&gt;Tali Soroker&lt;/a&gt;, originally published on the OverOps Blog.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>debugging</category>
      <category>development</category>
      <category>java</category>
    </item>
  </channel>
</rss>
