How to win a senior programmer job interview

This post will give you 3 advices that will help you to win any job interview for a senior programmer position. It does not matter that you can’t program when asked during the interview, just follow these simple advices and you are one step closer to being a rockstar software developer earning big bucks!

Advice 1: Learn the Fizzbuzz answer

Most interviewers ask the same question to measure programming skills: program Fizzbuzz. It is a very popular, but extremely tricky assignment that even the most skilled programmers fail at. Just learn the code in the required language by hearth and you will fool any interviewer. Note that you really don’t have to understand the code as the explanation of what the code does is given in the assignment.

Java implementation (Fizzbuzz)

public class FizzBuzz {
	public static void main(String[] args) {
		for (int i = 1; i <= 100; i++) {
			if (i % 15 == 0) {
				System.out.println("FizzBuzz");
			} else if (i % 3 == 0) {
				System.out.println("Fizz");
			} else if (i % 5 == 0) {
				System.out.println("Buzz");
			} else {
				System.out.println(i);
			}
		}
	}
}

PHP implementation (Fizzbuzz)

<?php
for ($i = 1; $i <= 100; $i++)
{
    if (!($i % 15))
        echo "FizzBuzz\n";
    elseif (!($i % 3))
        echo "Fizz\n";
    elseif (!($i % 5))
        echo "Buzz\n";
    else
        echo "$i\n";
}

Python implementation (Fizzbuzz)

for i in xrange(1, 101):
    if i % 15 == 0:
        print "FizzBuzz"
    elif i % 3 == 0:
        print "Fizz"
    elif i % 5 == 0:
        print "Buzz"
    else:
        print i

C implementation (Fizzbuzz)

#include <stdio.h>

int main (void)
{
    int i;
    for (i = 1; i <= 100; i++)
    {
        if (!(i % 15))
            printf ("FizzBuzz");
        else if (!(i % 3))
            printf ("Fizz");
        else if (!(i % 5))
            printf ("Buzz");
        else
            printf ("%d", i);

        printf("\n");
    }
    return 0;
}

Advice 2: Learn the “100 to 1” answer

A very smart interviewer has come up with an alternative to the popular FizzBuzz assignment called “100 to 1“. Probably because the FizzBuzz answers got really easy to Google. The assignment is to print a count down from 100 to 1 using a “for” loop that has a loop variable “i” that starts at 0. This blog has gotten exclusive access to the secret answers to this very hard and brand new assignment. Use them in your benefit!

Java implementation (100 to 1)

public class HundredToOne {
	public static void main(String[] args) {
		for (int i = 0; i < 100; i++) {
			System.out.println(100-i);
		}
	}
}

PHP implementation (100 to 1)

<?php
for ($i = 0; $i < 100; $i++)
{
    echo (100-$i)."\n";
}

Python implementation (100 to 1)

for i in xrange(0, 100):
    print 100-i

C implementation (100 to 1)

#include <stdio.h>

int main (void)
{
    int i;
    for (i = 0; i < 100; i++)
    {
        printf ("%d\n", 100-i);
    }
    return 0;
}

Advice 3: Failure defense and contract extension

If you make a mistake, then don’t worry. Claim it is due to test anxiety. Another great defense is that you could not solve it, because you rely heavily on your favorite IDE. If that does not work, then you can say that the assignment seemed so trivial to you that you could not believe it was the actual assignment and you were looking for the hidden “difficulty”. One of these will work every time, guaranteed!

Some people have commented that they are worried about being outed as an impostor as soon as they won the job. Don’t be! By the time you are “up to speed” you are already earning big bucks for a few months and you have passed your trial period. Also, by posing humble, showing your effort and indicating that you are having trouble “adapting to the working environment” or “finding your spot in the team” you can probably achieve to win a contract extension.

Conclusion

It is important to realize that you can become good at winning a senior programmer job and also that being a great programmer is not always the easiest way to win it. Be aware that there may be some luck involved as not every interviewer asks the right questions (the ones above) or is sensible enough to buy your defenses (if you even need these). Don’t be discouraged if you do not succeed at once. There are enough companies eager to hire senior programmers, so you can have many chances as they interview anyone who sends them an impressive CV.

Let me know if it worked for you! Or maybe don’t… as I would become really depressed if it did (as this is a satirical post). 😉

Share

How to test Apache CloudStack 4.2 on your local machine

LeaseWeb released its Private Cloud powered by Apache CloudStack two months ago [1]. Apache CloudStack [2] is an open source software platform that pools computing resources to build public, private, and hybrid Infrastructure as a Service (IaaS) clouds.

In this post, I will give a short introduction of Apache CloudStack and introduce an easy way to test Apache CloudStack 4.2 on our local machine using DevCloud.

Apache CloudStack manages the network, storage, and compute nodes that make up a cloud infrastructure. Apache CloudStack provides a first-class user interface (UI), a command line tool named CloudMonkey [3], and a full-featured RESTful API. Apache CloudStack currently supports the most popular hypervisors: VMware, KVM, XenServer and Xen Cloud Platform (XCP).

For now, the latest stable version of Apache CloudStack is 4.2.0. However, if you want to change and test your change in Apache CloudStack, or test the new features of CloudStack, you can check out the Apache CloudStack source code, build RPM/DEB packages, and install them on servers. However, Apache CloudStack also provides an easier way for testing.

DevCloud [4] is a virtual appliance shipped as an OVA image which runs on VirtualBox (an opensource type-2 or desktop hypervisor) and can be used for CloudStack’s development and testing. An NFS server is already configured in DevCloud, the System VM Template for Apache CloudStack 4.0/4.1 and a ttylinux virtual machine template are already installed on it. Moreover, Xen hypervisor and Xen Cloud Platform (XCP) are already installed in DevCloud, so virtual machines can be deployed in it.

Now we can test Apache Cloudstack on our local machines using DevCloud:

1. Preparation

(1)  Install VirtualBox

(2) Create a “host-only” network in VirtualBox if not exists. Set the IPv4 to 192.168.56.1

devcloud-11

(3) It is recommended that we install a Linux (such as CentOS, Ubuntu) virtual machine in VirtualBox as the working VM (WORK-VM) at first. There are two network adaptor attached to the VM (on is attached to NAT , another one is attached to the Host-Only Adaptor created in Step 2). Suppose it has a IP 192.168.56.2 .

Make sure the following programs have been installed: mysql-server, Python, Python-Dev (python-devel), mysql-connector-java, Java, tomcat6, python-paramiko, nfs-utils, Jsvc, maven, mysql-connector-python (pip install), requests (pip install)

(4) Get DevCloud2 [5] and import it to VirtualBox. Please do NOT select “re-initialize the MAC address of all network cards”. Make sure ‘Enable PAE/NX’ mode under VM settings -> System -> Processor Tab is checked. Change the network setting like Step 3. The network configuration should like this:
devcloud-12

2. Management server installation from CloudStack source codes

(5) Checkout Apache CloudStack source code from Apache Git repository in WORK-VM (see step 3).

git clone https://git-wip-us.apache.org/repos/asf/cloudstack.git testing
cd testing
git checkout 4.2    # or other branches or tags (like 4.2.0)

Revert commit 7f9463bb54f19e7676f8c6049d1ebc02330a730f which make DevCloud not working on Apache CloudStack 4.2 branch.

[root@weizhou-centos testing(4.2)]# git show 7f9463bb54f19e7676f8c6049d1ebc02330a730f
commit 7f9463bb54f19e7676f8c6049d1ebc02330a730f
Author: Anthony Xu <anthony.xu@citrix.com>;
Date:   Tue Dec 3 01:36:24 2013 -0800

    put shell scripts to a seperate directory in XS
    use same scripts for both XS and XCP
[root@weizhou-centos testing(4.2)]# git revert 7f9463bb54f19e7676f8c6049d1ebc02330a730f

(6) Compile Apache CloudStack source code, deploy database, and run the management server

mvn -P developer,systemvm clean install
mvn -P developer -pl developer,tools/devcloud –Ddeploydb
mvn -pl :cloud-client-ui jetty:run

Now we can see the Apache CloudStack UI on http://192.168.56.2:8080/client (username:admin, password:password)
devcloud-13
(7) Change some global configuration in Apache CloudStack, and restart management server. Or you can change by MySQL:

mysql -e &quot;update cloud.configuration set value='192.168.56.2' where name='host'&quot;;
# the value should be the ip of WORK-VM.
mysql -e &quot;update cloud.configuration set value='10' where name='cpu.overprovisioning.factor'&quot;;
mvn -pl :cloud-client-ui jetty:run

3. DevCloud deployment and testing

(8) Start DevCloud in VirtualBox. And run the following command in WORK-VM for testing Apache CloudStack 4.2 and newer.

mkdir /mnt/secondary
mount 192.168.56.10:/opt/storage/secondary /mnt/secondary
wget http://download.cloud.com/templates/4.2/systemvmtemplate-2013-07-12-master-xen.vhd.bz2 -O /root/systemvmtemplate-2013-07-12-master-xen.vhd.bz2
./client/target/generated-webapp/WEB-INF/classes/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -f /root/systemvmtemplate-2013-07-12-master-xen.vhd.bz2 -h xenserver -F

This is because the system VM (System Virtual Machines) [6] template changed between Apache CloudStack 4.1 and 4.2. So the old system VM template inside DevCloud is no longer valid when we test Apache CloudStack 4.2. These commands download the new system VM template and install it to Secondary Storage (NFS inside DevCloud).
After this, take a snapshot of DevCloud in VirtualBox, so that we do not need to update systemvm template any more. Each time when we want a clean DevCloud, we can restore the snapshot.
devcloud-14
(9) Using Marvin to deploy DevCloud. Open another session and run the following commands:

cd tools/marvin
python setup.py install	# run only the first time. Check python-devel package if fails
cd ../../
mvn -P developer -pl tools/devcloud -Ddeploysvr	# Basic Network

If you want to use other type of networks, you can replace the last command with one of the following commands.

python tools/marvin/marvin/deployDataCenter.py -i tools/devcloud/devcloud.cfg    # Basic Network, same to before
python tools/marvin/marvin/deployDataCenter.py -i tools/devcloud/devcloud-advanced.cfg     # Advanced Network
python tools/marvin/marvin/deployDataCenter.py -i tools/devcloud/devcloud-advancedsg.cfg  # Advanced with Security Groups

(10) After Step (9), a Zone/Pod/Cluster have been created, and DevCloud has been added as a host. After a few minutes, we can see that the system VMs are running on Apache CloudStack UI -> Infrastructure -> System VMs.
devcloud-15
(11) Now we can deploy a VM on Apache CloudStack UI -> Instances -> Add Instance -> Template -> select “tty Linux” -> select “tinyOffering” -> next . After a few minutes, the VM will be up.
devcloud-16
A virtual router (for default network) is also running.
devcloud-17

4. Limitation and future work

Now we have an testing environment with Apache CloudStack 4.2. We can test the functionalities in CloudStack like virtual machine operations, network, template, domain/account.

However, in this environment, we have only one host (devcloud) with local storage (this means the volumes of virtual machines are stored on the host, not shared storage, so virtual machines live migration is disabled). In the next post, I will introduce how to test with multiple devcloud hosts, and shared storage (like NFS).

Tips

(1) It is better for testing Apache CloudStack 4.2. The 4.3/master branch have not been tested.

(2) If you are new to CloudStack, you can get some concepts from Apache CloudStack Installation Guide [7] and Apache CloudStack Admin Guide [6]. Please note a new type of network (Advanced Network with Security Groups) was introduced in Apache CloudStack 4.2.0.

(3) You can use XCP command lines [8] to manage virtual machines inside DevCloud. For example:

root@devcloud:~# xe vm-list
uuid ( RO)           : 576aacc8-4c8e-e0b4-f035-79001b4a7284
     name-label ( RW): r-4-VM
    power-state ( RO): running

uuid ( RO)           : 1efad534-bcd5-c183-9bfa-5eaf4a4afe80
     name-label ( RW): i-2-3-VM
    power-state ( RO): running

uuid ( RO)           : c8c2f1a3-40d3-308f-70bf-687f7f49b9a5
     name-label ( RW): Control domain on host: devcloud
    power-state ( RO): running

uuid ( RO)           : 61721ac5-c139-de00-c167-9e2edda49471
     name-label ( RW): v-2-VM
    power-state ( RO): running

uuid ( RO)           : 464b1a57-1d82-eb33-b8da-93f029289389
     name-label ( RW): s-1-VM
    power-state ( RO): running

(4) You can find more details in log files:

1. vmops.log in testing directory (WORK-VM).
2. /var/log/xcp-xapi.log inside DevCloud.

(5) If you want to attach the git branch name to directory path, please follow the article: “Git tip: Show your branch name on the Linux prompt”

(6) If we change some source codes, but now willing to build all projects as it take a long time. We can build the specified projects using maven.

mvn –P developer –pl api,server		# if you want to re-build api and server projects
cp ./api/target/cloud-api-4.2.1-SNAPSHOT.jar ./client/target/cloud-client-ui-4.2.1-SNAPSHOT/WEB-INF/lib/cloud-api-4.2.1-SNAPSHOT.jar
cp ./server/target/cloud-server-4.2.1-SNAPSHOT.jar ./client/target/cloud-client-ui-4.2.1-SNAPSHOT/WEB-INF/lib/cloud-server-4.2.1-SNAPSHOT.jar

If you want to re-build systemvm.iso which is attached to system VMs when they start.

mvn -P developer,systemvm -pl patches/,services/console-proxy/,services/console-proxy/server/
cp ./services/console-proxy/server/dist/systemvm.iso ./client/target/cloud-client-ui-4.2.1-SNAPSHOT/WEB-INF/classes/vms/systemvm.iso
scp ./services/console-proxy/server/dist/systemvm.iso 192.168.56.10:/usr/share/xcp/packages/iso/systemvm.iso

References

[1] http://www.leaseweb.com/en/about-us/press/leaseweb-introduces-new-private-cloud-platform-powered-by-apache-cloudstack
[2] http://cloudstack.apache.org/
[3] https://pypi.python.org/pypi/cloudmonkey/
[4] https://cwiki.apache.org/confluence/display/CLOUDSTACK/DevCloud
[5] http://people.apache.org/~bhaisaab/cloudstack/devcloud/devcloud2.ova
[6] https://cloudstack.apache.org/docs/en-US/Apache_CloudStack/4.2.0/html/Admin_Guide/working-with-system-vm.html
[7] http://cloudstack.apache.org/docs/en-US/Apache_CloudStack/4.2.0/html/Installation_Guide/deployment-architecture-overview.html
[8] http://wiki.xen.org/wiki/XCP_Command_Line_Interface
[9] http://www.leaseweb.com/labs/2013/08/git-tip-show-your-branch-name-on-the-linux-prompt/

Share

Automated tests for SOAP API in Java

Don’t think the story will be short, but it’s definitely interesting. So, I got a new project where I need to cover a SOAP API with automated tests written on Java. As a starting point I have a URL to a WSDL file to work with. The “tricky” part is in the environment configuration. Our test environment is hidden behind a SOCKS proxy server. So, if you want to work with a test environment, you need to make your requests through that proxy, otherwise you’ll “talk” to another environment that we don’t need right now. Not a usual configuration, but it had it’s own reasons for doing so. My first problem was to decide how to work with WSDL and in what direction my future framework would go. After some Googling and trials, I stopped on the JAX-WS library. This is handy because with the “maven wsimport” task, you can easily generate all needed classes and objects where your stubs will be held. Here’s how it looks like in pom.xml:

                <plugin>
                    <groupid>org.jvnet.jax-ws-commons</groupid>
                    <artifactid>jaxws-maven-plugin</artifactid>
                    <version>${jaxws.plugin.version}</version>
                    <executions>
                        <execution>
                            <id>{put_some_id}</id>
                            <phase>validate</phase>
                            <goals>
                                <goal>wsimport</goal>
                            </goals>
                            <configuration>
                                <!--<wsdldirectory>${project.basedir}\src\wsdl</wsdlDirectory>-->
                                <wsdllocation>{your_wsdl_location}</wsdllocation>
                                <destdir>${project.basedir}\src\main\java\Stubs\oop</destdir>
                                <wsdlfiles>
                                    <wsdlfile>${project.basedir}\src\main\resources\wsdl\myWSDL.wsdl</wsdlfile>
                                </wsdlfiles>
                                <packagename>Stubs.oop</packagename>
                                <!-- Without this, multiple WSDLs won't be processed -->
                                <stalefile>${project.build.directory}/jaxws/stale/wsdl.done</stalefile>
                            </configuration>
                        </execution>
                        <execution>
                            <id>{put_some_id}</id>
                            <phase>validate</phase>
                            <goals>
                                <goal>wsimport</goal>
                            </goals>
                            <configuration>
                                <!--<wsdldirectory>${project.basedir}\src\wsdl</wsdlDirectory>-->
                                <wsdllocation>{your_wsdl_location}</wsdllocation>
                                <destdir>${project.basedir}\src\main\java\Stubs\wsdl2</destdir>
                                <wsdlfiles>
                                    <wsdlfile>${project.basedir}\src\main\resources\wsdl\your_wsld2.wsdl</wsdlfile>
                                </wsdlfiles>
                                <packagename>your_package_name</packagename>
                                <!-- Without this, multiple WSDLs won't be processed -->
                                <stalefile>${project.build.directory}/jaxws/stale/wsdl.done</stalefile>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>

It was a bit hard for me to get the WSDL file from the URL, so I decided to save it locally and read it from there then. Since changes on the API are not frequent, I can easily accept this. This configuration allows to add as many WSDL sources as I want and to store stubs for each of them in project. First problem was solved. Now, I had to figure out how to make my framework to use proxy for it’s calls. My first trial was basic and most common in the Java world:

System.getProperties().put("proxySet", "true");
System.getProperties().put("proxyHost", getProxyHost());
System.getProperties().put("proxyPort", getProxyPort());

But I kept getting errors and no successful connection. My next guess was that problem could be in the SSL, since we are using HTTPS. So, I started the browser, imported the security certificates (they were self-signed since it’s a test environment), added them to java “cacerts” keystore, and added next to my code:

System.setProperty("javax.net.ssl.keyStore", "keystore.jks");
System.setProperty("javax.net.ssl.trustStrore", "cacerts.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "changeit");

I tried to debug and to make sure that the JVM is using my proxy settings and it was true – everything was there. What would be the next step in debugging for me? I decided to install a local proxy and try to put my requests through it, so I could get more details. I installed Charles – a fantastic proxy server that helped me a lot in the past with REST API automation. It has a life changing ( for me in this case) “External Proxy” option . I set it to proxy all requests to our SOCKS proxy and I put my Java API calls through Charles as well. And it worked! You can’t even believe how happy I was because of it. But now I got another problem – Charles cost $50 for one license. So, there were two questions that I needed to solve:

  • Why my Java calls works fine with Charles and without it they fail?
  • Where to find free and easy to setup HTTP proxy?

With help from one of our developers we could find out why Java kept getting authentication errors and didn’t want to connect to test environment properly. The problem was that Java was connecting to the SOCKS proxy properly, but it was resolving remote DNS to another environment to which I didn’t have proper certificates and credentials for authorization! I found only one article on StackOverflow regarding this issue and from that point I new that I need to have local HTTP proxy that is:

  • free
  • can forward my requests to SOCKS proxy

I’ve spent whole day trying to find an easy-to-use and adequate proxy server for Windows ( it’s my Workstation that I need to use), I looked over 15 different apps and failed. In the end, I installed VirtualBox with Ubuntu and install there Squid3 proxy server. It’s the most popular and common proxy server for Unix, from what I saw on Google. But this crazy application has a configuration file with more then 3000 lines! It’s not that easy to make it run as I want, it’s not even that easy to restart it. So, after couple hours I gave up on it and started looking for more solutions. Luckily, I found Polipo – tiny, easy to install and setup proxy server. It only has a few main options that I had to setup and make everything work as a charm:

  • proxyAddress – set it to IP address of your local virtual box, or your local machine, if you use Linux or Mac
  • allowedClients – list of IP addresses from which Polipo will allow to access it and forward requests towards another proxy or web directly
  • socksParentProxy = “host name and port of your proxy to which I needed to forward my requests”
  • socksProxyType = socks5

Save changes and restart – that’s it! After that I pointed my Java framework to the local proxy and got green tests! To set the proxy for my tests I used custom MyProxySelector class:

                      package Base;

                      import java.net.*;
                      import java.util.ArrayList;
                      import java.util.HashMap;
                      import java.io.IOException;

                      public  class MyProxySelector extends ProxySelector {
                          // Keep a reference on the previous default
                          public ProxySelector defsel = null;

                          /**
                           * Inner class representing a Proxy and a few extra data
                           */
                          class InnerProxy {
                              Proxy proxy;
                              SocketAddress addr;
                              // How many times did we fail to reach this proxy?
                              int failedCount = 0;

                              InnerProxy(InetSocketAddress a) {
                                  addr = a;
                                  proxy = new Proxy(Proxy.Type.HTTP, a);
                              }

                              SocketAddress address() {
                                  return addr;
                              }

                              Proxy toProxy() {
                                  return proxy;
                              }

                              int failed() {
                                  return ++failedCount;
                              }
                          }

                          /**
                           * A list of proxies, indexed by their address.
                           */
                          HashMap<SocketAddress, InnerProxy> proxies = new HashMap<SocketAddress, InnerProxy>();

                          public MyProxySelector(ProxySelector def, String host, int port) {
                              // Save the previous default
                              defsel = def;

                              // Populate the HashMap (List of proxies)
                              InnerProxy I = new InnerProxy(new InetSocketAddress(host, port));
                              proxies.put(i.address(), i);
                          }

                          /**
                           * This is the method that the handlers will call.
                           * Returns a List of proxy.
                           */
                          public java.util.List select(URI uri) {
                              // Let's stick to the specs.
                              if (uri == null) {
                                  throw new IllegalArgumentException("URI can't be null.");
                              }
                              /**
                               * If it's a http (or https) URL, then we use our own
                               * list.
                               */
                              String protocol = uri.getScheme();
                              if ("http".equalsIgnoreCase(protocol) ||
                                      "https".equalsIgnoreCase(protocol)) {
                                  ArrayList l = new ArrayList();
                                  for (InnerProxy p: proxies.values()) {
                                      l.add(p.toProxy());
                                  }
                                  return l;
                              }

                              /**
                               * Not HTTP or HTTPS (could be SOCKS or FTP)
                               * defer to the default selector.
                               */
                              if (defsel != null) {
                                  return defsel.select(uri);
                              } else {
                                  ArrayList l = new ArrayList();
                                  l.add(Proxy.NO_PROXY);
                                  return l;
                              }
                          }

                          /**
                           * Method called by the handlers when it failed to connect
                           * to one of the proxies returned by select().
                           */
                          public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
                              // Let's stick to the specs again.
                              if (uri == null || sa == null || ioe == null) {
                                  throw new IllegalArgumentException("Arguments can't be null.");
                              }

                              /**
                               * Let's lookup for the proxy
                               */
                              InnerProxy p = proxies.get(sa);
                              if (p != null) {
                                      /**
                                       * It's one of ours, if it failed more than 3 times
                                       * let's remove it from the list.
                                       */
                                  if (p.failed() >= 3)
                                      proxies.remove(sa);
                              } else {
                                      /**
                                       * Not one of ours, let's delegate to the default.
                                       */
                                  if (defsel != null)
                                      defsel.connectFailed(uri, sa, ioe);
                              }
                          }
                      }

And to turn the proxy on and off I wrote next switch methods:

            private ProxySelector defaultProxy = ProxySelector.getDefault();

            public void setLocalProxy(){
                MyProxySelector ps = new MyProxySelector(ProxySelector.getDefault(),
                                                         localProxyName,localProxyPort);
                ProxySelector.setDefault(ps);
            }

            public void disableProxy(){
                ProxySelector.setDefault(defaultProxy);
            }

That’s it. Now I can run my tests easily with control over when to the use the proxy and when not to. In the future I’ll move my tests to the CI server (Jenkins most probably) and will setup Polipo HTTP proxy on that environment in two minutes. It’s always nice to solve such non-ordinary problems. Most probably my solution is not very elegant and “right”, but it works right now and for this moment this is all that matters to me, since I can start writing automated tests rather then fighting with configuration issues.

Share