Wednesday, 4 February 2015

Gmail like outlook

We migrated from Outlook to Gmail here at work recently. I love the flat design of Gmail, but I also love the Outlook preview panel on the right when you click on the emails.
So, after a bit of research (and the help of a colleague, thanks Gordon!), I found what I was looking for :



Steps :

  1. On the left panel of your Gmail, where you have the list of your labels,  click on the more link.
  2.  Now click on Manage Labels link.
  3. Here click on the Labs tab.
  4. In the "Search for a lab:" enter  preview pane .
  5. Click on Enable option.
  6. Gmail will reload.
  7. On the top right of the screen there will be a new a drop down menu :
  8. Choose Vertical Split.
  9. Thank me later.

Monday, 2 February 2015

SimpleReact : Simple Functional Reactive Programming for Java 8

We (the very productive and small team I work with here in Aol) have just released a very lightweight functional reactive programming library for Java 8. It builds entirely on pre-existing JDK 8 libraries (so functional interfaces, Streams, CompletableFuture) and makes it very easy to create asynchronous reactive dataflows.

Getting started

Getting started is as simple as setting up a basic Reactive flow such as the following and evolving from there -
 List<String> strings = new SimpleReact()
            .<Integer> react(() -> 1, () -> 2, () -> 3)
            .then(it -> it * 100)
            .then(it -> "*" + it)
            .block();

This will result in a list, that looks something like this :
 ["*100","*200","*300"]

Although not necessarily in that order. All the work will be done asynchronously, and the block() method blocks the current thread until all the work is complete (& blocking the current thread is optional). See more examples on the SimpleReact wiki .

Adding SimpleReact as a dependency


SimpleReact is available on Maven Central.

Gradle


compile group: 'com.aol.simplereact', name:'simple-react', version:'0.1'

Gradle


<dependency>
 <groupId>com.aol.simplereact</groupId>
  <artifactId>simple-react</artifactId>
  <version>0.1</version>
  <scope>compile</scope>
</dependency>
 

Friday, 3 October 2014

Java 8 it's easy : Higher-order Function

higher-order what?

Higher-order means that it is possible to pass to a method both values and functions and in the same way the method itself can return either a value or a function.

Example:
   •    public void doSomething(String name, Function someFunction){...}


   •    public Function createAnAction(Integer someInteger)

EASY!!!!


Use case 1:

Print a message with weight information in kilos. 

This is easy : 

package com.marco.higherOrder;
public class Printer {

        public void print(int weight) {
                System.out.println("Printing : your weight is " + weight + " kilos");
        }

        public static void main(String[] args) {
                Printer printer = new Printer();
                printer.print(65);

        }
}

Use case 2:

I need to be able to print different weight unit like stone and pounds.




Ok, just put an if and shut up!!

Putting an if it means to add and pass a boolean and then check that boolean and put a boring if/else.

Also what about open close principle? what if we need to add yet another weight unit?



Higher-order Function to the rescue:

I want a class in charge of handling different weight units :


package com.marco.higherOrder;
public class Scale {

        public String toStones(int weight) {
                return "your weight is " + weight + " stones";
        }

        public String toKilos(int weight) {
                return "the weight is " + weight + " kilos";
        }

        public String toPounds(int weight) {
                return "the weight is " + weight + " pounds";
        }
}

Then I can add a Function in my Printer.print method and pass functions:


package com.marco.higherOrder;
import java.util.function.Function;
public class Printer {

        public void print(int weight, Function<Integer, String> scale) {
                System.out.println("Printing : " + scale.apply(weight));
        }

        public static void main(String[] args) {
                Printer sender = new Printer();
                Scale scale = new Scale();

                sender.print(65, scale::toKilos);

                sender.print(65, scale::toStones);

                sender.print(65, scale::toPounds);

        }
}

Function<Integer, String> means that this function will accept an Integer and will return a String.

 scale::toKilos means that the method toKilos of the scale instance will be called.
EASY!!!!

What if I don't need the Scale class?

Then don't don't it :)!!!


package com.marco.higherOrder;
import java.util.function.Function;
public class Printer {

        public void print(int weight, Function<Integer, String> scale) {
                System.out.println("Printing : " + scale.apply(weight));
        }

        public static void main(String[] args) {
                Printer sender = new Printer();

                sender.print(65, p -> "your weight is " + p + " kilos");

                sender.print(65, p -> "your weight is " + p + " stones");

                sender.print(65, p -> "your weight is " + p + " pounds");

        }
}
p -> "your weight is " + p + " kilos" the p is simply the int that will be passed to the method.





Functional it’s easy , don’t trust who says it’s hard!


Have a great weekend


Ciao.

Monday, 29 September 2014

Java 8 : Null? no thanks!

You know, I know, they know, everybody knows, returning null from a public method is often a bad practice.
Reasons are multiple, from the risk of raising NullPointerException in runtime to the horrible == null check in your code.

To avoid returning nulls in Java 8 you can use java.util.Optional (if you are on previous version of Java, Guava has similar functionality).

package com.marco;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public class NoNullsThanks {

        private final Map<String, Integer> nameAge = new HashMap<String, Integer>();

        public Integer getAge(String name) {
                return Optional.ofNullable(nameAge.get(name)).orElse(-1);
        }

        private final Map<String, List<String>> nameEmails = new HashMap<String, List<String>>();

        public List<String> getEmails(String name) {
                return Optional.ofNullable(nameEmails.get(name)).orElse(new ArrayList<String>());
        }
}


Nice & Clean :)

Friday, 19 September 2014

Tridimensional developers

Working in the industry for a while, I noticed different behaviors between developers.

These differences are mostly related to their personalities, their team spirit and finally their entrepreneurship skills.

I identified 3 types or better 3 dimensions in which I can fit all the people I work and worked with.
Before starting and describing these dimensions, I just want to point out couple of important things.
  1. This has nothing to do with how good you are with the code or design or testing. You can be the best kickass-bruce-lee-coder, but still entering in the mono-dimensional category.
  2. This has also nothing to do with your level of seniority, I saw Juniors that can perfectly fit in the tridimensional category and team leaders falling in the mono-dimensional one. 
  3. This is perfectly applicable to ANY workplace and ANY type of job and ANY industry.
  4. It is just my point of view in a boring Friday afternoon.
So lets start :)

Mono-Dimensional Developer

You work daily at your stories/tasks

You participate to meetings about process and technologies

You communicate with other team members about status
updates, risks and issues encountered

You create and/or maintain software applications 

You keep updated yourself about emerging technologies and trends











Bidimensional Developer 

You cover the Mono-dimensional points

You help team members without being asked directly

You share with your team what you learned using slides/blogs/etc.

You actively participate to process and technology meetings, asking questions and/or proposing solutions.





Tridimensional Developer

You cover the Bidimensional points

You create, propose and promote new processes and technologies

You take team building actions when needed without being asked directly

You actively participate to meetings other than process and technology

You create blogs/wikis/etc in order to facilitate communication without being asked directly

You see opportunities everywhere and you act on them.



So which developer are you?




Friday, 12 September 2014

Friday-Benchmarking Functional Java

Lets image your product owner goes crazy one day and he asks you to do the following :

From a set of Strings as follows :

"marco_8", "john_33", "marco_1", "john_33", "thomas_5", "john_33", "marco_4", ....

give me back a comma separated String with only the marco's numbers and numbers need to be in order. 

 Example of expected result :

"1,4,8"


I will implement this logic in 4 distinct ways and I will micro benchmark each one of them. The ways I'm going to implement the logic are :

  • Traditional java with loops and all.
  • Functional with Guava 
  • Functional with java 8 stream
  • Functional with java 8 parallelStream

Code is below or in gist


package com.marco.brownbag.functional;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.google.common.collect.Ordering;
public class MicroBenchMarkFunctional {

        private static final int totStrings = 200000;

        public static void main(String[] args) {

                Set<String> someNames = new HashSet<String>();

                init(someNames);

                for (int i = 1; i < totStrings; i++) {
                        someNames.add("marco_" + i);
                        someNames.add("someone_else_" + i);
                }

                System.out.println("start");

                run(someNames);

        }

        private static void run(Set<String> someNames) {
                System.out.println("========================");
                long start = System.nanoTime();
                int totalLoops = 20;
                for (int i = 1; i < totalLoops; i++) {
                        classic(someNames);
                }
                System.out.println("Classic         : " + ((System.nanoTime() - start)) / totalLoops);

                start = System.nanoTime();
                for (int i = 1; i < totalLoops; i++) {
                        guava(someNames);
                }
                System.out.println("Guava           : " + ((System.nanoTime() - start)) / totalLoops);

                start = System.nanoTime();
                for (int i = 1; i < totalLoops; i++) {
                        stream(someNames);
                }
                System.out.println("Stream          : " + ((System.nanoTime() - start)) / totalLoops);

                start = System.nanoTime();
                for (int i = 1; i < totalLoops; i++) {
                        parallelStream(someNames);
                }
                System.out.println("Parallel Stream : " + ((System.nanoTime() - start)) / totalLoops);

                System.out.println("========================");
        }

        private static void init(Set<String> someNames) {
                someNames.add("marco_1");
                classic(someNames);
                guava(someNames);
                stream(someNames);
                parallelStream(someNames);
                someNames.clear();
        }

        private static String stream(Set<String> someNames) {
                return someNames.stream().filter(element -> element.startsWith("m")).map(element -> element.replaceAll("marco_", "")).sorted()
                                .collect(Collectors.joining(","));
        }

        private static String parallelStream(Set<String> someNames) {
                return someNames.parallelStream().filter(element -> element.startsWith("m")).map(element -> element.replaceAll("marco_", "")).sorted()
                                .collect(Collectors.joining(","));
        }

        private static String guava(Set<String> someNames) {
                return Joiner.on(',').join(
                                Ordering.from(String.CASE_INSENSITIVE_ORDER).immutableSortedCopy(
                                                Collections2.transform(Collections2.filter(someNames, Predicates.containsPattern("marco")), REPLACE_MARCO)));

        }

        private static Function<String, String> REPLACE_MARCO = new Function<String, String>() {
                @Override
                public String apply(final String element) {
                        return element.replaceAll("marco_", "");
                }
        };

        private static String classic(Set<String> someNames) {

                List<String> namesWithM = new ArrayList<String>();

                for (String element : someNames) {
                        if (element.startsWith("m")) {
                                namesWithM.add(element.replaceAll("marco_", ""));
                        }
                }

                Collections.sort(namesWithM);

                StringBuilder commaSeparetedString = new StringBuilder();

                Iterator<String> namesWithMIterator = namesWithM.iterator();
                while (namesWithMIterator.hasNext()) {
                        commaSeparetedString.append(namesWithMIterator.next());
                        if (namesWithMIterator.hasNext()) {
                                commaSeparetedString.append(",");
                        }

                }

                return commaSeparetedString.toString();

        }
}


Two points before we dig into performance :

  1. Forget about the init() method, that one is just to initialize objects in the jvm otherwise numbers are just crazy.
  2. The java 8 functional style looks nicer and cleaner than guava and than developing in a traditional way :).

Performance:



Running that program on my mac with 4 cores, the result is the following :


========================
Classic              : 151941400
Guava               : 238798150
Stream              : 151853850
Parallel Stream : 55724700
========================

Parallel Stream is 3 times faster. This is because java will split the job in multiple tasks (total of tasks depends on your machine, cores, etc) and will run them in parallel, aggregating the result at the end.
Classic Java and java 8 stream have more or less the same performance.
Guava is the looser.


That is amazing, so someone could think:
"cool, I can just always use parallelStream and I will have big bonus at the end of the year". 
But life is never easy. Here is what happens when you reduce that Set of strings from 200.000 to 20

========================
Classic              : 36950
Guava               : 69650
Stream              : 29850
Parallel Stream : 143350
========================

Parallel Stream became damn slow. This because parallelStream has a big overhead in terms of initializing and managing multitasking and assembling back the results.
Java 8 stream looks now the winner compare to the other 2.

Ok, at this point, someone could say something like :
"for collections with lots of elements I use parallelStream, otherwise I use stream"
That would be nice and simple to get, but what happens when I reduce that Set again from 20 to 2?
This :

========================
Classic              : 8500
Guava               : 20050
Stream              : 24700
Parallel Stream : 67850
========================

Classic java loops are faster with very few elements.

So at this point I can go back to my crazy product owner and ask how many Strings he thinks to have in that input collection. 20? less? more? much more?


Like the Carpenter says :

Measure Twice, Cut Once!!

 

 







Monday, 8 September 2014

Migrate your project from SVN to Git Stash in few steps

Step by step guide on how to migrate your SVN repository with all its history to the Stash, the Atlassian git manager.


Only once :

  1. add the ssh key
  2. open a terminal 
  3. create the authors.txt file in ~/Documents/ 
  4. git config svn.authorsfile ~/Documents/authors.txt 

authors.txt format :

username = Name LastName <email>

example :

gordof = Gordon Flash <gordon.flash@superhero.com>
marcoc = Marco Castigliego <marco.castigliego@superhero.com>



For each project :

For this example I will migrate a project called super-hero-service.

  1. Tell your team members to not commit on the project during the process.
  2. Open a terminal
  3. cd ~
  4. mkdir migration
  5. cd migration
  6. git svn clone svn+ssh://marcoc@svn.superhero.com/com/super/hero/Services/ --trunk=super-hero-service super-hero-service
  7. go to take a coffee
  8. cd super-hero-service
  9. git svn show-ignore (Which outputs everything in the SVN ignore property to the console. Then you can copy this to a new file called .gitignore at the root of your repository.Add and commit the file.)
  10. go to https://stash.superhero.com/projectsServices and create a repository called super-hero-service
  11. git remote add origin ssh://git@stash.suoperhero.com:2022/services/super-hero-service.git
  12. git push -u origin master