<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Cognizant Softvision Insights - Medium]]></title>
        <description><![CDATA[Cognizant Softvision Insights — a place where thought leaders share their ideas, expertise and knowledge on various technology topics. From AI trends to iOS tips, to Full Stack Web how-tos, readers will walk away feeling inspired with thought-provoking content to lead the way. - Medium]]></description>
        <link>https://medium.com/cognizantsoftvision-guildhall?source=rss----fc208b4204a4---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Cognizant Softvision Insights - Medium</title>
            <link>https://medium.com/cognizantsoftvision-guildhall?source=rss----fc208b4204a4---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 16 May 2026 17:07:47 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/cognizantsoftvision-guildhall" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Switching from Java 7 to Java 8: Part 4]]></title>
            <link>https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-4-c3ce7cccc0ec?source=rss----fc208b4204a4---4</link>
            <guid isPermaLink="false">https://medium.com/p/c3ce7cccc0ec</guid>
            <category><![CDATA[java]]></category>
            <category><![CDATA[java-8-feature]]></category>
            <category><![CDATA[lambda]]></category>
            <dc:creator><![CDATA[Cognizant]]></dc:creator>
            <pubDate>Tue, 09 May 2023 13:08:18 GMT</pubDate>
            <atom:updated>2023-05-09T13:08:17.953Z</atom:updated>
            <content:encoded><![CDATA[<h3><strong>Lambdas Concepts and Structures</strong></h3><p><strong>By Vlad Ionescu, Java Developer, Cognizant Softvision</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7HLPCguNbdnBUUtNA6NJig.jpeg" /></figure><p>So far in this series, we discussed how we can <a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-one-a4d7b54f8dc7?source=friends_link&amp;sk=3a67d540d0beb04d2b6535250c179028">define interfaces</a> as a type for lambda expressions, how to actually <a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-2-50c255f83e39?source=friends_link&amp;sk=becfabcac41363ebf65394ce9098a068">construct the lambdas</a> themselves, and dove <a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-3-6678cc1468c9?source=friends_link&amp;sk=1c6198d9cce692de86e72ec611f127a0">further into functional interfaces</a> and what functional interfaces Java 8 provides for us. In this final article, we cover method references and collections for each iteration, and give a brief introduction to streams.</p><p>Let’s get started with method references. View the example below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/476/1*yLCsCow7t3U2DbvEM9nLfw.png" /></figure><p>In the above image, we’ve defined a static method called “printMessage” which prints out to the console the text “Hello.” In the “main” method, we created a thread and passed it as an argument to a lambda expression that executes our previously defined method. In the previous articles we revealed that, instead of a “Runnable,” we can pass in a lambda since “Runnable” is an interface with only one abstract method called “run.” The code we want to execute in the lambda expression is the method call for “printMessage.” Running the above code would print out “Hello” from a new thread.</p><p>Now, a method reference means that, if we have a lambda expression that takes no parameters and just calls a method as its body, then we can use an alternate way to achieve the same thing. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*fpXNd7RkAQv_FDqcrUE5NA.png" /></figure><p>In the example above, instead of the lambda expression, we used the class name, “MethodReference,” followed by two colon symbols and then the method we want to call. This would look like: MethodReference::printMessage</p><p>Now let’s look at some other examples. Consider the below class.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*jwhN-3WHvqYti0NM8XsFww.png" /></figure><p>Remember this example from our previous articles? We defined a list of cars for which we want to print out all the cars in it. We’re doing that by calling the “perform” method which takes in the list of cars, the condition (which is always true in our case, because we want to print out all the cars), and the action we want to execute (in our case, printing the cars to the console). Running the above would print:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/446/1*wgHPsyxYDNt3AJPyW4y4bA.png" /></figure><p>The lambda that we pass in to the “perform” method looks like this: car -&gt; System.out.println(car). So, the lambda takes in one parameter and executes an action on it (the printing to the console). Similar to the previous case where we used a method reference for a lambda with no input parameters and just a method call, we can use a method reference here too. The difference here is we’re not invoking a static method, but the method “println” on the “System.out” object. If we have a look over the documentation we can see that “System.out” is an object of type “PrintStream.”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/412/1*j4-aURy0zqn9A_bo-_9wFQ.png" /></figure><p>In addition, looking into the PrintStream class, we can see a “println” method defined there which takes in an “Object” as the input parameter.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/401/1*T7cPmmvV0Sy4sjwxMS9pJQ.png" /></figure><p>Switching back to our code, the method reference would look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/461/1*8dkXtLd7iWCXfbDreYGxjA.png" /></figure><p>The method reference call from the above is composed of the instance of the class we want to execute the method on, “System.out,” followed by two colons, followed by the method itself we want to execute, “println.” We can see that there are no input parameters passed to this syntax as they are when using lambdas. This is because the “perform” method takes in as the last parameter a “Consumer” of “Cars” which is a functional interface that defines a method that takes in an input parameter of type “Car” and returns nothing. Thus, when using the method reference, the compiler automatically deduces that the action passed in, the “System.out::println”, has to be executed over a “car” object.</p><p>Now let’s talk about looping through a list of objects in Java. Prior to Java 8, there were two ways of doing that. Let’s see an example below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/530/1*1MBOUU5LjEnL_HWSbP_UKQ.png" /></figure><p>We will be using the same list of “car” objects as we did in our previous examples. The first method for looping through this list is using the “for in” loop.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/353/1*h84d66yZR19QE8mwX5ZkiQ.png" /></figure><p>In the above picture, we start with an index equal to zero and iterate through all the items from the list, one by one. For each of these elements, we will print them out to the console.</p><p>Another method we could use for looping is the “for each” loop. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/258/1*V70ZPUzy3cWsxYRMSwJs9Q.png" /></figure><p>In the above picture, for each car in the “cars” list, we will also print it out to the console. This form is a shortened one compared to the first one, achieving the same result.</p><p>Java 8 introduced a new way of iterating through a collection of items, the “forEach” one. See below as an example.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/394/1*yNwTyTqgBGe_OyVkoXNMmw.png" /></figure><p>Each “Iterable” contains now a “forEach” method which is used to iterate through the elements of a collection. The method receives as an input parameter a “consumer.” In the picture above, the consumer is a lambda that consists of an input parameter of type “car” — the current element being iterated from the list, and the action — printing out to the console the current “car” object.</p><p>The first two methods of looping through a list of elements are called external iteration and this third method is called internal iteration. With the external iteration, the user who writes the code has full control of the iteration, meaning: stating where it should start, where it should end, etc. All of this is done in a sequential order.</p><p>In the internal iteration, one specifies only the intent of the iteration and not how to actually do it. The runtime could choose to use several threads to compute this, one of them handling the first two elements of the list, the second thread handling the next five elements, for example, and so on. This way facilitates a parallel approach of iterating through a list of elements, thus leveraging the multi-core processors computers have nowadays.</p><p>The above lambda can also be replaced with a method reference as shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/327/1*Nr1KOrs0UztF2QqQ4prTwg.png" /></figure><p>Lastly, let’s talk about “streams.” The best way to explain this concept is through an example. Let’s take our well known “cars” example. Let’s say we have a list of “cars” for which we want some work done. For this, we employ three people — one for fixing the engine, one for changing the tires, and one for painting each car red. So what we can do is to talk to each person and say: here are the cars. First, go fix the engine. And, so, the employee will go and fix the engine for each of the cars. Then, we can talk with the second person and tell them to change the tires for each of the cars. And last, talk with the third employee and ask them to paint each car red. We could take this approach, but we made three iterations, one for each employee to go through the list of cars and do their one job. This doesn’t seem very efficient. Another way to think of this is to have some people in a specific place (each one performing its own unit of work) and all the cars lined up like in an assembly line. Then, each of the cars passes by each individual, whereby they perform their duty. When a car passes through all of the employees (aka, each unit of work) then the process of work on it is done. See the picture below where the squares represent the cars.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/241/1*O8L8gfMc6PudBjklZ4YoEA.png" /></figure><p>This is a good analogy of what streams are. They let you build this “assembly line” on a collection of elements. Then, you can call different operations, aka units of work, to perform different tasks on each element of the list (these are the employees who repair the car from the above example). Let’s switch to code and see how that looks.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/516/1*M1PRr0k-GEPj0jXeGhwQlA.png" /></figure><p>In the above image we have the same list of “cars” objects on which we want to perform two operations: one for choosing only the cars that have the model starting with “X” and one for printing these cars to the console. We want the output of the first operation, filtering out the cars, to be stored in a list. The first approach we discussed would mean that first, we would iterate through the list of cars to take into consideration only the cars that start with “X” and then we would iterate again through this new returned list in order to print them out to the console. Again, this doesn’t seem very efficient. What we can do instead is to build that “assembly line.” Refer to the picture below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/506/1*feCDPtFK0qA4pDnE2Zbing.png" /></figure><p>In Java 8, each collection has an additional method called “stream()” which creates the “assembly line.” What follows after “stream()” are the operations that we want to perform on each element of the list. The first operation is the “filter” one which accepts a “Predicate.” We talked about predicates early in this series of articles, and established that this is a functional interface with a method that accepts one input parameter and returns a boolean. So, we will define a lambda expression that, in our example, takes in a “car” object and returns whether or not that car model starts with “X.” Then, the result of the first operation goes as the input for the second operation. The first operation returns a stream containing the filtered cars. Then, “forEach” of these cars, we will print them out to the console — the second operation.</p><p>We can think of the “stream” as a view of the collection on which we invoke it. The stream will always have a source, the backing collection itself. A “stream” is composed of three parts: the collection on which is executed, the set of operations we want to use to process the collection and a terminal operation. The terminal operation is the one that triggers the stream to be executed. In our example, the terminal operation we used is “forEach.” There are others, as well. If the terminal operation wasn’t invoked, then nothing would have happened with the collection, even though we called the “stream()” method and did several processings on it.</p><p>Let’s have a look at another example.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/486/1*YHct3FfL0XTJ-SabOgQEnQ.png" /></figure><p>In the above picture, we used the same collection on which we invoked the “stream()” method, did the same filtering, but instead of printing to the console the cars that start with “X,” we added them to a new list using the “collect” method. This method is also a terminal operation.</p><p>In the example below, we use another terminal operation, called “count.” We count the elements that result after applying the filter on the stream.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/519/1*Gl_XruZa632ql9LAs1BtYQ.png" /></figure><p>In this article series, we saw how lambdas enable the use of functional programming in Java by passing in directly the behavior we want to execute instead of an object containing the behavior. Using lambdas transforms our code into a more readable and concise code, compared to the use of anonymous inner classes which look more like code spaghetti. The use of out-of-the-box functional interfaces that Java 8 brings to the table facilitates the declaration of lambda expressions without the need for the programmer to create one each time. Last but not least, lambdas play a huge role when dealing with streams, enabling us to use them as inputs for different kinds of processings like filtering, adding elements to a new list, and much more.</p><p><strong><em>Article Sources</em></strong></p><p><a href="https://www.youtube.com/@Java.Brains">https://www.youtube.com/@Java.Brains</a></p><p><strong><em>Series Sections</em></strong></p><p><a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-one-a4d7b54f8dc7?source=friends_link&amp;sk=3a67d540d0beb04d2b6535250c179028">Part one — fundamentals</a></p><p><a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-2-50c255f83e39?source=friends_link&amp;sk=becfabcac41363ebf65394ce9098a068">Part two — more on lambdas</a></p><p><a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-3-6678cc1468c9?source=friends_link&amp;sk=1c6198d9cce692de86e72ec611f127a0">Part three — lambdas and functional interfaces</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c3ce7cccc0ec" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-4-c3ce7cccc0ec">Switching from Java 7 to Java 8: Part 4</a> was originally published in <a href="https://medium.com/cognizantsoftvision-guildhall">Cognizant Softvision Insights</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Switching from Java 7 to Java 8: Part 3]]></title>
            <link>https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-3-6678cc1468c9?source=rss----fc208b4204a4---4</link>
            <guid isPermaLink="false">https://medium.com/p/6678cc1468c9</guid>
            <category><![CDATA[java-8-feature]]></category>
            <category><![CDATA[lambda-function]]></category>
            <category><![CDATA[lambda]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[java8]]></category>
            <dc:creator><![CDATA[Cognizant]]></dc:creator>
            <pubDate>Thu, 04 May 2023 12:25:32 GMT</pubDate>
            <atom:updated>2023-05-04T12:25:32.015Z</atom:updated>
            <content:encoded><![CDATA[<h3>Lambdas and Functional Interfaces</h3><p><strong>By Vlad Ionescu, Java Developer, Cognizant Softvision</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7HLPCguNbdnBUUtNA6NJig.jpeg" /></figure><p>With the release of Java 8 came lambdas, which give programmers a way to pass in a behavior in functional programming. In parts <a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-one-a4d7b54f8dc7?source=friends_link&amp;sk=3a67d540d0beb04d2b6535250c179028">one</a> and <a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-2-50c255f83e39?source=friends_link&amp;sk=becfabcac41363ebf65394ce9098a068">two</a> of this series, we talked about how we can define interfaces as a type for lambda expressions and how to actually construct the lambdas themselves. We also covered an exercise where we implemented some functionality in Java 7 and then transformed it using Java 8.</p><p>Besides marking an interface with “@FunctionalInterface” annotation for declaring a lambda, Java 8 came with an out-of-the-box feature, where it exposes several functional interfaces already ready to use. For most of the cases, we do not have to declare our own interfaces just to use for a lambda. Certainly we can do that, as we covered this in our previous articles, but only if we need this for some complex scenario where the already defined interfaces won’t do the job.</p><p>In <a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-2-50c255f83e39?source=friends_link&amp;sk=becfabcac41363ebf65394ce9098a068">the previous article</a>, we concluded with a picture displaying how short and clean the code is when written with Java 8, as shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*e4AcHgEWinyjsrBGr4o1yA.png" /></figure><p>Leveraging existing functional interfaces, it turns out that we can “clean up” this code a little more and make it more Java 8 user-friendly.</p><p>For printing out cars based on a condition, we needed to define our own functional interface. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/240/1*TnVw7K0ZLnbFzCtyFBYeNA.png" /></figure><p>We do not need to do this anymore. What does this interface do? It declares a method that takes in one argument and returns a boolean. Java 8 already comes in with an interface that does just that, the “Predicate” functional interface. Below you’ll find the definition for it from the documentation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/517/1*tBQigCobTti0Ocf6pYxp_A.png" /></figure><p>As we can see, this interface is marked with “@FunctionalInterface” annotation and contains only one abstract method (it also contains other default method, but this is not relevant for our case) called “test(T t)” that takes in one parameter and returns a boolean.</p><p>We can replace our implementation to use the “Predicate” interface instead of the “Condition” one. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*KuFwtRPsu6xLgxCZGs6aGQ.png" /></figure><p>Notice that the rest of the code did not change. Since the “Predicate” interface uses the same abstract method called, “test()”, as we did before in our own interface, we can still use this one to filter based on the condition. The lambda expression remains the same also, since we’re coding to an identical interface.</p><p>The “Predicate” interface is part of the “util.function” package which contains a whole lot more of other functional interfaces as well. Below is a snippet of this package.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/300/1*qzOs76TltD1sWC_bGyFCbA.png" /></figure><p>In the code from above, we are still printing out to the console directly from the method. Let’s change that and pass in this behavior as a lambda expression, rather than hard-coding it in the method. Maybe, later on, we would want to log the car in a file or save it in a Db. For that, we would need to create three separate methods to accomplish these scenarios. Instead, we can define the behavior and just execute it in this method. Then, we will let the caller of the method define each behavior he wants in particular for each case: write the car to the console, save it in a database, or write to a file. Let’s transform the code as in the image below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/710/1*I9xRQ1ChPCMdEyPlZWa9kQ.png" /></figure><p>In the above picture, we refactored the method’s name to “perform()”, since we don’t just print out to the console, but rather we execute whatever behavior is passed in to the method. Besides the other two already defined parameters, we also passed in an extra argument, the “Consumer.” According to the documentation, this functional interface defines one abstract method, called “accept(T t)”, which takes in one argument and returns nothing.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/270/1*z9GZQCw9vD8pliurGwgqCQ.png" /></figure><p>We parameterized the generic Consumer interface with “Car”, so the “accept(T t)” method will accept a “car” object. Then, the caller of this method will have to also pass in the behavior itself which, in our case, is to print out to the console. See the picture below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*7fTdZYGhPuEJcAA61wc3qw.png" /></figure><p>In the first piece of code from above, we sort out the cars and then we “perform” on the “cars” list of objects, a behavior for printing them all out to the console (the condition we pass in is always true).</p><p>In the second piece of code, we “perform” a filter on the “car” list of objects to accept only the ones whose “model” start with “X”. Then, as a behavior, we print them out to the console.</p><p>Besides these two functional interfaces (“Predicate” and “Consumer”), we can mention some others which cover the most important use cases of defining lambda expressions in practice:</p><ul><li>“Supplier&lt;T&gt;” has the method <strong>T get()</strong> — functional interface used to define a lambda expression that just returns something and no input parameters are required.</li><li>“Function&lt;T, R&gt;” has the method <strong>R apply(T)</strong> — functional interface used to define a lambda expression which requires one input parameter of type “T” and returns something of type “R.”</li><li>“BiFunction&lt;T, U, R&gt;” has the method <strong>R apply(T t, U u)</strong> — functional interface used for defining a lambda where we need two input parameters of type “T”, respectively “U”, and returns something of type “R.”</li></ul><p>Now let’s talk a little bit about exception handling when using lambdas. Let’s consider the following scenario: we have a list of numbers and a factor and we want to write a method that performs an operation between each number in the list and the factor. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/511/1*uRztGAMvI9fP_D71KO9SZA.png" /></figure><p>In the above example, the operation we chose to perform between each number of the list and the factor is “sum.” The output for each summing will be:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/49/1*XxqJyKUvVXZLbgM-cSTsQQ.png" /></figure><p>With the above design for modeling the “process” method, it doesn’t leave us with much choice, if we want to pick another operation, let’s say division. For that to work, we would need to change the method and accept a behavior as a parameter instead of hardcoding the behavior directly in the method. In our case, the behavior would be printing out to the console each number “operated” with the factor. So, the operation would take in two parameters and return nothing. We already have an interface defined for this in Java 8, called BiConsumer. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/712/1*GKwd27Oni5xHrR2E1suX7A.png" /></figure><p>In the above picture, we iterate through each number in the list and accept the behavior given by the caller. An example of the caller, using the “sum” operation, would be as shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*ygEjxalUDrE5qkzEWPYoOg.png" /></figure><p>But we can also invoke the “process” method with a different operation, division, for example. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/598/1*8iJ6oGjatk7odIMIQbNEIA.png" /></figure><p>Let’s use the latter one, and running the above code would print out:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/39/1*rObFkdJWWeDh8nC4Pei5SA.png" /></figure><p>But what if we were to change the “factor” variable from its value two to zero? Running the code with this new value will print out the following exception:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*SuVOebpgFGz3dfa3Wixamg.png" /></figure><p>We tried to divide something by zero and we got an exception. In order to mitigate this, we need to handle the exception with a “try/catch” block, but the question is: where exactly do we put this? There are a couple of places where we can insert that block. The most obvious one is when we invoke the “accept” method of the “BiConsumer.” Since that is the place where the lambda expression gets executed, the intuitive way is to wrap the “accept” method into a “try/catch” block, as seen below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/688/1*Rcz0Tv3nYowiKIwsg7xMlQ.png" /></figure><p>Then, for each number we divide by zero with, we will catch the exception. The following displays the output after running the above code.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/211/1*TVdrDak_ddcjMUNBJJHx2g.png" /></figure><p>So this would work, but what happens if we change back the operation from division to sum? Then the “try/catch” block is useless in this case because the code will never throw a division by zero exception for this operation. Moreover, this exception will only be thrown in the case of the division and not any other operation, so it doesn’t quite make sense to wrap the “accept” method with a “try/catch” block just for this particular case. This seems like a poor design decision.</p><p>Another way to achieve the same thing would be to use the “try/catch” block at the caller level. The advantage of this method would be that we can choose to or not to use it depending on the operation in question. Thus, for the division operation we choose to use it, but for the sum operation, we’re not. The following shows how it would look in the case where the caller uses the division operation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/428/1*u88PL5Qf7-lJ70DRVYU4IQ.png" /></figure><p>The “process” method will just “accept” the lambda expression and won’t handle anything related to exceptions.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/695/1*dn_0tbTD0Gl3BlcgnyQZyQ.png" /></figure><p>This approach would work too but, the downside of it is, that the short lambda expression we’ve written in the beginning, now transformed into a code spaghetti.</p><p>Even though there isn’t quite a standard way to handle exceptions when using lambdas, there is a third method, a better way, which leverages the previous method. We still have to use a “try/catch” block, since this is the only way to handle exceptions in Java (we don’t want to throw them up in the calling chain), but we will create a separate method for that, in order not to bloat the original lambda with this structure too.</p><p>Let’s start small and define a method that takes in a lambda expression and returns a new different lambda expression. This will act basically like a wrapper or decorator over the original lambda. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/678/1*Z-O4wkXNujwXl2UiLaJwJw.png" /></figure><p>In the above picture we are returning a new “biConsumer.” We defined a new lambda that takes in two parameters, “a” and “b” and doesn’t return anything but instead, it uses the original “biConsumer” to accept as input parameters the input parameters we defined in the new lambda. Calling this method with the original lambda as the input parameter, where we’re printing out to the console the division between the list of numbers and the factor, will give us the same output as it did when we hadn’t used this method. Thus, the method acts just like a wrapper over the lambda, and not influencing anything for the moment. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*VoxsW0Zb2y6eHhTtAJyfLQ.png" /></figure><p>The output after calling the above will still be:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/45/1*H3EuY4Q53QzUWrRHbQUJoA.png" /></figure><p>But what if we change back the “factor” variable to have the value equal to zero? Then we will have the same problem as before where the exception is not caught and the code run results in an “ArithmeticException” error.</p><p>Having this wrapper method defined, we can now include the “try/catch” block inside it and handle whatever exceptions we want, including this one. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/690/1*wXyn0ELkYxGIp1zg1TE7dg.png" /></figure><p>Basically, we’re returning in the same way the new lambda expression as before, but now we’re surrounding it with the exception handling mechanism. Running the above code, but with the “factor” variable changed back to zero, would print:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/177/1*uzb8eBhS4X2GKJhtTDPuVg.png" /></figure><p>Even though this third method of handling lambda exceptions looks like the second approach in terms of applying the “try/catch” block, this one gives us much more flexibility and cleaner code from a design point of view.</p><p>Next, we will have a look over the “this” reference, and how it behaves, when talking about lambdas. We will make a comparison between the “this” reference in the anonymous classes and lambdas. Let’s start with the former.</p><p>Below we will define an interface that declares one method, called “process”, which takes in one parameter of type “int”, and doesn’t return anything.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/231/1*YSwda7k-fMcPIk_B6FZFTQ.png" /></figure><p>Then, we will define a method, “doProcess”, that takes in a parameter of type “Process” and an “int” and invokes the “process” method on the interface.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/1*SO3lrjo-KbgiMyl6ZZ2bwg.png" /></figure><p>In the “main” method, we will make an instance of the class where we defined the above “doProcess” method, and call the method with an anonymous implementation for the “Process” interface.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/470/1*8xPpYMEcwwOU4SSibkWzLw.png" /></figure><p>In the above implementation of the “process” method, we’re printing out the value of “i” and the “this” object reference. See the output below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/320/1*oj2GM96sszNw2QpdGExo6Q.png" /></figure><p>The “this” object reference from inside the “process” method points to the instance of the anonymous class defined inline. This is not something related to Java 8, and this behavior was there in the prior versions as well.</p><p>Now let’s change the implementation using an anonymous class with a one using lambdas:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*BsfFCGypH1ySAK9kSwVQjw.png" /></figure><p>The whole class looks like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/426/1*ubjyQkMC4wlu7jt1s5FNUA.png" /></figure><p>We can see that trying to print out the “this” reference from inside a lambda results in a compile error saying that “article.ThisReference.this cannot be referenced from a static context”. This error is happening because the “this” reference from inside the lambda is not referring to the context inside the lambda (as it did before with the anonymous class where it referred to the actual instance of the anonymous class), but rather to the “this” reference of the object from the “ThisReference” class where the “main” method resides. Since it’s referring to that, we cannot use the ”this” reference from inside a static context, because static deals with classes and “this” deals with objects.</p><p>However, we can extract the call of the “doProcess” method inside a non-static method and try to reference the “this” from there. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/402/1*quNz9Hq0HuYEsvWMNuafOg.png" /></figure><p>We’ve created an “execute” method from which we invoke the “doProcess” method. Inside the lambda, we are printing out to the console the “this” reference and notice that this line doesn’t show as an error anymore, since the “execute” method it’s an instance method, a non-static one, essentially. Running the above code would print out:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/340/1*uw7pWyGajDGQRECgyXuOqg.png" /></figure><p>Let’s double check what we’ve previously said that the “this” reference from inside the lambda expression is the same with the instance’s class one. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/428/1*-O1OtVAVUdL4mA_lxfXHmw.png" /></figure><p>In the above picture, we’re printing out the value of “this” from the “execute” method and also from the lambda expression. Running the above would print out:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/320/1*HxFJIxkoZmsnUqyhYZ-23g.png" /></figure><p>As we can see, the value for the “this” reference is the same in both cases.</p><p>In the next and final article, we cover more about concepts and structures when dealing with lambdas.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6678cc1468c9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-3-6678cc1468c9">Switching from Java 7 to Java 8: Part 3</a> was originally published in <a href="https://medium.com/cognizantsoftvision-guildhall">Cognizant Softvision Insights</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Switching from Java 7 to Java 8: Part 2]]></title>
            <link>https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-2-50c255f83e39?source=rss----fc208b4204a4---4</link>
            <guid isPermaLink="false">https://medium.com/p/50c255f83e39</guid>
            <category><![CDATA[java-functional-interface]]></category>
            <category><![CDATA[lambda]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[java8]]></category>
            <dc:creator><![CDATA[Cognizant]]></dc:creator>
            <pubDate>Tue, 02 May 2023 14:45:11 GMT</pubDate>
            <atom:updated>2023-05-02T14:45:11.755Z</atom:updated>
            <content:encoded><![CDATA[<h3>More on Lambdas</h3><p><strong>By Vlad Ionescu, Java Developer, Cognizant Softvision</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7HLPCguNbdnBUUtNA6NJig.jpeg" /></figure><p>In the <a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-one-a4d7b54f8dc7?source=friends_link&amp;sk=3a67d540d0beb04d2b6535250c179028">first article of this series</a>, we scratched the surface on the topic of lambdas as they pertain to Java 8. In this article, we will continue to dive further into lambdas.</p><p><strong><em>Lambdas vs. Anonymous Inner Classes</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*dSgkNpOtu9F-B5RR4bSwjw.png" /></figure><p>In the example above there are two ways of printing out “Hello World” to the console. One way is by creating a new class, “HelloWorldSalutation,” that implements the Salutation interface and provides the logic in that class. In the second way, we do not create a new class, but rather a lambda expression that is assigned to the same interface type, “Salutation.” It is almost like we’ve created an inline implementation of the “Salutation” interface using lambda.</p><p>In a manner of speaking we did just that. This can be done in Java without using lambda expressions, but rather with anonymous inner classes. In the example below, we defined an inline implementation for the “Salutation” interface.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*vyCVeHMsypabQmeSFiT6Jg.png" /></figure><p>Both the lambda expression and the anonymous inner class will print out “Hello World” to the console. With some stretching, we can affirm that the lambda expression is a sugar syntax for the inline implementation using an anonymous class. For the most part, you can think of these two ways to be identical, a different way of achieving the same stuff, but behind the scenes, they are not the same and do have subtle differences.</p><p>Since we have already defined previously a method that invokes the “perform()” method on an instance of the “Salutation” interface, and both the lambda expression and the anonymous inner class are of the same type, “Salutation,” we can use that method to print out to the console “Hello World.” See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*y6m_2khasvplUZipuA405Q.png" /></figure><p><strong><em>Type Inference</em></strong></p><p>Let’s use the following example to illustrate this concept.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*_FQ1eFba_DalKo7XPpM1aw.png" /></figure><p>In the above, we have defined a functional interface for a lambda that calculates the length of a String. The interface contains a method that takes in a String and returns an integer. Executing this code will print out nine to the console. In the <a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-one-a4d7b54f8dc7?source=friends_link&amp;sk=3a67d540d0beb04d2b6535250c179028">previous article</a> we discussed how the compiler can infer some information about the lambda expression based on the interface and its only method defined. As an example, in the definition of the above lambda expression, there is no need to explicitly use the keyword “return.” This information has been deducted from the method signature, “int getLength(String s).” It turns out that besides this information, it can also deduct the type of the arguments that are passed through the lambda expression. Therefore, there is no need to explicitly declare “String s” in the definition of the lambda expression.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/492/1*kDrLqrNnNAOcBHi8MCnyZw.png" /></figure><p>The above will also work and the compiler will not complain about it. One last thing we can do to shorten the syntax further is to also remove the parentheses at the end. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/515/1*ybHIgyXODoZjr6rnO7cn3A.png" /></figure><p>And this is the shortest form that a lambda expression can take. Removing the parentheses will only work if we have only one input parameter. Otherwise, the compiler will give an error.</p><p>So, we’ve defined a lambda expression that is in fact a function that takes in one String parameter and returns an integer. We know that based on the abstract method defined in the interface.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/278/1*0K07TPDeVL28Phcmn56kPA.png" /></figure><p>How does the compiler correctly resolve the lambda definition? It infers all the necessary information based on the method defined in the interface. Because of this, we can pass in the lambda expression as an input parameter to a method that prints out the execution of the lambda expression. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/558/1*Ho71KFpCWWQ-VNUZUmG4sA.png" /></figure><p><strong><em>Runnable Using Lambdas</em></strong></p><p>There is a reason why lambda expressions have been built on top of an interface and not on something new, created specific for this purpose. The main reason is for backwards-compatibility. If, for example, we have a library or other code that accepts as an input parameter an interface which has only one abstract method defined, then we can not only pass a concrete implementation of that class, but also a lambda expression. This is a huge advantage to leverage existing code when using it with lambdas. One example of this kind of existing interface is “Runnable.”</p><p>Prior to Java 8, one way to create a thread was to implement the interface “Runnable.”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*jFPMFmL8UC3iuC4snBVF6g.png" /></figure><p>In the picture above, “MyRunnable” implements the “Runnable” interface and overrides the mandatory method “run().” Then, in the main method, we create a new “Thread” and pass in this “Runnable” as an argument to the thread. The last step is to start the thread.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/414/1*xeiz9bgHKHXxMsGfdEB2tg.png" /></figure><p>The output would be:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/430/1*GHF71dTLyTNxoys78x01Sw.png" /></figure><p>Another way to work with “Runnable” before Java 8 is to use it as an anonymous inner class, instead of creating a new class in a separate file. See below an example of that.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/694/1*fW4lVh5e-l43XCKWyvuNPA.png" /></figure><p>In the above picture, we defined inline a new “Runnable” and implemented the “run()” method. The last step, the same as in the first case, is to start the tread. The output would be:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/488/1*TENtNRR2C7BKgdcq3MEv1g.png" /></figure><p>In Java 8 we can leverage lambdas to achieve the same functionality. The code for this becomes simpler and is just two lines. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*KuFVSBUnEsVr1DeQDV60_A.png" /></figure><p>In the above example, in the first line of code, we instantiate a thread to which we pass in a lambda expression. Since the “Runnable” interface contains just one abstract method, “run(),” we can do that. The signature of the “run()” method is “public void run().” Thus, is a method that takes no input parameters and returns nothing. The lambda for this would be “() -&gt; {my_code_here}.” Since we have just one line of code in our implementation of the lambda, namely printing out to the console the text “Printed inside a lambda”, we can remove the brackets and replace the “my_code_here” with the “System.out.println(…)” command. Thus, becoming:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/521/1*WUnqbzkqxJpZuLPts0fD4A.png" /></figure><p>The second line of code from the above picture just starts the thread, the same as in the previous two cases. The output would be:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/256/1*y5bLWCpzYLVuZefZ5RihSw.png" /></figure><p><strong><em>Functional Interface</em></strong></p><p>Throughout this series, we’ve talked about the functional interface being an interface that has only one abstract method. Let’s take, for example, our old “Salutation” class and see how it looked. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/301/1*pBY2luDVjVJ6e3_O8iy91w.png" /></figure><p>Let’s take the “Main” class and define two lambda expressions, one for printing out to the console “Hi!” and the other one, “Hello!”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*fa0JP4kStHaSKlIqYNU9oQ.png" /></figure><p>We can see that no errors are shown in the program, and running this would print out:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/92/1*RqV5zHtZ9ox6PDzRjbARbQ.png" /></figure><p>But what if we decide to add another method to the “Salutation” interface? Let’s call it “other()”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/256/1*fXi97l5yG5l_lWoZau8EEg.png" /></figure><p>We can see now that, in the main program, the lines defining the lambda expressions are marked with errors:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*81hOUbGw8GmtGq6Ui8AUbA.png" /></figure><p>We know that we’ve created that specific interface with the whole purpose of defining lambda expressions. But there are no guarantees that another developer won’t come later on and add different methods for his needs. To prevent this scenario, there is a way to enforce the interface to not allow any other methods than one abstract method and basically mark it as a functional interface. The interface can be annotated with “@FunctionalInterface.”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/298/1*CHXCHtpfWV6ANK-gw8tgsw.png" /></figure><p>Notice now that the error has been shifted from the lambda expressions definition to the actual interface that defines how the lambda should look. This shift comes very much in hand when we talk about third party libraries that are used by a client and lambda expressions are defined using one interface. If someone else from the development team came in and added another method, then all the clients that use that library would have their code broken. To prevent that, we mark the interface as a “Functional Interface” and the code won’t compile at the development side if someone adds other methods in there.</p><p>Let’s remove the extra method in the interface.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/270/1*c2-FdNpEbDb2Tbw5A2uxDA.png" /></figure><p>The “@FunctionalInterface” annotation is not a mandatory one for defining lambda expressions, but is a best practice to use it because of the reasons explained above.</p><p>In the next section of this article we will discuss a small exercise where we want to implement a couple of things first using Java 7 and then transform the code into Java 8 to achieve the same functionality.</p><p>For this exercise, let’s use a sample class called “Car” with getters, setters, a constructor, and an override of the “toString()” method.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/482/1*YDxPtRE2w87EAxXgex_6Gw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/372/1*eXs6Jh7YQVZykkeIh6HjSg.png" /></figure><p>In the “main” method let’s instantiate a list of cars using the following values.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/567/1*x1TzgxLHwVqICBrXH37PvQ.png" /></figure><p>Let’s define a method that prints out this list of cars to the console.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/420/1*2VS4bdw_zQKHe9Q4XhA1xA.png" /></figure><p>The first thing we want to do with this list is to sort it by the car’s brand name (using Java 7). What we need to do for this is to create a comparator in which we specify the sorting condition. We can do this inline, by using an anonymous class and override the “compare()” method, as shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/504/1*lLuoJ31YDTH2cg26jHF85w.png" /></figure><p>The “compare()” method takes in two arguments of type “Car” and returns an integer depicting if the brand name is greater, equal or less than, in a lexicographical order, the other brand name we compare with. After invoking this method, the output would be:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/520/1*vgapobWg299ku7O8xWsb5g.png" /></figure><p>The second thing we want to do on this list is to print out all the cars that meet up a condition. For this, we can define a method that accepts a condition, and based on that condition, if it’s true or false, we print out the cars. Therefore, in order to model the condition itself, we can define an interface that takes one method. This method would return a boolean (we want it to return true or false every time) and will take in an argument of type “Car.” We want to create the condition based on the “Car” object. This would look something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/240/1*TnVw7K0ZLnbFzCtyFBYeNA.png" /></figure><p>Then, the print method for all the cars using a condition would look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*E-QkUnCfEXICEbAQ7eWi8A.png" /></figure><p>The above method will print all the cars that meet the condition. Let’s have a look over an invocation call of this method below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/440/1*531SqkDvpKNh6aNgvaQdGQ.png" /></figure><p>When we invoke the method, we need to create a condition using an anonymous inner class and implement the actual filter. In our case, we would like to take into consideration only the “Car” objects for which “model” property starts with “X.” Therefore, if the “model” starts with “X” then we will print them out. See below the result of this method call.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/428/1*9t89NCljL5zoxPaYdMK77w.png" /></figure><p>Now, let’s have a look at the same examples, but using Java 8 instead of Java 7. This implementation also will be based on the same “Car” object. Based on this, we will populate a list of cars with the same values as we did for the Java 7 example.</p><p>The first thing we did before was to sort the list based on the car’s brand. If in Java 7 we used an anonymous inner class to define an inline comparator based on the brand, now, in Java 8, we can replace that with a lambda expression. We can do that, because the “Comparator” interface defines only one abstract method, called “compare().” Below is the Java 8 definition of the “Comparator” interface as it is described in Oracle’s documentation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*BewNhkTsuG6NRjxTHbi7Uw.png" /></figure><p>In previous sections of this article, we discussed that, as a best practice, this class is marked also with “@FunctionalInterface” annotation. Since it’s a functional interface, we can define a lambda expression for the comparator like below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*a9ic1F6Qhg8TZG5el_yWIQ.png" /></figure><p>Invoking the above method in the main class will result in the same output. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/461/1*pA1Nv1j5hW-W4LrUPuVAzg.png" /></figure><p>Now let’s take a look at printing out only some specific cars from the list that meet up a condition. We went earlier through an example of how we can achieve that using Java 7. For Java 8 we will use a lambda expression for that, as we did for the previous example where we sorted out the list of cars based on the brand name.</p><p>The definition of the method stays the same as in Java 7. We defined a method that takes in a list of cars and a condition, and when the condition is met for that particular car, we print it out to the console. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*E-QkUnCfEXICEbAQ7eWi8A.png" /></figure><p>However, when we invoke this method, we can use a lambda expression for defining that condition, instead of using an anonymous inner class. See below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*PE4rVx1P-iBif8DCimeLIA.png" /></figure><p>Let’s remember that in the beginning of this exercise, using Java 7, we defined a method that prints out to the console all the cars.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/420/1*2VS4bdw_zQKHe9Q4XhA1xA.png" /></figure><p>But we also have a method that prints out conditionally. This seems like redundant code. We can replace the “printAllCars(List&lt;Car&gt; cars)” method with the conditional one to which we pass in, as a condition, the value of true — meaning that we want to display the cars all the time. The invocation of this method would look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/415/1*tnj_0ccynDbWACkABEonXA.png" /></figure><p>Notice the lambda expression, “p -&gt; true,” one of the shortest and concise lambda expressions you can write. The condition will always evaluate to true, printing out all the cars.</p><p>As a result, the whole code looks more clean and short and easy to follow. One downside of this approach would be the learning curve for this lambdas might be a bit steep, until you get used to it. See below the whole code in Java 8 for this exercise.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*e4AcHgEWinyjsrBGr4o1yA.png" /></figure><p>In the next article we will dive in more into functional interfaces and what functional interfaces Java 8 provides for us out-of-the-box.</p><p><strong><em>Article sources</em></strong></p><p><em>[1]</em><strong><em> </em></strong><a href="https://www.youtube.com/@Java.Brains">https://www.youtube.com/@Java.Brains</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=50c255f83e39" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-2-50c255f83e39">Switching from Java 7 to Java 8: Part 2</a> was originally published in <a href="https://medium.com/cognizantsoftvision-guildhall">Cognizant Softvision Insights</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Switching from Java 7 to Java 8 — Part One]]></title>
            <link>https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-one-a4d7b54f8dc7?source=rss----fc208b4204a4---4</link>
            <guid isPermaLink="false">https://medium.com/p/a4d7b54f8dc7</guid>
            <category><![CDATA[java-7]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[java-functional-interface]]></category>
            <category><![CDATA[java8]]></category>
            <dc:creator><![CDATA[Cognizant]]></dc:creator>
            <pubDate>Thu, 20 Apr 2023 17:23:30 GMT</pubDate>
            <atom:updated>2023-05-02T14:49:04.677Z</atom:updated>
            <content:encoded><![CDATA[<h3><strong>Switching from Java 7 to Java 8: Part One</strong></h3><h3><strong>Lambdas fundamentals</strong></h3><p><strong>By Vlad Ionescu, Java Developer, Cognizant Softvision</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7HLPCguNbdnBUUtNA6NJig.jpeg" /></figure><p>In 1991, James Gosling of Sun Microsystems created Java, a programming language. Java allows one to write a program and run it on multiple operating systems. The first publicly available version of Java (Java 1.0) was released in 1995, but it was years later that Java became more widely known, with the release of Java 5.[1] This version is still used on some old legacy banking systems that are complex and therefore more challenging to switch to a newer system. The most commonly used Java versions are 6 and 7, and they brought many improvements compared to their older siblings. However, Java 8 was a turning point from all previous versions in paradigm-shifting and implementing various programming approaches already available in other programming languages.</p><p>Java 8 came with a lot of cool features like lambdas, functional interfaces, optionals, streams, default methods, and so on. In this first edition of a four-part article series, we will scratch the surface of the topic of lambdas.</p><p><strong><em>Why lambdas in the first place?</em></strong></p><p>Lambdas have several advantages, with the topmost being the following:</p><p>1. They enable the use of functional programming in a programming language that is object oriented (OOP) by default.</p><p>2. As a consequence, you can write more readable and concise code, thus avoiding the boiler plate, spaghetti code.</p><p>3. They enable the use of parallel processing, thus leveraging the multiple cores each computer has nowadays, making the code run faster.</p><p><strong><em>What is the difference between functional programming and object oriented programming?</em></strong></p><p>Anything that can be done using functional programming can also be done using object oriented ones. This begs the question, do we even need functional programming? Yes. Functional programming is not a means to replace object oriented programming. Functional programming can be thought of as a new paradigm of writing better and more understandable code. At the end of the day, whether it’s functional programming or OOP, the code is being translated into machine (assembly) code. Therefore, there are some scenarios when writing functional programming code results in a more clean and readable code than using object oriented programming.</p><p><strong><em>What are lambdas?</em></strong></p><p>You can think of lambdas as a way to pass in a behavior in functional programming.</p><p><strong><em>How do you pass in a behavior using OOP (prior to Java 8)?</em></strong></p><p>Everything in OOP is a class or an object. Code blocks are “associated” with classes or objects. You cannot have a piece of action, i.e. a function/method that is isolated. This is because OOP “thinks” in terms of nouns or things, rather than actions or verbs.</p><p>Let’s use the following example:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/786/0*GeKIW-DAPNPiX6ez" /></figure><p>In the above picture we have a “Saluter” class with one “salute()” method. Then, in the main method, we create an instance of this class and invoke the method on it. This will print out “Hello World.” But, “the salute()” method does only one thing– it prints out “Hello World.” What if we wanted to do different things based on an input? We could have this method take an input parameter and, based on it, do a switch. For each switch case, for example, we would print something else. Even though this would work, it is not a very elegant solution and we will end up with spaghetti code inside the “salute()” method.</p><p>Another way of doing this, in Java 7, is to pass in a behavior. The behavior would be a specific implementation of an interface that has one method. In our case let’s call it “perform()”. Then, each implementation of this interface would perform its own specific action, for example, printing out “Hello World.” In the end, “the salute()” method of the “Saluter” class would just invoke the perform() method on the specific instance of the interface. Let’s see how all these pieces tie together.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*gDwrTPy8GwVGhSgm" /></figure><p>The “salute(…)” method from the “Salutater” class now takes one input parameter of type Salutation. This is the interface we’ve previously talked about which abstracts in fact the behavior we pass in. See below the interface that contains one method called perform().</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/0*RbyXE3ULYQfCS42H" /></figure><p>The “main(…)” method creates two salutation types, one of type “HelloWorldSalutation” and the other one of type “HiSalutation.” See below the implementations for these two types, along with the “perform()” method.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/968/0*Lv0EHXz3Omhfq_YY" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/826/0*d5H12ZB5imhR27EN" /></figure><p>Then the “Saluter” object invokes the “salute()” method for each one of them.</p><p><strong><em>How do we pass in a behavior using lambdas (Java 8)?</em></strong></p><p>Now that we’ve taken a look at how to pass in behavior using Java 7, let’s consider if that method solved our problem. It did, but we didn’t quite pass in a behavior, but an object that has a behavior, on which we’ve executed the behavior. This resulted in extra code written for something simple we want to achieve. It would be nice if we could have a method that receives an action as a parameter and inside the method we just execute that action. Below is an example of what this would look like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/522/0*liYunPyJ3dyKwO4P" /></figure><p>In Java 8 we can do that using lambdas. These are just functions that do not belong to a class, but exist in isolation. Moreover, these functions can be treated as values, meaning they can be assigned to a variable which can be used throughout the code. The following is a rough example of that.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/688/0*yIa96tNberK_A5HO" /></figure><p>In the above picture we try to assign the method perform(), that prints out “Hello world!”, to a variable called “blockOfCode.” This is possible in Java 8 using lambdas. Going on, we will analyze the above piece of code and see how we can write a lambda expression based on it.</p><p>First, we can remove the keyword “public”. Since the “public” keyword is used in a context of a class member and lambdas are just functions in isolation, we don’t need that keyword. Next let’s have a look at the name of the method. Its name is “perform.” Since, using this method, we assign it to another variable, we don’t need two names. The method itself will be held in the “blockOfCode” variable name. Using this name, the method can be referenced in other places in the code. Therefore, we can take out the “perform” name too. Let’s see what we have left so far:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/680/0*XRbNTO4W17csuXCo" /></figure><p>We have a method that returns void and prints out “Hello world!” which is assigned to a variable called “blockOfCode.”</p><p>We can take this a little bit further. In Java 8 the compiler is smart enough to deduct the return type based on the actual code. Since it sees that the code only prints out to the console, it deducts that the return type is void. Thus, the return type can also be taken out. See the end result below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*3AssmVOnsO7tPCzz" /></figure><p>These are the elements that you need to provide in order to write a lambda expression. We took the “perform()” method and transformed it into a lambda expression. We didn’t have to specify the “public” keyword, the method’s name, or even its return type. What remains are the open and closing parentheses for the input parameters and the actual block of code. We almost have the full correct syntax for writing a lambda expression except for one minor tweak. We need to add an “arrow” in order to separate the input parameters from the actual block of code. See how a lambda expression looks like in Java 8 below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/670/0*HB8ywngtMJfynGU0" /></figure><p>For the above example we can do one more tweak. If the block of code of the lambda expression contains only one line, then we can remove the curly braces. Then the lambda expression will look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/936/0*zOErT3BY1qxW9UPA" /></figure><p>In our example, this is also a valid lambda expression and both of these ways of writing it are correct.</p><p>For the examples above, we’ve used the IntelliJ IDE. You may have noticed there are some red lines or some highlighted red words. This means that the syntax is not correct. This is true and has been done intentionally.</p><p>If you have been following along until now, you may also have noticed that we haven’t talked about the type that this variable should have. Since Java is a strongly typed language, we cannot have a variable without defining its type. This also applies to lambdas. We’ll get to that a little bit later in the article, but for now let’s assume it has a type and it’s not important at the moment. All we care about is the code on the right side of the equal sign. With that in mind, let’s have a look at some other examples of lambda expressions.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*cFa_XVWmWkOPNr_G" /></figure><p>In the above we defined two more lambda expressions and assigned them to the other two variables. One of the lambdas prints out the same “Hello World!” while the other prints out “Hi!”. But what if we want our lambda expression to take in some input parameters? How would we accomplish that?</p><p>Since the opening and closing parentheses we talked about earlier are for input parameters, we can insert ours there.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/0*Ar1E1RrFspjIY7Jq" /></figure><p>In the above lambda expression we’ve defined an input parameter “a,” that will be taken into consideration into the lambda’s block of code and will return this value multiplied by 2. Notice the “return” keyword inside the block. This is exactly the same way as you would return from a method’s block of code.</p><p>Earlier in this article we discussed how Java is smart enough to deduct the return type. This also stands true in our case. If the lambda’s block of code has only one line, then the “return” keyword can be omitted along with the curly braces.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/702/0*wg5Cr8cI18MeFT_N" /></figure><p>Note: It is forbidden to have the “return” keyword without the curly braces.</p><p>Let’s look at another example, a lambda expression that sums up two numbers:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/776/0*swyqKhn0x9xlRp7j" /></figure><p>The above lambda takes in as input parameters, “a” and “b” and returns the sum of those two.</p><p>Here’s another example where we want to safely divide two numbers:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/626/0*tKRZcbuc_OOXBLEe" /></figure><p>Since the block of code of the lambda expression contains more than one line, we need to enclose it in curly braces.</p><p><strong><em>What type do we use for lambda expressions?</em></strong></p><p>Let’s get back to the lambda expression type and see how we can define it. Since we want to attach the lambda expression to a variable, we need to declare its type. Let’s get back to our working code where we passed in a salutation type, and in the end it printed out to the console “Hello World!”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*TSOoQxrcvrf1l7ph" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/968/0*rq-xwwAf9I9QJTur" /></figure><p>We want to define the lambda expression for printing out “Hello World!”, which we know how to do, and also assigning it a type. In general, there are a few steps we need to take in order to define the type of a lambda expression:</p><p>1. First thing we need to do is to create an interface. The name for it is not important.</p><p>2. The second thing we need to do is to create a method which has the same signature as the lambda expression we declared. In our case, the lambda expression prints out to the console a simple text, so, in terms of signature, it takes no parameters and returns void. Therefore, the method we create in the interface needs to also take no parameters and return void. As in the case of creating the interface, the name of the method is not important here as well.</p><p>See below the final form of the code. Notice that the red lines have disappeared from the lambda expression definition, meaning it is syntactically correct.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*-lHn8ZtLUWlhTUwm" /></figure><p>If we were to add a parameter to the lambda expression, say “int i,” this would not work since the type assigned doesn’t declare a method which takes one input parameter. See below the error we would receive:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ZEQbcBBSJsablVAp" /></figure><p>Now let’s fix the other examples of lambdas expressions we’ve presented so far and assign them the right type. The “HelloWorldSalutationFunction” type and “HiSalutationFunction” type will adhere to the same functional interface we defined above, since they take no input parameters and print out a specific message to the console.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*7s6366PEjGy39tRf" /></figure><p>The “doubleNumberFunction” takes an integer as input parameter and returns its value multiplied by two. We will assume that the value returned is an integer, too. We need to define a specific functional interface for that.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/692/0*uo18F6rGSOW3GZ2a" /></figure><p>The lambda expression will look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*8CMWPWuoz77L3QY0" /></figure><p>The “addNumbersFunction” takes in two integers as input parameters and returns the sum of those. We will assume that the result is an integer, too. We also need to define a specific functional interface for this scenario since the method from the functional interfaces we already have don’t match the signature we need in this case.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/666/0*OGh2VtKyN5nEtvQF" /></figure><p>The lambda expression will look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*YXwo3vlRRJlpyU81" /></figure><p>The last example we’ve talked about is the “divideFunction.” Since the result of the division is a real number and not an integer, we need to define a different functional interface. The signature of the method will take in two integers and return a double.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/606/0*OWwtrS1IDoKD3iPj" /></figure><p>The lambda expression will look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*cvyeHRuEaH3iHPvv" /></figure><p>Remember that the first thing we need to do when assigning a lambda expression to a type is to create an interface of that type. This step is, in fact, optional if we already have an interface that has a method with the same signature we need. In one of the previous examples, we had a lambda that printed out “Hello World” to the console and we’ve created an interface for it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*WbolGuWQoV1TO6z_" /></figure><p>We can do that, but we can also reuse the existing “Salutation” interface which contains one method with the signature we need for printing out “Hello World” to the console.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/0*MzL1Su876VQcuq0d" /></figure><p>The lambda expression will look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*XhIwWah5utoczM9e" /></figure><p>If we were to add another method to the “Salutation” interface, then we would get an error when we use that type for the lambda expression. See below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/508/0*o9Vt-y-on1EPgmB2" /></figure><p>We will receive the following error:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*U87V1m2PCgEubkTE" /></figure><p>Therefore, the interface needs to have only one abstract method in order to be able to assign it as a type for a lambda expression. Otherwise, it would not know which one of the methods it should use in order to correctly resolve the lambda expression.</p><p>Let’s look at the following piece of code:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*-HuCuJfRDSA_fy7R" /></figure><p>We have a concrete implementation of the “Salutation” interface called “HelloWorldSalutation,” which we instantiate in the first line of code. The second line of code declares a lambda expression which assigns it to a variable of the same type, Salutation. How do we print out to the console “Hello World” in the first case? We need to call the perform method on the object instance. See below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/544/0*zHZCT1c1e6Jn8ELV" /></figure><p>Since “HelloWorldSalutation” provides an actual implementation of the “perform()” method which prints out to the console, invoking “perform()” in this instance will leverage that implementation.</p><p>But what if we want to invoke the lambda expression from the second line of code to do the same thing? Since it is also an object of type Salutation, we can call the perform() method on this instance as well. See below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/546/0*xkV8zjgGAGxbTZJd" /></figure><p>Notice that there isn’t any syntax error displayed in this case. Since the interface we used for the lambda expression has one public method called perform(), we can call it. But in this scenario, we don’t have a “concrete” implementation of the “Salutation” interface as in the first case, but rather we defined a function, the lambda expression, which acts like the concrete implementation of the interface.</p><p>This is how we invoke a lambda expression to be executed — we call the method that it’s exposed in the interface on the instance variable which lambda expression is assigned to. Both lines of code from above will print out to the console “Hello World.”</p><p>Let’s go back to the previous examples we’ve talked about so far, and complete the code with invoking the lambda expressions.</p><p>The first example used the “Hello World” and “Hi” lambda expressions. They look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*tN-7nP0ctoz7Zgxd" /></figure><p>These expressions use the following interface:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/492/0*82IH3KHrogA2VKQD" /></figure><p>The code for invoking the following lambdas looks like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/606/0*DoBy5a-F4TESD38y" /></figure><p>The output after invoking lambdas is below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/594/0*1heqfhVLPXoWLVEi" /></figure><p>This is the full circle flow of defining a lambda expression, declaring its associate interface, and invoking the lambda.</p><p>In our second example, we looked at how we could double a number using a lambda expression.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*fq1OtFGnk_tTSBuJ" /></figure><p>The associated interface for it looked like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/724/0*jXT5tN0qbCxvCUcV" /></figure><p>The code that invokes the lambda is pretty similar with the one from the first example, but now, since we return a new doubled value, we assign it to a variable. See below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*g40GA6WyZzL-mCgG" /></figure><p>After invoking the above code, it will print out to the console the following:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/582/0*QL2obPcwgz9E1I9g" /></figure><p>In the third example, we defined a lambda that calculated the sum of two numbers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*wzhNSkxJQng_KYU2" /></figure><p>For this we defined the following interface:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/690/0*06d9UPGrk76HNM9K" /></figure><p>Below is the code for invoking this lambda with two arguments.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*TphHq-AGWROi5hYP" /></figure><p>The above will print out 7 to the console.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/590/0*_4K7w3A7ZJUahu19" /></figure><p>In the last example we had a look over the division of two integers. The lambda expression looked like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*oVS1HvV6wnyw_mjW" /></figure><p>The interface for defining the above lambda looks like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/610/0*TKCbN0mTfzysIE-p" /></figure><p>The invoking of the lambda expression dividing two numbers looks like the below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/994/0*4Ed79bQimrRIP3Bg" /></figure><p>The result for the above invocation is the following:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/0*0OGqqXWI5Dd5_LWS" /></figure><p>In this article we explained the basics of lambdas. We learned the anatomy of this concept introduced in Java 8 by detailing how to define a lambda and its associated interface and how to later invoke it.</p><p>In the <a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-2-50c255f83e39?source=friends_link&amp;sk=becfabcac41363ebf65394ce9098a068">next part in this series</a>, we will dive further into this function and explain more about what happens behind the scenes when we define a lambda. We will also have a look into some of the out-of-the-box functional interfaces that help us when defining lambdas.</p><p><strong><em>Article sources</em></strong></p><p><em>[1]</em><strong><em> </em></strong><a href="https://www.vogella.com/tutorials/JavaIntroduction/article.html">https://www.vogella.com/tutorials/JavaIntroduction/article.html</a></p><p><em>[2]</em> <a href="https://medium.com/@kasunpdh/java-lambda-expressions-3195f677ed38">https://medium.com/@kasunpdh/java-lambda-expressions-3195f677ed38</a></p><p><em>[3]</em> <a href="https://www.youtube.com/@Java.Brains">https://www.vogella.com/tutorials/JavaIntroduction/article.html</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a4d7b54f8dc7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cognizantsoftvision-guildhall/switching-from-java-7-to-java-8-part-one-a4d7b54f8dc7">Switching from Java 7 to Java 8 — Part One</a> was originally published in <a href="https://medium.com/cognizantsoftvision-guildhall">Cognizant Softvision Insights</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[API Security Challenges]]></title>
            <link>https://medium.com/cognizantsoftvision-guildhall/api-security-challenges-91fc7cab00c8?source=rss----fc208b4204a4---4</link>
            <guid isPermaLink="false">https://medium.com/p/91fc7cab00c8</guid>
            <category><![CDATA[qa]]></category>
            <category><![CDATA[quality-engineering]]></category>
            <category><![CDATA[api]]></category>
            <category><![CDATA[api-development]]></category>
            <category><![CDATA[api-security]]></category>
            <dc:creator><![CDATA[Cognizant]]></dc:creator>
            <pubDate>Wed, 05 Apr 2023 16:43:39 GMT</pubDate>
            <atom:updated>2023-04-05T17:01:06.786Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>By Elena Marin and Roxana Ambrozie, QC Engineers, Cognizant Softvision</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vG3a9Is2v5Us5sIlqb-rNg.jpeg" /></figure><p>An API, or Application Programming Interface, is a connection between two or more computers, respectively software applications. These connections have simple, well-defined rules that explain how computers or software applications communicate with each other. The use of APIs has been growing over the years, and as organizations move further to the cloud-native path, the use of APIs will continue to grow — along with potential security risks.</p><p>Today, APIs can face a lot of challenges when it comes to security. But before we dive into security issues, we must first understand what an API is and the role an API plays today. This white paper, <a href="https://www.cognizantsoftvision.com/wp-content/uploads/2015/04/04165156/API-Security.pdf"><em>API Security Challenges</em></a>, covers the basics of APIs, including their evolution, how they work, and common protocols and architectures before discussing security challenges. We then present common API security vulnerabilities and types of attacks so that we can focus on making the attacker’s job more difficult.</p><p><a href="https://www.cognizantsoftvision.com/wp-content/uploads/2015/04/04165156/API-Security.pdf">Click here</a> to download <em>API Security Challenges.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=91fc7cab00c8" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cognizantsoftvision-guildhall/api-security-challenges-91fc7cab00c8">API Security Challenges</a> was originally published in <a href="https://medium.com/cognizantsoftvision-guildhall">Cognizant Softvision Insights</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What’s all the fuss about “null”?]]></title>
            <link>https://medium.com/cognizantsoftvision-guildhall/whats-all-the-fuss-about-null-aadb7798b4ea?source=rss----fc208b4204a4---4</link>
            <guid isPermaLink="false">https://medium.com/p/aadb7798b4ea</guid>
            <category><![CDATA[enterprise-technology]]></category>
            <category><![CDATA[code]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[writing-code]]></category>
            <dc:creator><![CDATA[Cognizant]]></dc:creator>
            <pubDate>Thu, 16 Mar 2023 15:32:43 GMT</pubDate>
            <atom:updated>2023-03-16T15:32:43.569Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>By Sergiu Buceac, Senior Software Engineer, Cognizant Softvision</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hPJHS7zCUzgajoJKQV0FXw.jpeg" /></figure><p>When researching ways of writing cleaner and more robust code, there is a multitude of materials that debate the existence of this concept in an object-oriented language. This can be surprising since in practice we see “null” everywhere, yet these blogs, articles, and videos make it seem like it’s the enemy of<strong> </strong>beautiful, resilient code.</p><p>So, what are the reasons why “null” might be considered “bad?” What, if anything, can we do about it?</p><p><strong>The quick conclusion</strong></p><p>For the impatient among us, the quick conclusion is that completely eliminating “null” is pretty much impossible for a language that already supports it. In such cases, even avoiding “null” might be more effort than it’s worth, especially in a language where this concept already permeates everywhere, including its base libraries. However, reducing its usage could allow programmers to develop some good, worthwhile practices.</p><p><strong>The problems</strong></p><p>There are several reasons why “null” is said to be a “bad” concept:</p><p>1. <strong>Ambiguous at best</strong></p><p>A “null” value tries to represent several concepts (“nothing,” “undefined,” “not valid,” etc.) under the same umbrella. The way to interpret such a value varies greatly, not just from person to person, but also depending on the situation or context in which it is being used.</p><p>While this doesn’t seem to be a huge problem at face value, the more insidious issue is that it hides intent from the caller. This forces the caller to look into the implementation details, debug, and check for the real meaning behind that value. If the caller fails to take action, then the only alternative is to assume the meaning and possibly miss the correct way to handle it.</p><p>For business-related classes, a value of “null” often doesn’t really make sense. It’s an ambiguous technical term related to implementation, while a business class should reflect an object in reality. For instance, if a method searches for an employee and doesn’t find anything, returning “null.” What does a “null” employee even mean? Of course, a caller might be confused when receiving such a value, forcing the focus to be switched from handling an employee business object to a technical “null” value.</p><p>2. <strong>Guard clauses</strong></p><p>Once a method is capable of returning “null” in any of its branches, it can lead to a lot of bloat in the code. This is also a bit irresponsible because returning “null” passes the handling of an internally invalid or unexpected state from the method to its callers, forcing the callers to deal with details they should not even know about. Now all callers are forced to check for, handle, and possibly even propagate “null” to its own callers. And if a caller fails to do so, then the runtime–and the clients–will surely notice the crash caused by the missing check.</p><p>Fortunately, recent versions of the .NET framework compilers can help identify where a guard clause might be needed by statically checking for possible “null” usages.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/988/0*46CFo9rwgdBKhg09" /></figure><p>3. <strong>A special case that is a bit too special</strong></p><p>Although there are plenty of examples of special values, using “null” requires a lot more consideration and mental modeling when using it.</p><p>An empty string or the PI constant are special values, but the difference is that any method that you can call on a random string, you can also call on an empty string as well. Any method you can call on a number you can also call on the PI constant. “Null,” however, is quite the opposite; it tries to represent a lack of value while being assigned just like a normal value. For example, you can do anything with an employee object unless it’s “null,” “ToLower” can be used on any string unless it’s “null,” and it is highly likely you will only get this feedback at runtime when it can be too late to return to normal operations.</p><p>Also, there’s plenty of inconsistencies throughout frameworks and languages on how to handle operations that involve “null” values. The .NET framework has always been pretty consistent on that front fortunately.</p><p><strong>Some proposed solutions</strong></p><p>1. <strong>Optional types</strong></p><p>Optional types have been suggested as an alternative to “null” by wrapping a value into an object that also exposes, for example, a Boolean indicating if a value is present or not. Although this does solve the problem of the polymorphic nature of “null,” since optional types are often provided as a templated class, in practice it does little to solve the aforementioned issues because:</p><p>a) Optional types just replace checks for “null” with checks on the Boolean property of the optional type</p><p>b) Using optional types suffers from the same issue of proliferation along the call chain as “null”</p><p>c) Just replacing a generic “null” with another generic optional type is often not enough. For example, when a search for a user yields no results one might want to return a generic anonymous user with part of the functionality of a normal user.</p><p>2. <strong>Throwing exceptions</strong></p><p>Instead of propagating “null” or optional types we could throw exceptions in case a rule or result is not what we expected. At first glance this looks like a good approach, and for cases where the invalid value is truly unexpected an exception is a good practice. However, careful consideration must be taken into what really is an unexpected event.</p><p>Exceptions are often misused and overused as crude ways to change the control flow of a business operation. There are not that many errors that are completely unrecoverable and must result in a full stop of an operation. Remember that not all errors are exceptions.</p><p>For example, let’s say that we save some configuration for a user in a file and we have a method that reads the configuration from that file on user login. From the business’ point of view, does it make sense to prevent a user login because the configuration file could not be opened? Site owners would not want to prevent users from using their shop for that reason and would much rather use a default set of configurations.</p><p>Knowing the business domain and talking to business experts will convert a lot of those exceptions into alternative error handling procedures. Still, this seems to be a common and easy trap to fall into, and some languages have dropped exception handling altogether (for example, <a href="https://go.dev/doc/faq#exceptions">GO</a>).</p><p>3. <strong>Avoiding “null” as much as possible</strong></p><p>We’ve already covered that avoiding “null” completely is not possible, since the .NET framework itself and its base class libraries make no effort to specifically avoid “null.” That being said, what would it take to significantly reduce the usage of “null,” especially in the core business implementation, which is part of the software where changes occur more often? Well, it takes a lot of attention and communication combined with implementing some basic patterns to isolate the business core as much as possible. Some examples of steps that can be taken are:</p><p>a) Since we have no control over third party libraries, we could (and likely should), hide them behind something. The adapter pattern comes to mind and this is, in general, a good approach whether we try to avoid “null” or not.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/579/0*aDs8WxwoHZGu7q1j" /></figure><p>Another good approach would be to implement an architectural pattern. For instance, the “Onion” architectural pattern is good at isolating business code from the rest of the system. Remember that database, UI, and file systems are all like external libraries that usually have little or nothing to do with the core business.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/0*0X9bfkn_2JLX33qO" /><figcaption>Image inspiration: <a href="https://dzone.com/articles/onion-architecture-is-interesting">https://dzone.com/articles/onion-architecture-is-interesting</a></figcaption></figure><p>b) Dependency injection has seen a lot of adoption, in part encouraged by the framework itself as, for example, ASP.NET Core already comes with a built-in dependency injection container. Therefore, since an unregistered dependency just replaces the “null” reference exception with a different exception type, we can try to validate the registered dependencies. The built in dependency container from ASP.NET Core can validate its dependencies at startup, although with some limitations. One limitation of this approach is that dependencies directly injected in controllers are not validated because of the special way they are registered in the default ASP.NET dependency container.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/806/0*-1YFc0NJkm57Ue4y" /></figure><p>c) Carefully watch for any call to the base class library for methods that might return null (for example, FirstOrDefault in a LINQ expression). Unfortunately, this is harder to do by hiding it behind an adapter since it’s such a common and basic functionality (it’s part of the base class library, after all).</p><p><strong>Nix “null”</strong></p><p>Unfortunately, for .NET avoiding “null” is impossible. But in all other cases, trying to avoid “null” as much as possible can significantly reduce code clutter and bring what actually matters to the forefront– without getting lost in lots of easily avoidable statements. It also encourages business code isolation from the rest of the system, while helping programmers adopt good patterns and practices. So while avoiding “null” is challenging, it’s worth it.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=aadb7798b4ea" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cognizantsoftvision-guildhall/whats-all-the-fuss-about-null-aadb7798b4ea">What’s all the fuss about “null”?</a> was originally published in <a href="https://medium.com/cognizantsoftvision-guildhall">Cognizant Softvision Insights</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Unsung Hero of our Connected World]]></title>
            <link>https://medium.com/cognizantsoftvision-guildhall/the-unsung-hero-of-our-connected-world-a23c159cf7af?source=rss----fc208b4204a4---4</link>
            <guid isPermaLink="false">https://medium.com/p/a23c159cf7af</guid>
            <category><![CDATA[backend]]></category>
            <category><![CDATA[rest-api]]></category>
            <category><![CDATA[quality-engineering]]></category>
            <category><![CDATA[api]]></category>
            <dc:creator><![CDATA[Cognizant]]></dc:creator>
            <pubDate>Tue, 07 Mar 2023 14:44:41 GMT</pubDate>
            <atom:updated>2023-03-07T14:44:41.484Z</atom:updated>
            <content:encoded><![CDATA[<h3>Part 2: Approaches, Types &amp; Tools</h3><p><strong>By Tudor Blaga, QC Engineer, Cognizant Softvision</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IRGGkj1bkCoFEYr5Cub8Bw.jpeg" /></figure><p>As more organizations are moving towards a micro-service and service-oriented architecture, the need for effective API testing is becoming more and more critical.</p><p><a href="https://medium.com/cognizantsoftvision-guildhall/the-unsung-hero-of-our-connected-world-e69b25053724?source=friends_link&amp;sk=182fe4ad15ae0f9d52e6ec1279240dd2">Part one of this series</a> covered API basics, REST API, endpoints, web services, and methods. In this second half, we will explore API testing approaches and testing types. We will also reveal some commonly used API testing tools that can help ensure software applications’ smooth functionalities.</p><h3><strong>How to approach API testing</strong></h3><p>All API tests should begin with a clearly defined scope of the program as well as a full understanding of how the API is supposed to work. Start with gathering the following information:</p><ul><li>Information about what endpoints are available for testing</li><li>Information about what response codes are expected for successful requests</li><li>Information about what response codes are expected for unsuccessful requests</li><li>Information about what error messages are expected to appear in the body of an unsuccessful request</li><li>Information about the defined input parameters</li></ul><p>Once factors like the above are understood, testers can perform the test and compare the expected results to the actual results. Tests should include information on responses like:</p><ul><li>The value of the response/reply time</li><li>Data quality, which is a measure of the condition of data based on factors such as accuracy, completeness and consistency</li><li>Confirmation of authorization</li><li>Error codes</li><li>Status codes</li></ul><p>You can find a complete list for API response status codes <a href="https://restfulapi.net/http-status-codes/">here</a>.</p><h3>Types of API testing</h3><p>Functional testing ensures the API performs exactly as it is supposed to. This test analyzes specific functions within the codebase to guarantee that the API functions within its expected parameters and can handle errors when the results are outside the designated parameters.</p><p><strong>Load testing</strong><br>The point of load testing is to measure where the limit of system performance under high load lies. That’s why we measure response times, throughput, server conditions, etc., while increasing the number of calls.</p><p><strong>Soak testing</strong> <br>Load tests that run over a long period of time can reveal system instabilities like API memory leaks. So when you have a weekend ahead, leave automated soak tests running. On Monday, it will show you whether any unwanted behavior has emerged.</p><p><strong>Stress testing</strong> <br>The idea is to gradually increase the count of virtual users to find the point at which the API starts throwing errors, slows down, or stops responding.</p><p><strong>Spike testing</strong> <br>Contrary to stress testing, here an API undergoes a sudden spike of users. Spike testing checks whether the API is able to stabilize and return to normal functioning after that.</p><p><strong>Scalability testing</strong><br>You want to be sure that your system performance scales according to the changing load. To do so, increase the number of incoming requests and monitor whether it causes a proportional increase in response time.</p><p><strong>Peak testing</strong><br>Similar to soak testing, here you subject your API to the heaviest load while reducing the time of the attack.</p><p><strong>Validation testing</strong> <br>Validation testing includes a few simple questions that address the whole project. The first set of questions concerns the product: Was the correct product built? Is the designed API the correct product for the issue it attempts to resolve? Was there any major code bloat — production of code that is unnecessarily long, slow and wasteful — throughout development that would push the API in an unsustainable direction?</p><p><strong>Penetration testing</strong><br>Penetration testing builds upon security testing. In this test, the API is attacked by a person with limited knowledge of the API. This enables testers to analyze the attack vector from an outside perspective. The attacks used in penetration testing can be limited to specific elements of the API or they can target the API in its entirety.</p><p><strong>Reliability testing</strong><br>Reliability testing ensures the API can produce consistent results and the connection between platforms is constant.</p><h3>Where do you need API testing?</h3><p>API testing is needed when an application’s functionality is dependent on the integration of multiple APIs. It is needed to ensure that the APIs are working properly and returning the expected results. At points it is also needed:</p><ul><li>During the development process to identify and fix bugs and errors in an early state</li><li>Before deployment to ensure that the APIs are ready for production and will function correctly in the live environment</li><li>After deployment to monitor the APIs for any issues and ensure that they continue to function properly</li><li>Whenever there are changes to services to ensure that no new issues have been introduced</li><li>When integration with third-party APIs is developed to ensure that the integration is successful and that third-party APIs are working properly</li><li>For performance testing, to identify bottlenecks and measure the scalability of the APIs</li></ul><p>API testing must be an ongoing process throughout the development cycle and maintenance of the API.</p><h3>Choosing the right tools</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/630/0*H7GfX2OomCN-Hduk" /></figure><p>One of the most common struggles of API testing is choosing the right tool. There is no general proper tool for testing. The term “right tool” for API testing is not determined by a particular tool, but rather determined by some key considerations, such as:</p><ul><li>Basic API Requirements: Does it support the majority of the HTTP requests? Can settings and artifacts be imported from one project/test to another to save time?</li><li>Complexity: Make sure the skillsets in your team are able to learn and use the software in the shortest time possible.</li><li>CI/CD Integration: Check its list of integrations to see if the tool works with CI systems your team is using like Jenkins or Bitbucket, and also if it’s native to avoid extra time trying to configure everything.</li><li>Interoperability: Can the tool be connected to communication platforms like Slack; project management systems like Jira; Git for version control or your team’s toolchain?</li><li>Non-technical Friendly: Read the tools’ documentation to see if they support BDD conventions and are able to export easy-to-understand reports.</li></ul><h3><strong>Recommended Resources</strong></h3><p>Here is a list of API testing tools that are the most commonly used:</p><p><strong>Postman</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/846/0*r0_bTTS3AsrgxhXq" /></figure><p>Postman is an API platform for building and using APIs. Postman simplifies each step of the API lifecycle and streamlines collaboration so you can create better APIs — faster. For more details <a href="https://www.getpostman.com/">visit the Postman website</a>.</p><p><strong>Jmeter</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/780/0*QvPJR3n6EaPf0nfs" /></figure><p><a href="https://jmeter.apache.org/">Jmeter</a> is easy to use, with a rich interface, able to run on Mac and Windows and has integration with Swagger and RAML formats</p><p><strong>Rest-assured</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*iHH55XY-IdWnzQO4" /></figure><p>Initially created for performance testing, <a href="http://rest-assured.io/">Rest-assured</a> transformed to an easy to use functional testing tool. Cache and offline replay of test results. Automation works with CSV files of other types of files to create unique parameters values for the API tests at Speed.</p><p><strong>Soap UI</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*yAlAvv30aR3JKjN6" /></figure><p>A java domain specific language test tool that enables REST services in a simple manner. It is most commonly used to validate responses from requests. <a href="https://www.soapui.org">Soap UI</a> supports all the REST requests (POST, GET, PUT, DELETE, OPTIONS, PATCH, and HEAD).</p><p><strong>Karate</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*rlrxXNgvIVnJ_6aP" /></figure><p>A headless functional testing tool dedicated to API testing, <a href="https://github.com/intuit/karate">Karate</a> allows users to test REST and SOAP APIs and Web Services with no hassles.</p><p><strong>Talend API tester — Free edition</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/916/0*NTWDDXI2_c58SB5_" /></figure><p><a href="https://chrome.google.com/webstore/detail/talend-api-tester-free-ed/aejoelaoggembcahagimdiliamlcdmfm">Talend API tester</a> is an API testing tool that assists users in creating scenarios for API-based BDD tests simply without writing definition steps. Formerly known as Restlet, it interacts with REST or simple HTTP APIs through a visual and easy to use GUI. This extension is excellent to use while testing a platform without needing authorization keys in most of the executed calls.</p><p><strong>Airborne</strong></p><p><a href="https://github.com/brooklynDev/airborne">Airborne</a> is an API automation testing framework with a Ruby-based RSpec-driven framework. Since Airborne is a programming framework, it has no user interface apart from the text file to create code. In addition, to use Airborne, testers need to remember a few critical methods in the toolset and some Ruby and RSpec fundamentals.</p><p><strong>Insomnia</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/776/0*ZaSlvCaIRMafptjV" /></figure><p><a href="https://insomnia.rest/products/insomnia">Insomnia</a> is a free cross-platform desktop application that takes the pain out of interacting with and designing HTTP-based APIs. Insomnia combines an easy-to-use interface with advanced functionality like authentication helpers, code generation, and environment variables.</p><p><strong>API Fortress</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*SmZ5ySBRuVAVm8HC" /></figure><p>Testers and developers can create and automate functional tests since <a href="https://apifortress.com/">API Fortress</a> is a continuous platform for API testing. It has an easy-to-use UI for any skill level and supports Test REST, SOAP, GraphQL, and microservices.</p><h3><strong>Advantages of API Testing</strong></h3><p>Let’s highlight a few of the major advantages that API testing brings:</p><p>API testing plays a crucial role in ensuring the functionality and reliability of APIs. This approach allows for faster and more efficient testing of the application as the API can be tested independently from the user interface.</p><p>API testing can also be used to test performance by simulating various loads and stress testing, making repetitive testing easier for changes and updates. It facilitates compatibility testing across different platforms and devices and helps ensure compliance with industry standards and regulations.</p><p>API testing is a cost-effective and efficient method, enabling early detection of bugs and errors and reducing the cost of fixing them later in the development process. It also enables testing of the integration between different systems to ensure they work together seamlessly, as well as the security of the code to protect against unauthorized access.</p><h3><strong>API Appreciation</strong></h3><p>APIs are an essential part of modern software development, helping easy integration and communication between different applications and systems. As the demand for interoperability and data exchange is continuously growing, APIs will continue to play a critical role in enabling innovation in businesses and applications development, thus making API testing an absolutely crucial process to ensure that the applications are working as expected.</p><p>While APIs may not wear capes, they are the true heroes of our connected world. So next time you place a food order through your favorite app or search for cats of the ‘gram’, take a moment to thank the little API that made it possible.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a23c159cf7af" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cognizantsoftvision-guildhall/the-unsung-hero-of-our-connected-world-a23c159cf7af">The Unsung Hero of our Connected World</a> was originally published in <a href="https://medium.com/cognizantsoftvision-guildhall">Cognizant Softvision Insights</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Unsung Hero of our Connected World]]></title>
            <link>https://medium.com/cognizantsoftvision-guildhall/the-unsung-hero-of-our-connected-world-e69b25053724?source=rss----fc208b4204a4---4</link>
            <guid isPermaLink="false">https://medium.com/p/e69b25053724</guid>
            <category><![CDATA[rest-api]]></category>
            <category><![CDATA[backend]]></category>
            <category><![CDATA[api]]></category>
            <category><![CDATA[api-integration]]></category>
            <category><![CDATA[qa]]></category>
            <dc:creator><![CDATA[Cognizant]]></dc:creator>
            <pubDate>Tue, 28 Feb 2023 14:03:00 GMT</pubDate>
            <atom:updated>2023-03-07T14:45:51.034Z</atom:updated>
            <content:encoded><![CDATA[<h3><strong>Part 1: Basics and Benefits</strong></h3><p><strong>By Tudor Blaga, QC Engineer, Cognizant Softvision</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*z8v7YaMDUDSTc9PGAYjQqw.jpeg" /></figure><p>Application Programming Interfaces, or APIs, are an important and integral part of modern software development, helping different applications and technologies interact and share data between them.</p><p>This two-part article will cover API basics, benefits, testing approaches, tools, and best practices. The following, part one, explores what an API is and dives into the methods, web services, and how the software development process benefits from using APIs.</p><h3><strong>What is API?</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/738/0*dJXZswEo7msNhaUb" /></figure><p>API is the messenger that takes requests and tells a system what you want to do, and then returns the response back to you.</p><p>For an example, the most common analogy is to imagine that you are in a restaurant with a menu in front of you. The kitchen is the part of the system which will prepare your order. The crucial link in communicating your order to the kitchen is missing, and this is where the waiter (the API) steps in. The waiter acts as the messenger, taking your request (your order) and communicating it to the system (the kitchen) on what actions to take. The waiter then returns the response back to you (the food).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/683/0*tpJt3ZuCnN-tmlJ0" /></figure><p>A technical definition for Application Programming Interface (API):</p><p>An API serves as a software interface that enables two applications to communicate with each other without any need for user involvement. It comprises multiple functions and procedures (code) that can be easily accessed and executed, facilitating communication and data exchange between two or more software programs.</p><p>An illustration of a functioning API can be seen through the example of booking.com. This platform gathers information from multiple hotel, apartment, and vendor sources. For instance, when you book a hotel room, you input details such as the number of days you need the room for, room options, breakfast offerings, etc. This, in turn, presents you with various room options and their availability. In this scenario, the application interacts with APIs from multiple vendors, providing access to their data.</p><h3>What is API Testing?</h3><p>API testing is a type of software testing that doesn’t use a Graphical User Interface (GUI) and cannot be done at a front-end level.</p><p>The API lies at the heart of an application, sandwiched between the data layer, the service layer (API), and the presentation layer (UI/GUI). As a middleware, it serves as the connecting link between these layers and enables communication between two software programs.</p><p>The purpose of API testing is to evaluate the Application Programming Interface and ensure that it delivers the expected functionality, performance, reliability, and security. This is achieved by sending requests to one or more API endpoints and comparing the response to the expected outcome.</p><h3>What is REST API?</h3><p>Imagine you are searching for videos of cats on YouTube. You type “cats” into the search field and upon hitting enter, you are presented with a list of videos about cats. This is how a REST API endpoint operates. You send a request for information, and in return, you receive a list of results from the service you are making the request to.</p><p>The anatomy of a Request is as follows:</p><ul><li>The endpoint</li><li>The method</li><li>The headers</li><li>The body (data)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/706/0*n47zhSZW2aFAeRZX" /></figure><h3>What is an Endpoint?</h3><p>An API endpoint is a digital spot where the API can receive requests related to a particular resource hosted on its server. It comprises a uniform resource locator (URL) which provides the location of the resource on the server. An endpoint is a part of the API, while the API as a whole is a set of guidelines that enable multiple applications to share resources.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/694/0*BmC8sfSn2WhnNcxR" /></figure><h3>What is a method?</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/678/0*uFIHOAFxOgPZXDsj" /></figure><p>The method is the request type that you send to a server. The available methods are as follows:</p><p><strong>GET:</strong></p><p>This request is used to get a resource from a server. If you perform a `GET` request, the server looks for the data you requested and sends it back to you. In other words, a `GET` request performs a `READ` operation. This is the default request method.</p><p>Example: GET /store/inventory, which is an operation that returns inventory items from somewhere</p><p><strong>POST:</strong></p><p>This request is used to create a new resource on a server. If you perform a `POST` request, the server creates a new entry in the database and tells you whether the creation is successful. In other words, a `POST` request performs a `CREATE` operation.</p><p>Example: POST /store/order, which is an operation that places and order for something</p><p><strong>PUT / PATCH:</strong></p><p>These two requests are used to update a resource on a server. If you perform a `PUT` or `PATCH` request, the server updates an entry in the database and tells you whether the update is successful. In other words, a `PUT` or `PATCH` request performs an `UPDATE` operation.</p><p>Example: PUT /itemId, which is an operation that updates the information regarding a particular item by id</p><p><strong>DELETE:</strong></p><p>This request is used to delete a resource from a server. If you perform a `DELETE` request, the server deletes an entry in the database and tells you whether the deletion is successful. In other words, a `DELETE` request performs a `DELETE` operation.</p><p>Example: DELETE /store/order/{orderId}, which is an operation that deletes a purchase order by id.</p><p>These methods provide the meaning regarding the request that you are performing. Those operations are named CRUD operations. CRUD is an abbreviation for CREATE, READ, UPDATE, and DELETE.</p><h3>Web Services vs. Web API</h3><p>Web Services and Web API both serve the purpose of facilitating communication between the client and the server. The main distinction between them lies in the manner of communication. To communicate effectively, each of them requires a request body that can be processed in a specific language. Additionally, there are differences in terms of security, speed of communication with the server, and response time to the client.</p><p><strong>Web Services:</strong></p><ul><li>Web Services use XML for encoding and therefore offer higher security.</li><li>In addition to SSL for data transmission, Web Services also provide WSS for enhanced security.</li><li>Web Services are a subset of Web APIs, only offering three styles of use (SOAP, REST, and XML-RPC).</li><li>Web Services require a network connection to function.</li><li>Web Services allow for “One Code different applications,” meaning a single, generic code can be used across various applications.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/681/0*xsq5O4zp52rIiWJm" /></figure><p><strong>Web API:</strong></p><ul><li>The use of JSON (JavaScript Object Notation) in a Web API contributes to its speed advantage.</li><li>Web API is faster than other technologies like XML due to JSON being a lighter weight data format.</li><li>Web API encompasses the functionality of Web Services, including all styles such as JSON-RPC.</li><li>The need for a network connection is not always required for Web API to function.</li><li>The level of interoperability supported by a Web API can vary depending on the specific system or application.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/554/0*2GrY0Fe_qTN-gH6V" /></figure><h3><strong>Key takeaways</strong></h3><p>APIs are an essential part of modern software development, helping easy integration and communication between different applications and systems. REST APIs are the most popular architecture style for web APIs. Endpoints and methods are fundamental concepts in API design, allowing different software programs and applications to access and manipulate specific resources from the servers.</p><p>As demand for interoperability and data exchange is continuously growing, APIs will continue to play a critical role in enabling innovation in businesses and applications development, thus making API testing an absolutely crucial process to ensure that the applications are working as expected. We expand on this in <a href="https://medium.com/cognizantsoftvision-guildhall/the-unsung-hero-of-our-connected-world-a23c159cf7af?source=friends_link&amp;sk=fdc7f046dadaa6f49315e8405d9c5815">part two of this article.</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e69b25053724" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cognizantsoftvision-guildhall/the-unsung-hero-of-our-connected-world-e69b25053724">The Unsung Hero of our Connected World</a> was originally published in <a href="https://medium.com/cognizantsoftvision-guildhall">Cognizant Softvision Insights</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[So Much More Than Bug Hunting: How to Overcome Common QA Challenges]]></title>
            <link>https://medium.com/cognizantsoftvision-guildhall/so-much-more-than-bug-hunting-how-to-overcome-common-qa-challenges-6a1c24675b2f?source=rss----fc208b4204a4---4</link>
            <guid isPermaLink="false">https://medium.com/p/6a1c24675b2f</guid>
            <category><![CDATA[qa]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[qa-testing]]></category>
            <dc:creator><![CDATA[Cognizant]]></dc:creator>
            <pubDate>Thu, 23 Feb 2023 14:27:40 GMT</pubDate>
            <atom:updated>2023-02-23T14:59:38.080Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>By Carmen Făt, Senior QA Engineer, Cognizant Softvision</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jCiB8VLhWJgbLImbp4E8lw.jpeg" /></figure><p>Many people have the wrong opinion when it comes to the work of a QA. Most believe that a QA engineer runs after bugs all day, every day. But is <strong>bug hunting</strong> the only thing that a QA has to do? Let’s shed some light on what a manual Quality Assurance tester really does.</p><p>There are several other tasks a QA engineer performs each day. We also encounter obstacles that block the flow of the testing process, making our work even more interesting.</p><p><strong>I. DOCUMENTATION (Or lack of it)</strong></p><p>The first step to start the testing process is to <strong>study</strong> the available documentation. <em>Mock-ups, PRDs, frameworks, UI//UX,</em> you name it. All of these types of documents are useful in order to understand the product.</p><p>As we all know, documents may contain designs, specifications in regards to the expected behavior of the product in test, and the Acceptance Criteria that needs to be fulfilled before launching the product to the users. There is no doubt that a good <a href="https://medium.com/cognizantsoftvision-guildhall/test-your-assumptions-83b51cf50042?source=friends_link&amp;sk=bd0941273271d0549f3e3c1f86c5a0c2">testing</a> process begins with <strong>good documentation</strong>.</p><p>But what happens if there is no written information about the product? What if most of the documentation is not ready/accessible? Let’s review the following cases and some best practices to handle them:</p><p><strong>a.</strong> <strong><em>Lack of documentation:</em></strong><em> </em>You just found out that a new app is being developed and you will be in charge of testing it. The first thing you do is ask a bunch of questions about the app. Unfortunately, your thrill is gone when you find out that there is no documentation to read, so you won’t get the answers you looked forward to.</p><p><em>What can you do?</em> Ask the Development Engineering or Product Management team about the development progress of the app. You might be lucky enough to get pieces and bits of the app while the development is still ongoing. You’re able to gain a general idea about the product and can start creating basic QA documentation (such as Test Plans). This way you will already be prepared when more details become available and will only have to update the QA documents you previously started writing. This is an important step since involving the QA early in the process can have a significant impact on the project, but it’s often forgotten or undervalued.<em> </em>(Search for the “<strong>Early Testing Principle”</strong> to learn more about the importance of involving QA early in the process).</p><p><strong>b.<em> Outdated documentation:</em></strong> You consider yourself fortunate enough because you got your hands on some documentation. This is until you read it and realize that it is obsolete and the information contained doesn’t correlate with the little information you received when you started working on the project. This can mean only one of two things: either the most recent documentation is placed somewhere else or the existing documents were not updated with the latest decisions.</p><p><em>What can you do?</em> Ask for updated documentation. If this is not possible, there are two paths you can take:</p><ol><li>One way is to <strong>escalate this issue</strong> to upper management (either your team lead, coordinator, project manager, etc). The advantage, in this case, is that you will benefit from your manager’s guidance on any escalation points.</li><li>The other way is to escalate this by yourself and <strong>ask for a meeting</strong> with the Development Engineering and Product Management teams. During this meeting, you can ask questions in order to clarify which of the information should still be used. If major decisions about the product are a work in progress, ask for an ETA.</li></ol><p>Keep in mind that approaching this case varies from one project to another. Thus, before assessing the right course of action, assess the specifics of your project and setup.</p><p><strong>c.</strong><em> </em><strong><em>Restricted documents: </em></strong>The project you are now working on is either top secret or maybe somebody just forgot to give you access rights to the documents. Either way, you are blocked and cannot continue with your work.</p><p><em>What can you do?</em> There is only one way to gain access to the documents you need, and that is by <strong>asking</strong> for them. First, you can ask the others involved in the project, such as your Team Lead or Project Manager. If they can’t help you, reach out to someone from the project who is in a timezone close to you and can provide you the permissions to read the documents. Depending on the project and your team’s communication channels, you can use instant chat apps (such as Slack) or emails to contact the individuals who can grant you access to the documentation.</p><p><strong>II. UNREALISTIC SCHEDULE</strong></p><p>Setting an unrealistic schedule happens more often than you think. There may be countless reasons why production rushes to launch the product to the users, from the engineering availability to financial risks or current events. Even though all the reasons are valid, having a tight deadline doesn’t help you much with the testing process.</p><p><em>What can you do?</em> Since you will need to work on a tight schedule, you won’t be able to go through all the testing phases you would normally go through. Because of this, you will have to take full advantage of the available timeline. This means that prioritization and estimation are important and helpful actions to resort to in these special cases. With testing prioritization, you can plan the testing process by ranking the tasks from mandatory to nice to have. Although it’s a subjective action, proper estimation can help with predicting how much effort (time, money, etc.) is required in order to accomplish the testing tasks. Gather the key people working on the project and perform a risk assessment together. Make sure that you all reach the same outcome; everybody understands the consequences of a rushed launch and has a backup plan if the worst-case scenario happens after launching the product.</p><p><strong>III. DEFECTIVE COMMUNICATION</strong></p><p>Before launching the product to the users, there is a lot of work that has to be done by the teams involved in the project. Each team has a specific scope, but in the end, they all must join forces and work together so that the final product is successful.</p><p>However, there are times when people fail to communicate effectively. Many factors can lead to miscommunication, from cultural differences to lack of context to poor or underdeveloped soft skills, and so on.</p><p><em>What can you do?</em> There are easy ways that can help you improve communication between you and your colleagues. Apply the following strategies:</p><p>1.<strong> Involve yourself as soon as possible in the process.</strong> Ask if there are any meetings where QA could participate, even if there is little to nothing to test at the moment. By attending the meetings, you will be up to date in regards to the decisions and changes that impact the product, so you will be able to also adjust the Testing Plan and keep track of the latest resolutions. Use these meetings to ask questions and note down every little aspect that can be useful for your work. Don’t be afraid to raise concerns if you have any. Involving yourself during the meetings creates <strong>connections </strong>with your colleagues and they will appreciate your interest and engagement.</p><p>2. <strong>Ask the right questions<em>.</em></strong> Try to avoid questions that might receive short answers and ask open questions. <strong>Open questions</strong> usually require long answers. Long answers might provide you with enough information so that you don’t have to come back and ask for more details. Experienced testers can also use their intuition and request information on areas that they already know may raise difficulties, based on their background knowledge.</p><p>Asking the right questions can also help when the people that share and exchange information are located in different time zones. This is especially important because miscommunication, besides causing frustration, can also lead to delaying the work for an entire day.</p><p>3. <strong>Provide constant feedback. </strong>Feedback is a crucial step toward growth and development, so why not use it to improve communication between colleagues? Giving and receiving feedback opens communication between people, but can also backfire if those involved in the project don’t deliver the feedback properly. Make sure your feedback doesn’t come off as accusatory or focused on any one individual. Instead, you can provide value in your feedback by being <strong>specific, issue-focused, and respectful</strong>. You can also provide suggestions for improving the communication between the teams. Try being objective rather than subjective when providing feedback to your colleagues.</p><p>The scenarios above might be helpful if the client is willing to make an effort to improve communication with the team. Unfortunately, there are clients that offer little to no information. Below are a few ways you can handle this difficulty:</p><p>1. Propose a <strong>testing process </strong>if there isn’t one already. If there is one, maybe it’s worth looking through ways of simplifying it. Try reaching an agreement that works for all the parties involved in the project. Keep it simple and focus the process around mandatory tasks.</p><p>2. Ultimately, if the client is not receptive to any of your suggestions to improve communication, you can write down a list of risks that can affect the success of the project. <strong>Explain some common risky scenarios</strong>, such as:</p><ul><li>Being unaware of deadlines is a blocker when it comes to test planning</li><li>Misunderstanding the product can lead to potential escaped bugs</li><li>A poor quality product will impact its success on the market in a negative way</li><li>A product that doesn’t perform as it should will affect the revenue, the number of users will drop, and so forth.</li></ul><p>Being faced with the risks might trigger a positive reaction from the client. But if this becomes too much of a challenge for you, it might be best to escalate this issue to your superiors. If nothing works, there could be bigger issues in regard to these particular clients and it might not be your place to fix them.</p><p><strong>Practice, Grow, and Expect the Unexpected</strong></p><p>There are many challenges a QA has to face and overcome, and the aforementioned are just a few. This is, of course, in addition to the main task, which is signing off on a high-level, quality product.</p><p>Whether the scenarios described are familiar to you or if you’re a beginner in the testing area, it’s always a good idea to expect the unexpected. Sure, being observant and thinking outside the box are two must-have qualities for a good QA, as they are crucial in finding issues of all kinds. However, a professional QA should always be open-minded in order to evaluate how to best respond to unpredictable situations.</p><p>Besides growing on the technical side, QAs should also expand and practice their soft skills. When you are working with various, diverse teams, soft skills become critical. Studying and practicing to improve the way you connect and interact with your colleagues will help you and the teams involved in the project deliver quality products that make the overall business successful.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6a1c24675b2f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cognizantsoftvision-guildhall/so-much-more-than-bug-hunting-how-to-overcome-common-qa-challenges-6a1c24675b2f">So Much More Than Bug Hunting: How to Overcome Common QA Challenges</a> was originally published in <a href="https://medium.com/cognizantsoftvision-guildhall">Cognizant Softvision Insights</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[“Todo” or Not “Todo” — It’s All About Time]]></title>
            <link>https://medium.com/cognizantsoftvision-guildhall/todo-or-not-todo-its-all-about-time-97ce0c8bb851?source=rss----fc208b4204a4---4</link>
            <guid isPermaLink="false">https://medium.com/p/97ce0c8bb851</guid>
            <category><![CDATA[software-engineer]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[enterprise-software]]></category>
            <dc:creator><![CDATA[Cognizant]]></dc:creator>
            <pubDate>Tue, 14 Feb 2023 15:43:51 GMT</pubDate>
            <atom:updated>2023-02-14T15:43:51.083Z</atom:updated>
            <content:encoded><![CDATA[<h3>“Todo” or Not “Todo” — It’s All About Time</h3><p><strong>By Ionut Chichisan, .Net Enterprise Software Engineer, Cognizant Softvision</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0-nLMI0patExcjge54kjLw.jpeg" /></figure><p>CLR, the .Net Runtime. Or ‘time to run,’ quickly if possible.</p><p>In the modern era, people want to have quick and responsive software. They want to spend the least amount of time in front of a computer and do their jobs in the most autonomous way possible. Usually, 10 seconds exceeds the limit users expect to wait for an operation. At the same time, application misbehaviors must be quickly solved by support teams, ensuring quick recovery when incidents arise.</p><p>In a developer’s world, there are general principles that should be followed as much as possible– guidelines that can increase application performance, reduce the risk of incidents/errors, and allow quick resolutions in case of failure. The following is a checklist of principles and recommendations for developers.</p><h4>Assume not null</h4><p>This is one of the most common exceptions/assumptions of all time, resulting in “Object reference not set for an instance of an object” or in the .Net world, <em>NullReferenceException.</em></p><p>An object’s lifetime is dictated by multiple systems in software: the flow interaction (code), the garbage collector, the platform invoke, etc.</p><p>“throw ex”</p><p>This one results in no stack trace &gt; no log specifics. Later debugging scenarios and incidents will be harder to accomplish.</p><h4>“Swallow” exceptions</h4><p>A try/catch without any error handling/logging on the catch block will lose the ability to identify problems later. There would be no logs, no error propagation, nothing to lead to the actual error identification. Too many logs on the other hand will result in spam. Every flow should output just the right amount of information, in order to quickly identify any error along with the most important parameter values.</p><h4>Thread exceptions</h4><p>You cannot catch exceptions outside the thread it was running on. Instead, you can use try/catch in threads or the <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.continuewith?view=net-6.0"><em>ContinueWith</em></a> method and check for errors. The <em>ContinueWith </em>method comes in multiple styles regarding its <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskcontinuationoptions?view=net-6.0"><em>TaskContinuationOptions</em></a><em> </em>flags<em> </em>parameter. One of the parameter values specifies ‘OnlyOnFaulted’, which ensures the continuation is only being executed if the parent thread terminates in an unhandled exception.</p><h4>Loops</h4><p>Loops are the simplest way of losing execution performance of the code, especially if the input enumeration length cannot be managed. What if the enumeration has 1 million records?</p><p>The solution would be to use multithreading with chunks, by splitting the list into smaller chunks that can run in parallel or by making use of <a href="https://dotnettutorials.net/lesson/maximum-degree-of-parallelism-in-csharp/">maximum degree of parallelism</a>.</p><p>There is a catch. Database operations usually are not thread-safe. Entity Framework and other ORMs do not allow the use of their database context in a multithreaded manner. To bypass this, guide the execution flow to collect all the data in a multithread manner, then commit/save the data once, after all threads have completed.</p><p>Another thing about the maximum degree of parallelism is that for optimal performance, the number of threads must be correlated with the number of CPU cores on the server.</p><p>In case of really large enumerations that result in losing precious time. regardless of whether or not you’re using multithreading, publisher/subscriber systems can be considered in order to be able to use multiple servers processing power. Also consider making the loop asynchronous to the user, meaning that a user launches the operation and is being notified later of the status, without directly waiting for the process to complete.</p><h4>Local datetime</h4><p>Never assume the application is going to be used locally, especially client/server ones.</p><p>Use UTC datetime centrally (server side, SQL Server, etc.) — beware the caveats of UTC as well — and convert it to local datetime when displayed to the user (client side). Then it would be easier for debugging and new SQL scripts to accommodate any date/time in your application.</p><p>Because datetime values could be in many places in an application, the code must be consistent about the time zone the dates are using.</p><p>When dealing with web APIs, the API response must output the UTC date (and then converted to the right timezone in JavaScript), while for server-side rendering scenarios (cshtml), the dates must be converted in JavaScript (client side) to the right time zone, after the rendering result is sent to the browser.</p><p>The best way would be to have specific user settings to be able specify the local time zone, with automatic selection based on browser specific APIs. This way the user may work on the default timezone (the browser detected one) or a specific one, if the user is traveling and is being accustomed to a specific timezone (other than the one reported by the browser).</p><p>With the user-specific time zone known, things might be easier in case of working with text/csv files where dates are not automatically converted upon opening. During generation of the file content, the exact time zone may be used.</p><h4>Local number formats</h4><p>Like local date formats, local number formats may be different from user to user.</p><p>A dot instead of a comma might ruin the data integrity for a whole year’s budget for the client company, with unforeseen consequences.</p><p>Keep server side numbers in an invariant culture (with dot as number separator), while on the client side convert everything to local number format. Ensure the process is reversed while pushing the data back to the server.</p><p>Just like time zones, local number formats should be persisted in storage on user settings, in order to be able to generate text/csv files containing numbers.</p><p><strong>Note: </strong>Some countries prefer to install their servers in a different locale that the default one, so be aware that server-side code could be in a specific locale as well.</p><h4>Blocking code/threads</h4><p>Never use Task.Run()/Task.Factory.StartNew() with a <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.wait?view=net-7.0"><em>Wait()</em></a> with no timeout.</p><p>A <em>CancellationTokenSource </em>can also be used with a timeout defined. That way its CancellationToken will automatically be set to canceled after the time has run out. You can also pass a cancellation token to the <em>Wait() </em>method.</p><h4>Notify users too late or not at all</h4><p>According to this <a href="https://blog.prototypr.io/guidelines-for-time-indication-and-progress-bars-in-user-interaction-design-4d5038084c84">article about time perception in human-computer interaction</a>, we could approximate how to interact with the user from a web page or form. Here are some results:</p><p><em>0–2 Seconds = No Indication Needed (generally instantaneous to the user)</em></p><p><em>2–5 Seconds = Busy Animation, Spinner or Spinning Animation</em></p><p><em>5–10 Seconds = Progress Indication Needed, Progress Bar or Visual Indication of Start &amp; Finish (Note: A textual indication of the time remaining is generally recommended in these scenarios.)</em></p><p><em>10+ Seconds = Progress Indication &amp; Cancel Button, User Should Have Ability to Cancel the Process (Note: A textual indication of the time remaining is strongly recommended in these scenarios.)</em></p><h4>Parallel.ForEach loops with async/await</h4><p>The parallel loop doesn’t wait for an async/await code completion; it creates orphaned threads instead. There are also a lot of pitfalls described in <a href="https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/potential-pitfalls-in-data-and-task-parallelism">this article</a>.</p><h3>I/O</h3><h4>Assume source availability</h4><p>Whenever you read from storage, network or any other input devices, it might not always be available. Things like checking for folder existence or bytes received from the network should always be part of initial checking mechanisms before reading actual bytes.</p><h4>Path/Url length</h4><p>Never assume a path will fit an operating system max allowed path length, especially if the path is dynamic. Windows usually supports paths up to 260 characters, while Linux up to 4096.</p><p>Also avoid using special characters in paths.</p><h4>Read past the end of a stream</h4><p>Always check the stream length when peeking portions of a stream.</p><p>Always reset the stream back to 0 when done interacting with it.</p><p>In case the development is being done in the web environment, and if the request content needs to be gathered, remember to reset the stream back to 0 after reading it. That’s because subsequent readings might expect the stream position to be set at the beginning.</p><h4>Read stream contents into memory</h4><p>Never read an entire stream into memory. The most edifying example is trying to copy a large file to other destinations. An out of memory error will be thrown as soon as the memory is not able to handle such a large file.</p><p>A solution is to buffer only parts of the source data and send it to the destination.</p><p>The tricky part is to implement it in a web environment, for example uploading large files. There are countless client-side libraries that can upload a file using chunking, but the idea is not to store the whole file in memory (server side), but to redirect those file parts (bytes) to the destination storage.</p><h4>Different speeds, chained read/writes</h4><p>When you have some raw processing of stream bytes gathered from an arbitrary source, plan to use buffers to accommodate the difference in the reading/processing speeds.</p><h4>Ignore logs</h4><p>There is a fine line between an informative log and a spamming one. Too few messages become hard to follow, while too many messages could easily become spam.</p><p>Group messages by a common identifier, “Correlation Id,” that should indicate messages coming from the same processing flow, for a specific user.</p><p>Give log messages enough information like date/time occurred, process id, user id, thread id, exception details (message and stack trace) to ensure less problematic fixing of issues later on. Include any major parameters that could save you from losing hours of code digging.</p><p>Make clear differences about log levels in order to control how many messages should be in the logs. Log more frequently occurring messages as debug level and enable log debug levels only when strictly necessary.</p><h4>Make threads cancelable</h4><p>Threads could pile up very quickly and if left unchecked, could decrease performance considerably.</p><p>Define timeouts whenever possible and cancel any operation that is lasting more than expected.</p><p>.Net has also a possibility to combine timeouts (cancellation tokens) and continue with a new token that will timeout as soon as one of the combined tokens times out.</p><p>Beware of timeout ordering: a timeout for a database operation cannot be set longer than the web request timeout the database call is being used in, otherwise the database timeout won’t be effective.</p><p>Have a centralized location to define timeouts for every aspect of your application.</p><h4>Retry specific operations</h4><p>Some operations (like database read/writes, API requests) have transient errors due to unavoidable factors (ex: network failures). Always plan to retry these operations, before marking the operation as failed.</p><p>The default retry strategies could be linear or using exponential backoff. The idea is to retry at the time the operation will most probable succeed.</p><p>You can also customize the retry interval by providing specific checks, in order to determine the retry is still feasible for success.</p><p>In .Net there is a comprehensive library that can handle retry operations called <a href="https://github.com/App-vNext/Polly">Polly</a>. It also provides other resiliencies like:</p><ul><li>Circuit breaker — ability to stop an operation if it can’t be handled by the system anymore; useful in preventing DDoS attacks as well as allowing the system to cool off</li><li>Timeout — provide timeout where the existing code does not permit it</li><li>Bulkhead Isolation — independent resiliency of different application elements</li><li>Rate-limiting — slows down an operation so the system could cope</li><li>Fallback — alternatives to the main flow in case it fails</li></ul><h4>Database queries</h4><p>Retrieving data from a database is one of the most underestimated operations in an application when it comes to performance. Because it became fairly easy to work with databases, the questions about query performance, number of database round-trips as well as database indexes are often ignored.</p><p>When working with millions of records in different tables, make sure proper database design has been considered from the beginning (indexes, table partitioning, normalization/denormalization of data), even proper database server.</p><p>Redesigning a database from scratch after the application has gone live is a procedure that almost no one wants to happen.</p><p>Data maintenance is another aspect that is worth mentioning. As time goes on and the data is accumulating, different indexing strategies must be considered. Azure provides this as <a href="https://learn.microsoft.com/en-us/azure/azure-sql/database/automatic-tuning-overview?view=azuresql">automated tuning</a>, a service that does index management automatically based on query history.</p><h4>Last but not least: Pyramidal thinking</h4><p>Think of the project as a pyramid. The very base of the pyramid constitutes the environment, hardware and software the application is going to run on.</p><p>It could be the most genius application ever, but if the environment won’t support it, all bets are off.</p><p>You must ensure the optimal processing power: CPU, memory, network bandwidth, and disk speed are just some of the parameters you should ask about.</p><p>Then comes the database. Because the database usually constitutes the “Single Point Of Truth (SPOT)” when it comes to data, you must ensure the server can handle enough concurrent connections to satisfy the application needs.</p><p>Usually, database calls are expensive in terms of performance. To overcome that, you must introduce at least some level of caching to keep the data into memory instead of reading it from the database. However, in order to ensure you have the most recent data when working with cache, you should proceed with at least one of the following:</p><ul><li>Cache static tables data, that won’t get changed at all or at least not very often</li><li>Have ORMs implement multiple levels of caching. This ensures caches are invalidated as soon as write operations are performed against the database.</li></ul><p>Every piece of software out there was designed to perform a specific operation. People tire of waiting quickly, and the slow software application gets scrapped. With a few precautions, serious software incidents and data loss can be easily avoided.</p><h4>References:</h4><p><a href="https://learn.microsoft.com/en-us/windows/win32/win7appqual/preventing-hangs-in-windows-applications">https://learn.microsoft.com/en-us/windows/win32/win7appqual/preventing-hangs-in-windows-applications</a></p><p><a href="https://www.zdnet.com/article/the-escape-button-a-key-to-the-psychology-of-device-design/">https://www.zdnet.com/article/the-escape-button-a-key-to-the-psychology-of-device-design/</a></p><p><a href="https://blog.prototypr.io/guidelines-for-time-indication-and-progress-bars-in-user-interaction-design-4d5038084c84">https://blog.prototypr.io/guidelines-for-time-indication-and-progress-bars-in-user-interaction-design-4d5038084c84</a></p><p><a href="https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/potential-pitfalls-in-data-and-task-parallelism">https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/potential-pitfalls-in-data-and-task-parallelism</a></p><p><a href="https://github.com/App-vNext/Polly">https://github.com/App-vNext/Polly</a></p><p><a href="https://dotnettutorials.net/lesson/maximum-degree-of-parallelism-in-csharp/">https://dotnettutorials.net/lesson/maximum-degree-of-parallelism-in-csharp/</a></p><p><a href="https://learn.microsoft.com/en-us/azure/azure-sql/database/automatic-tuning-overview?view=azuresql">https://learn.microsoft.com/en-us/azure/azure-sql/database/automatic-tuning-overview?view=azuresql</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=97ce0c8bb851" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cognizantsoftvision-guildhall/todo-or-not-todo-its-all-about-time-97ce0c8bb851">“Todo” or Not “Todo” — It’s All About Time</a> was originally published in <a href="https://medium.com/cognizantsoftvision-guildhall">Cognizant Softvision Insights</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>