Friday, January 31, 2020

Reduce Excessive Nesting



https://www.veracode.com/blog/secure-development/avoiding-nested-try-catch-java
Extracting the nested part as a new method will always work for any arbitrarily nested Try-Catch-Finally block. So this is one trick that you can always use to improve the code.

return early
https://www.codeproject.com/Articles/626403/How-and-Why-to-Avoid-Excessive-Nesting

Replace Nested Conditional with Guard Clauses
https://refactoring.guru/replace-nested-conditional-with-guard-clauses

Isolate all guard clauses that lead to calling an exception or immediate return of a value from the method. Place these conditions at the beginning of the method.

After rearrangement is complete and all tests are successfully completed, see whether you can use Consolidate Conditional Expression for guard clauses that lead to the same exceptions or returned values.


https://testing.googleblog.com/2017/06/code-health-reduce-nesting-reduce.html
The refactoring technique shown above is known as guard clauses. A guard clause checks a criterion and fails fast if it is not met. It decouples the computational logic from the error logic. By removing the cognitive gap between error checking and handling, it frees up mental processing power. As a result, the refactored version is much easier to read and maintain.

Here are some rules of thumb for reducing nesting in your code:

  • Keep conditional blocks short. It increases readability by keeping things local.
  • Consider refactoring when your loops and branches are more than 2 levels deep.
  • Think about moving nested logic into separate functions. For example, if you need to loop through a list of objects that each contain a list (such as a protocol buffer with repeated fields), you can define a function to process each object instead of using a double nested loop.
https://www.drdobbs.com/architecture-and-design/refactoring-deeply-nested-code/231500074
https://dzone.com/articles/code-smells-deeply-nested-code
    public MappedField getMappedField(final String storedName) {
        for (final MappedField mf : persistenceFields) {
            for (final String n : mf.getLoadNames()) {
                if (storedName.equals(n)) {
                    return mf;
                }
            }
        }
        return null;
    }


This what the Law of Demeter warns us against, therefore suggests to me we consider a tell-don’t-ask approach.  Wouldn’t it be prettier to ask mappedField if one of its names matched the name we wanted?
    public Optional<MappedField> getMappedField(final String storedName) {
        return persistenceFields.stream()
                                .filter(mf -> mf.hasName(storedName))
                                .findFirst();
    }
Symptoms:
  • Deeply nested code, usually loops and/or conditionals
  • Chained method calls that are all getters (or other non-builder, non-DSL method chains).
Possible solutions:
  • Consider tell, don’t ask. Where the code previously grabbed internal data and did checks against it, move those checks into the object containing the data and create a method with a useful name to help other objects answer their questions.
  • Examine your encapsulation. Does the data really need to leak out into other classes? Should data and/or responsibilities be relocated so that operations on the data are moved closer to the data itself?
  • Collection Encapsulation. Sometimes this pattern is a sign that you’re using a data structure as a domain object.  Consider encapsulating this data structure (Collection, array, etc) inside a domain object of its own and adding helper methods to let other objects ask it questions rather than poke around its internals.


    public Optional<MappedField> getMappedField(final String storedName) {
        return persistenceFields.stream()
                                .filter(mf -> mf.hasName(storedName))
                                .findFirst();
    }



Refactoring with Cognitive Complexity
https://resources.sei.cmu.edu/asset_files/Presentation/2017_017_001_497517.pdf

Control flow statements "if", "for", "while", "switch" and "try" should not be nested too deeply
https://rules.sonarsource.com/java/RSPEC-134

Thursday, January 30, 2020

Java Collection Tips



https://stackoverflow.com/questions/51872623/why-guava-standardtable-put-method-refuse-null-value
null in general seen as key or value in any Collection or Map is seen as a bad decision. The jdk itself has some examples, ConcurrentHashMap does not allow null keys or values, so does ConcurrentSkipListMap and many others.
So does static factory methods added in java-9, like Map::of. Even HashMap that does allow a null key and value, so these would both not fail:
HashMap<String, String> map = new HashMap<>();
map.put("", null);
map.put(null, "");
Using any of the new java-8 method of a HashMap will throw a NullPointerException:
 // value trying to be null
 chm.merge("", null, (k, v) -> k);
And the last point is that all guava Collections are not null-tolerant, which to me is great decision.
https://www.techiedelight.com/remove-null-values-map-java/

https://stackoverflow.com/questions/45210398/why-does-map-of-not-allow-null-keys-and-values
As others pointed out, the Map contract allows rejecting nulls...
[S]ome implementations prohibit null keys and values [...]. Attempting to insert an ineligible key or value throws an unchecked exception, typically NullPointerException or ClassCastException.
... and the collection factories (not just on maps) make use of that.
They disallow null keys and values. Attempts to create them with null keys or values result in NullPointerException.

But why?

Allowing null in collections is by now seen as a design error. This has a variety of reasons. A good one is usability, where the most prominent trouble maker is Map::get. If it returns null, it is unclear whether the key is missing or the value was null. Generally speaking, collections that are guaranteed null free are easier to use. Implementation-wise, they also require less special casing, making the code easier to maintain and more performant.
You can listen to Stuart Marks explain it in this talk but JEP 269 (the one that introduced the factory methods) summarizes it as well:
Null elements, keys, and values will be disallowed. (No recently introduced collections have supported nulls.) In addition, prohibiting nulls offers opportunities for a more compact internal representation, faster access, and fewer special cases.
Since HashMap was already out in the wild when this was slowly discovered, it was too late to change it without breaking existing code but most recent implementations of those interfaces (e.g. ConcurrentHashMap) do not allow null anymore and the new collections for the factory methods are no exception.
(I thought another reason was that explicitly using null values was seen as a likely implementation error but I got that wrong. That was about to duplicate keys, which are illegal as well.)
So disallowing null had some technical reason but it was also done to improve the robustness of the code using the created collections.



Wednesday, January 29, 2020

Java Core Tips



https://crunchify.com/how-to-iterate-through-java-list-4-way-to-iterate-through-loop/
There are 5 ways you can iterate through List.
For Loop
Advanced For Loop
Iterator
While Loop
Collections’s stream() util (Java8)


https://docs.oracle.com/javase/8/docs/technotes/guides/language/foreach.html
Here is a common mistake people make when they are trying to do nested iteration over two collections:
List suits = ...;
List ranks = ...;
List sortedDeck = new ArrayList();

// BROKEN - throws NoSuchElementException!
for (Iterator i = suits.iterator(); i.hasNext(); )
    for (Iterator j = ranks.iterator(); j.hasNext(); )
        sortedDeck.add(new Card(i.next(), j.next()));
Can you spot the bug? Don't feel bad if you can't. Many expert programmers have made this mistake at one time or another. The problem is that the next method is being called too many times on the "outer" collection (suits). It is being called in the inner loop for both the outer and inner collections, which is wrong. In order to fix it, you have to add a variable in the scope of the outer loop to hold the suit:
// Fixed, though a bit ugly
for (Iterator i = suits.iterator(); i.hasNext(); ) {
    Suit suit = (Suit) i.next();
    for (Iterator j = ranks.iterator(); j.hasNext(); )
        sortedDeck.add(new Card(suit, j.next()));

Tuesday, January 28, 2020

Java Enum Tips



Java: Check if enum contains a given string?
https://stackoverflow.com/questions/4936819/java-check-if-enum-contains-a-given-string/4936895

Guavas Enums could be your friend

    if (!Enums.getIfPresent(MyData.class, "THREE").isPresent()) {


https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/enum?redirectedfrom=MSDN
DO name flag enums with plural nouns or noun phrases and simple enums with singular nouns or noun phrases.
Do use a singular type name for an enumeration, unless its values are bit fields.
public enum ConsoleColor {
  Black,
  Blue,
  Cyan,
  ...
Do use a plural type name for an enumeration with bit fields as values, also called a flags enum.
[Flags]
public enum ConsoleModifiers {
  Alt,
  Control,
  Shift
}


Monday, January 27, 2020

Guide to Google Spanner



You'll want to implicitly unnest your array element. As an example

SELECT id, name, description
FROM articles as a, a.tags as single_tag
WHERE lang = "your lang value"
      AND single_tag = "your tag value"

First, I implicitly unnested the array column tags to the column single_tag.

Second, I changed your where clause to an equality against the new single_tag column

Note: If multiple values in tags match your criteria, you can have the same row returned multiple times. You can address this by adding in a DISTINCT clause as long as none of the columns you are returning are arrays or structs. For example:

SELECT DISTINCT id, name, description
FROM articles as a, a.tags as single_tag
WHERE lang = "your lang value"
      AND single_tag = "your tag value"


https://cloud.google.com/spanner/docs/getting-started/java/
https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/spanner/cloud-client/src/main/java/com/example/spanner/SpannerSample.java

https://www.nextplatform.com/2017/02/15/googles-spanner-database-wont-well-clone/
Google luminary Eric Brewer, who is vice president of infrastructure at Google and who helped create many of the data services at the search engine giant, coined the CAP Theorem back in 1998 and the ideas were developed by the database community in the following years. The gist of CAP Theorem is that all distributed databases have to worry about three things – consistency, availability, and partition tolerance – and no matter what you do, you can only have no more than two of these properties being fully implemented at any time in the datastore or database

With Spanner, after a decade of work, Google has been able to achieve this. (You can read all about Spanner in the paper that Google release back in October 2012.) Part of the reason why Google can do this is because it has developed a sophisticated timestamping scheme for the globally distributed parts of Spanner that creates a kind of universal and internally consistent time that is synchronized by Google’s own network and is not dependent on outside services like the Network Time Protocol (NTP) that is used by servers to keep relatively in synch. Google needed a finer-grained control of timestamping with Spanner, so it came up with a scheme based on atomic clocks and GPS receivers in its datacenters that could provide a kind of superclock that spanned all of its datacenters, ordering transactions across the distributed systems. This feature, called TrueTime by Google, is neat, but the real thing that makes Google’s Spanner work at the speed and scale that it does is the internal Google network that lashes those datacenters to the same heartbeat of time as it passes.



Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts