Vukoje.NET

Vukoje's blog about software development

Writing awesome dev job ad

Why write about job ads? This is blog for software developers, not HR and marketing. Well, can you really expect HR to find you good developers without your help? Yes you, the freak with the keyboard.

My company wanted to hire more talented programmers and the question was how to do this within limited time and budget? There are many companies fighting for good programmers, how can we step out?

I gave it a thought, what I can do to change this in our favor and I concluded that I should rewrite our old generic corporate developer job ad to something awesome. So I did it and we had pretty good result. You can see new job ad here.

Read on to see what were my guiding principles.

 

What’s wrong with old ad?

 

The ad is generic and boring. It doesn’t distinguish us from any other company.

Section describing candidate responsibilities should go without saying because it describes almost any dev job and still you have no idea what you would be working on if you get the job.

We ask for RequireJS experience. Really!? I can teach it to good dev in 1 day. I think you should rarely insist on experience in some technology if that is something that can be learnt very quickly.

 

How to be better?

 

Here are my guiding principles for writing new ad:

  • It should be written by dev for dev.
  • It should state all the things I like about my job. Yes coffee and parking are important to me, they make every morning start a little nicer. Why not share it with others.
  • It should mention all the things we built and are proud of. Programmers love challenges and project where they can learn new stuff. If you have them, than brag you fool!
  • No bullshit and empty talk.  Marketing lead, friendly work environment, bla bla… say something concrete and interesting.
  • It should be funny. Why the hell not! We try to have fun at work every day and we are very proud of our work atmosphere. Why be boring when it comes to a job ad?
  • It should be in native language.

 

How did it go?

 

It went great! We had way more job candidates than normal. Usually we hire 1 good programmer after we put out an ad. This time we hired 3. Few candidates said that they applied only because they liked the unusual ad. We got CV’s and emails from candidates that were personalized to match humor from our ad.

All of this because of little honesty and humor. Don’t be boring!

 

Start.it talk – Juniors & Seniors

Last Friday I gave a talk at Start.it event about junior programmers, how can day choose a company and I gave some tips how to manage new guys in team from team lead perspective. I hope you enjoyed it. Slides are below.

juniori-seniori002

 

juniori-seniori001

 

From junior programmer to master

A decade ago I had many, many questions and doubts about programming. How does programming look in real life on big projects? Is it too hard? Will I be any good at it? Over the last few months I have been mentoring talented junior programmers in my company from whom I’ve come to have great expectations. This is what motivated me to write this post and share it with young talents with whom I will hopefully work one day soon.

Learn, learn, learn

You will learn some things in the university, but they are not enough to make you excellent. You should keep learning new things all the time because technology is complex and constantly changing. For every subject you are interested in there is a fabulous book out there full of knowledge.

Once a friend told me “If I read 10 pages of an IT book every day, imagine how many books I will have read in few years, and what I will know”. Well, of course, I didn’t keep up with that pace, but I pressured myself to always read a lot. I keep a public list of things I read as a public CV and a motivator to keep going.

Technical blogs are becoming a main source of information and more and more often people publish books by refining content already published on their blogs. So pick a favorite RSS reader and start building you feed collection that will keep you up to date. For a start, here are some of my favorites:

You become an excellent programmer in you free time

Formal education is a good start, but it’s not enough. Work experience is mandatory, but you only advance in practical stuff you solve at your desk. It takes time and passion to go deeper into problems and get your eureka moments. Don’t expect that others, teachers or colleagues, will teach you how to code.

This doesn’t mean that you will have no free time. It only means that programing will be one of your hobbies and that you will annoy your non-programming friends with your technical discussions.

Learn how to write code

If you are going to be a programmer, you will be staring at code editor and writing code most of your work day. You should write code like a pro. Some programmers tend to think that architecture and fancy patterns are important and that code is just something in between, but I would strongly disagree. I’ve never seen app with great architecture and crappy code.

Not having enough time is a common excuse for writing bad code. Avoid excuses. Once you master the skill of clean code it will come naturally to you, at no cost.

So how do you write code like a pro? Well read a book of course! I read Refactoring by Martin Fowler but I’ve heard that Clean Code and Code Complete are also great. Actually I remember an older guy at the university who told me to read Refactoring and that it will make me twice the programmer I was. Till this day I believe this to be truth.

There are also code conventions and code analysis tools for specific platforms. They will come in handy. Why waste time and energy on trivial decisions when you can follow guides.

Is it hard?

Well, it can be, when not done the right way. You could end up with an application that is very hard to maintain because of the huge complexity and a lack of tests or documentation. On the other hand, when development is done properly, programming seems more like a fun game than work. As you get better you will build better apps and your job will be easier.

Sometime you end up with a problem you just cannot solve. In that case you either solve it and feel like you’re on top of the world, or somebody else does and you learn from him or her.

Do the hard stuff

Some guys constantly run away from tough tasks. My advice is to do just the opposite, ask for the toughest. Tough problems will make you a tough programmer and speed up your learning. Also, if you go for the hard things you will never be bored at work.

It’s ok to be scared

So you are starting to feel comfortable as a programmer and you are successfully completing your tasks. It feels good. But then one day a new task comes along. A new task requires new technologies, tools and domain knowledge you don’t have. You get scared. You doubt if you will you be able to complete the task. It’s OK to be scared. The only difference between you and a more experienced guy is that he has been scared many times before and probably successfully completed such tasks and now he believes in himself. Everybody feels like a phony at some point.

It isn’t only about code

Writing code is not all there is to being a programmer. Your job is to create successful software. In order to do that you will be testing, writing specs, talking to customers, organizing tasks, installing machines, motivating and mentoring coworkers… Even carrying equipment and much, much more… Don’t underestimate value of pure business domain knowledge. It can be much more valuable than programming skill.

There are always guys who insist that their job is only to write code and not know anything about the business domain or anything else, but they are usually jerks.

Don’t be a jerk

Because nobody wants to work with one. If you behave like one you will be alone in solving problems although it much easier to do it together.  Be a humble programmer.

Integrating responsive site in Salesforce1

As you probably already know, Salesforce (SF) has built their native app Salesforce1 (SF1) and because SF is such a big hit there is a high chance you app will need to integrate with SF1, which could cause you problems. SF1 is native app which is extendable not by writing native code but by integrating with web apps. Now as native usually means iOS, this integration leads us to dreadful mobile Safari iframe.

The Pain

So here you are, you need to open your app in safari mobile iframe which sucks… and chances are you’ll want to open your existing web app with responsive design that adjusts to mobile screen sizes. Responsive design means general purpose design that adjusts to various screen sizes and as such it is much more complex than pure mobile site. This complexity significantly lowers your chances of working properly in safari mobile iframe.

 

When I opened my site it was complete agony because it had completely unpredictable behavior. It would reset scroll position in middle of page scrolling and page width would change constantly causing elements to jump around constantly. Occasionally SF1 would crash and wouldn’t open my site again until I reinstalled SF1 app.

I spent few days working on a solution which I wanted to share with everyone and hopefully ease someone’s suffering.

The Solution

In order to fix problem with flickering and iframe width changing I needed to set iframe width to exact value in pixels. Setting width to 100% simply wouldn’t work so I would calculate window width in JavaScript and set it dynamically to iframe.

Now I was left with the problem of scrolling. Unlikely any other browser, mobile Safari iframe expands vertically to display the full document which it contains. There are various strategies for “implementing” iframe scrolling on mobile Safari. At the end I fixed this by setting scrolling="no" and style="overflow: hidden” on iframe. I also set iframe height to window size which I calculated same way as window height. I added this height to iframe url as query string which on the other hand I used to resize my site and actually have scrolling on site instead on iframe.

Below is the code I have embeded in my SF page.

Cross domain RESTful API calls?

Maybe you started moving more of your web app logic to client and relying on RESTful services for client-server communication knowing that someday other people will be able to reuse these services as remote API to you app. When I did, I knew that there was a problem with calling restful services from other site’s JavaScript because of the same origin policy that forbids browser to make cross domain Ajax calls, but I also knew that all the major web sites allow restful services consuming from JavaScript.

I investigated a bit and here are alternatives I found for this problem.

JSONP

JSONP is browser hack that became standard solution for cross domain Ajax calls. Browser is hacked by pretending that service is static JavaScript file. In order for this hack to work, server must support JSONP, which means you might be required to alter your services a bit.

Main issue with JSONP is that it doesn’t support HTTP POST (only HTTP GET). Another potential problem with JSONP is that is not asynchronous, which means that it would probably block browser which would lead to poor user experience.

CORS

Cross-origin resource sharing (CORS) is new standard that allows cross-domain Ajax calls. Main issue is that not all main browses are supported. Biggest problem is partial support in IE8/9 of which next limitations are biggest problem:

  • Only text/plain is supported for the request's Content-Type header
  • No authentication or cookies will be sent with the request

Server Proxy

Another alternative would be to use server proxy that would execute cross-domain request. In other words, do cross-domain request on server instead in browser because server doesn’t have Same-origin policy limitation. The disadvantage is additional work for your clients that must code server proxy instead of consuming your API right from JavaScript.

cqrs-proxy

iFrame integration

Although iFrames have cross domain restrictions like Ajax, they are much more flexible, so hidden iFrame can be used to enable cross-domain Ajax. 3rd party web page could load our special iFrame for that could execute Ajax calls in behalf of 3rd party page because it is on same domain as our API, and then it can send data back to page. For cross origin iFrame communication Window.postMessage can be used or easyXDM library if older browsers need to be supported.

cqrs-ifrmae

Resources

Naming is the design

There are only two hard things in Computer Science: cache invalidation and naming things. - Phil Karlton

Yes, naming is hard but it is also very important. We tend to think that big complex architecture is the software design and that type and member naming along the way is just something that is hard and that we screw up. My point here is that naming is the software design and that on daily basis to me it is more important than architecture.

If naming is good:

  • it will be easier to understand the code and get the big picture
  • API will be simpler to user and there will be less bugs
  • there will be a greater chance that code for some new feature goes to the right place and that software will evolve gracefully instead of becoming a big ball of mud

In book Domain Driven Design, Eric Evans describes the term Ubiquitous language for the practice of building up a common, rigorous language between developer and users, and we can think of this as naming on steroids. Also Obfuscation can demonstrate the importance of naming because obfuscated code has worst possible names so that is almost not human readable.

Naming and Cohesion

 

As applied to object-oriented programming, if the methods that serve the given class tend to be similar in many aspects, then the class is said to have high cohesion. In a highly cohesive system, code readability and the likelihood of reuse is increased, while complexity is kept manageable. - Cohesion

IMO types that have high cohesion are easy to name. Low cohesion types are hard for naming because usually they are schizophrenic and do many (unrelated things). So we can think of a good name as a necessity that will force good design decisions. 

Code example

 

I want to give an example of bad naming that irritated me enough to write this post. Here are some JavaScript DOM Event methods.

  • cancelable - Returns whether or not an event can have its default action prevented
  • preventDefault() - To cancel the event if it is cancelable, meaning that any default action normally taken by the implementation as a result of the event will not occur
  • defaultPrevented - Returns a boolean indicating whether or not event.preventDefault() was called on the event.
  • bubbles - Returns whether or not an event is a bubbling event
  • stopPropagation() - To prevent further propagation of an event during event flow
  • cancelBubble - Indicates if event bubbling for this event has been canceled or not.

For me it is hard to remember names of function and properties because they are not consistent. Here are some terms that are used interchangeable in API but mean the same thing:

  • stop, cancel, prevent
  • bubble, propagation
  • cancelable, hasDefault

Below is my proposal for renaming this API that should be trivial to remember.

Old New
cancelable hasDefault
preventDefault() cancelDefault()
defaultPrevented isDefaultCanceled
bubbles bubbles
stopPropagation() cancelBubling()
cancelBubble isBublingCanceled

Thoughts on logger lib design

Last year I gave a talk State of the art logging where I discussed logging, logging libraries and tools for logs analysis. I wanted to go a step back and share with you my notes on designing a logging library. I actually written down what was important for me and later decided to go with custom logger implementation that wraps NLog.

When I talk about logging I always tell a difference between tracing and event logging. By tracing I mean logs with high detail data useful for debugging app. Trace is available only in “tracing mode” – trace data is not collected by default. By event logging I mean data that application outputs to some persistent store and which are used for monitoring application behavior (e.g. crash reports).

 

Tracing

Tracing must have high performance:

  • It should have no performance impact if not turned on
  • String formatting should not be done if tracing is turned on (Tracing client code never formats string because formatting consumes time and it might not be needed)
  • It should have very small memory consumption when tracing is turned off.
  • When turned on it must not endanger app pool execution (e.g. production tracing must not cause out of memory exception).

Tracing should be enabled per session in web applications (multitenant or not) but should also work in cases where session doesn’t exist (tracing win services, tracing web applications before session initialization).

Tracing should support priority levels and labels (categories).

Tracing should support “Start – End” style logs with using statement. This will make tracing API better (smaller and more readable code) and make performance monitoring easier (time of method execution). It should also enable hierarchy displaying of trace data (similar to Call stacks in debugging).

If Tracing component uses external components this must be hidden (our trace will wrap them) because otherwise it would introduce high coupling to that external component and make any changes very hard.

Trace should support logging to file. File system organization for web multitenant applications should be like this: Root folder/tenant name/user name/date/request time stamp.log Programmer should be able to configure simpler folder structure in simpler cases (Windows service that doesn’t have tenant or user). Root folder should be configurable. If session is not yet initialized or is lost, files should be logged to Root folder/tenant name/.

In web applications it should be possible to trace each web request in separate trace file. In other cases programmer should be able to decide when to split file (per day, month, never…).

Trace should have buffer of last N relevant trace calls (probably only logs with highest priority). N constant should be possible to configure by programmers. Beside this buffer of last N relevant logs we might keep full trace of last HTTP request. This can be useful when tracing is not turned on and application breaks. In this case we might still want full trace form request that broke the app. This solution might compromise memory so we must be careful with it.

Trace files older by some period should be deleted in some time intervals.

Tracing must not break in production! Breaking is only ok in debug mode. E.g. if programmer supplies trace with invalid parameters, Trace should break only in debug mode.

 

Event logging

Event log should contain information about events in application that are of interest to people monitoring application health and configuration status.

Event log should support Event log types:

  • Breaking error
  • Handled error
  • Info
  • Warning

It should be possible to search and filer event log data. E.g. show me today’s breaking errors or show me yesterday information containing text “salesforce.com sync started”.

Event logs should contain enough useful data for understanding event details. E.g. braking errors should contain following data:

  • User name or logged in user
  • Application name (multiple applications might be logging events to same DB)
  • Exception data (call stack…)
  • Http request data
  • Trace buffer (what did User do before error – useful for extracting reproduction steps)

Events should be logged to DB and files. Logging to file is needed for:

  • applications that don’t have DB
  • logging DB access errors (e.g. invalid DB connection string)

Event logging must not break in production! Breaking is only ok in debug mode. E.g. if event log DB is not accessible, Event logger should not break.

It would be nice to have feature where Event Logs can be updated by support team with comment (e.g. “Known issue”, “Bug 123 created”, ”Resolved”…).

Event logging should not be transactional. If Event is being logged in some outer transaction and that transaction is rolled back, the event is still logged.

My badass list of JavaScript resources

About a year ago I finally started learning JavaScript so I could build complex, fast and fancy client web app that relies on restful services. I was completely new to this subject so I basically needed to learn everything from scratch… the language, best practices, architecture…

So here are resources I used for learning and libraries that helped me along the way.

JavaScript basics

First the language and most popular lib – jQuery.

Knockout

Knockout is great lib for MVVM that does client rendering and data binding.

Bootstrap

Grate CSS framework with fancy controls that supports responsive UI.

Controls

Additional controls that integrate nicely with Bootstrap.

Libs

Don’t make me think–notes from book

In effort to teach myself more about web design I have read “Don’t make me think” by Steve Krug. I recommend the book to everyone interested in the same subject. This book seams as a good starting point and additionally it is small and is being read very fast. If you are planning to read this book maybe it is best to wait for the third edition that will be out soon. Update – third edition is out.

So here are my most important notes I am sharing so I can look them up later.

  • Webpage should probably have following elements that should be easy to spot:
    • Site ID/Logo and tagline – Indicates what site is this? It should be clickable and lead to home page.
    • Site Sections – Indicates what are the major sections of this site? Current sections should be highlighted.
    • Site Search – Especially important for users that prefer searching to browsing
    • Utilities – Less important common link like login, home, how to by…
    • Page name – Clearly informs user on what page are currently.
    • Local (contextual) navigation - Show what are user options on current page?
    • Breadcrumbs – Clearly explaining where user is in site hierarchy and offering easy way to go back to some upper level.
  • Home page is different from the rest of the site and it should be designed more like billboard or cover of the magazine. For some visitors home page will be only chance to leave good impression about your site.
  • Home page common elements:
    • Site ID/Logo and tagline
    • Site Sections – to give an overview of what site has to offer.
    • Site Search
    • Welcome blurb – short description of site that should be visible without scrolling.
    • Teases – hints of good site good stuff (top stories, hot deals, most popular pages…)
    • Timely content – like recent news/comments to signal that site is live and frequently updated.
    • Start here – It should be clear to user how to begin using the site (e.g. user registration)
  • Things that are related logically should be related visually
  • Make it obvious what is clickable.
  • Omit needles words. Design web pages for scanning, not reading.
  • Good design makes web site obvious to users and it doesn’t requires them to think too much how to use it.
  • Test usability of your site at least once a month.