Showing posts with label SDLC. Show all posts
Showing posts with label SDLC. Show all posts

Thursday, February 13, 2014

Don't Send Us Your Resume!

At a small company where I work, we had a job opening about 9 months ago (it takes a bit of time to finish writing a blog post). We were looking for a software tester of a particular kind: one that can program. Automated testing is absolutely crucial in making maintainable, good quality software.

First attempt - FAIL.
We posted a normal ad first, and in two weeks we received almost a hundred CVs/resumes. The advertised position was a 3 month contract with a very good rate, and a chance of extending.

A side note:
Although both leading job search sites: seek.com.au and mycareer.com.au ask for resumes, in Australia, the terms "CV" - Curriculum Vitae and "resume" seem to be used interchangeably in this context. In the US it's usually "resume", in Europe - "CV". Australia takes words from both cultures. In the US a CV is usually a complete career history, and a resume is a short 1-2 page version of your CV tailored to the job you are applying for. Unless you are applying for a highly visible job, for example, a CEO of an international company, a university lecturer, or something similar, you should probably send your 1-2 page resume, not 7-9 page CV.

Back to the main story:

It took me a few days to go through the submissions and identify potential candidates. It was not something I would like to do again. Here is why:

1. CVs instead of resumes.
Some of the documents were very long: 7 to 9 pages. It would take me days or weeks to read everything carefully (7 x 100 = 700 pages), so I skimmed.

2. No cover letters.
Maybe a third of submissions had cover letters. Without a cover letter it is sometimes hard to determine if you are applying for a job with us, or if you submitted your resume by mistake. A short cover letter helps me get interested in your resume.

3. Missing information.
Many candidates did not include their address. I did not know if they were local or not. Many did not provide addresses (city, country) of their employers. I did not know which country they worked in. A few did not provide e-mail addresses or phone numbers.

4. Inappropriate information.
At that stage I am not interested in your visa or passport number, I assume you have the right to work in Australia if you are applying for a job in Australia, if not, please say so in your cover letter. You definitely should not include your picture, unless you are applying for a job as an actor, TV presenter, or a model. :-)

5. Language errors.
Good communication skills don't need to be advertised, they are self-evident. In some jobs they don't matter much, in others they are crucial, but a resume must not have glaring errors, and no, it is not enough to run a spellchecker.

6. Multiple submissions.
Not keeping track of where you applied and sending your resume twice for the same ad doesn't look good. It's not about quantity, it's about quality.

Initially, I planned on confirming every submission by e-mail, and then informing every candidate about their status, but after the first five I realised that I did not have time for that. Sorry. The reality is: if the employer is interested in you, they will probably contact you quite quickly. Some organisations take long though, weeks or even months.

From the 100 candidates we selected 10. We asked them to complete a simple programming task in Sikuli and Robot Framework. At home. Time given: we were prepared to wait a few days.

Only one candidate completed the task, but not very well, half of the code worked, the other half had a sneaky bug that made it look like it worked, but in reality it didn't. We still would consider that candidate, but he was not readily available - he was in India, and he had other commitments at that time - we needed someone quickly. The others, well, the main excuses were: "the task is too hard", and "I had no experience with that technology" -  the technology was listed in the ad, so there was time to check it out, and we did not require being a master in it. Quite the opposite, we assumed no candidate worked with it before. One candidate misunderstood instructions, couldn't do it, and then started whinging. That's probably the worst you can do. Positive "can do" attitude, courtesy, and ability to learn quickly are very important.

Second attempt - PASS.
My project manager is a bit of a cowboy sometimes (the "quick on the trigger" type), so seeing that the first ad, prepared carefully by our boss, was not working, he took a risk, wrote another ad, and using his own money posted it. The new ad's headline?

"Don't Send Us Your Resume!"

The ad asked candidates to NOT send their resumes, but instead it had a link to the programming task. That obviously did not stop a few people from sending their resumes. Seriously, sending your resume off without reading the ad carefully, doesn't increase your chances of finding a job. It just shows your carelessness.

After two days we had the first submission, by a local software engineering student looking for a part time job. A few days later, we had another, by a French software developer who was on a working holiday visa, working on a farm nearby. Both started working with us within days, and they are still with us 9 months later.




Monday, March 7, 2011

Software Creativity by Robert Glass

Rating: A critical look at formal methods as a solution to all.

By page 19 (and 13 pages of forewords) we learned that there are two opposite views of how software should be developed: disciplined and flexible, and that the author will in the end show us that the middle way is the best.

Author's theory about software practice includes these issues:
  • Discipline vs. flexibility
  • Formal methods vs. heuristics
  • Optimizing vs. satisficing (sic!)
  • Quantitative vs. qualitative
  • Process vs. product
  • Intellectual vs. clerical tasks

On page 268 there is a good list of what academic research should be focusing on, two of which seem especially worthy:
  • issues contrary to commercial interests,
  • unsolved problems.

I think that definition of standards with sample implementations might fall into the "contrary to commercial interests" category. This might prevent the "design by committee" problems that we see in CORBA and IATA CUSS standards.

Chapter 9 contains an interesting discussion of "fun" in software development. The author references a paper by Bruce Blum, who lists the fun/tedium ratio for different phases of SDLC:
  • "selling the concept" phase - pure problem solving/analysis phase: 100% fun - 0% tedium
  • writing down requirements: 50-50
  • top-level design: 40-60
  • detailed design: 33-67
  • programming: 75-25
  • testing: 33-67
  • maintenance: 0-100


Chapter 9.3 mentions another interesting idea for creating projects with higher ratio of fun - the "incremental consensus" technique by Jerry Weinberg: begin with 2 people who want to work in a mutually pleasing manner and succeed on a project, then grow the team in increments of 1 and only when the candidate gets everyone's acceptance.

Chapter 13 lists ideas on how organizations can become more creative:
  • support open sharing of information
  • support risk-taking behaviors
  • create group diversity
  • create highly participative culture
  • create "slack resources"

Chapter 14 lists traits of creative people.

Chapter 15 shows that computer tools can decrease creativity in problem solving.

Chapter 16 explains creativity paradoxes:
  • The more you know about the problem domain, the less creative your solutions are.
  • To come up with creative solutions, you must know how others solved it.


Chapter 17 shows that software life cycle is just an implementation of a universal problem solving algorithm:
  • Identify a problem.
  • Define the requirements of the problem.
  • Design a solution to the problem.
  • Implement the design.
  • Test the implementation.
  • Use the implemented product.

Summary:
What I am missing in this book is the word "pragmatic". It is a simple, elegant, and "to the point" summary of the approach that Robert L. Glass postulates to use for software development.

Rapid Development by Steve McConnell

Rating: Instruction manual for software projects.

Chapter 7 - Lifecycle Planning - has a surprise for those who think that "Agile" and "SCRUM" are new revolutionary concepts. This book was written in 1996 and the Evolutionary Prototyping, Staged Delivery, Design-to-Schedule, and Evolutionary Delivery processes described there look eerily familiar to us.

There is a very interesting table on page 156: Lifecycle Model Strengths and Weaknesses. The Spiral model is a clear winner.

Chapter 9 - Scheduling - explains what the estimated completion date really is. "Developers typically estimate 20 to 30 percent lower than their actual effort. Merely using their normal estimates puts the chance of completing on time below 50%".

Chapter 11 - Motivation - has interesting insights about developers and managers. For example: "Compared to the general population, developers are much more motivated by possibility of growth, personal life, opportunity for technical supervision, and interpersonal relations with their peers. Developers are much less motivated by status, interpersonal relationships with subordinates, responsibility, and recognition."

Percentage of computer professionals who have a preference for:

  • introverted (I) over extroverted (E): 58%... I = interested in ideas rather than people and things,
  • thinking (T) over feeling (F): 80%... T = logical, objective decisions,
  • judging (J) over perceiving (P): 66%... J = live in a planned, orderly way.

Chapter 43 - Voluntary Overtime - shows in a Machiavellian way how to trick developers into producing more without compensation. It's tricky, but it can be done. Other ways DO NOT work. Involuntary or excessive overtime decreases overall productivity. "Trying to motivate developers can be like trying to push on a rope - you'd be better off pulling on the other end."


Key Lessons:

  • Software development can be optimized for schedule, quality, performance, maintainability, usability, cost. Pick one or make trade-offs.
  • To get software on time you must:
    • not make classic mistakes,
    • follow software development fundamentals,
    • manage risk,
    • use schedule-oriented practices.

Summary:
Rapid Development complements Code Complete. It gives team leads and managers knowledge with which they can deliver software projects on time.

Code Complete 2 by Steve McConnell

Rating: The Bible of Programming. Every developer can learn a few things from it
and have an occasional laugh.

Concepts:
  • heuristics vs algorithms
  • metaphors for making software: 
    • penmanship: writing code, 
    • farming: growing a system, 
    • oyster farming: system accretion, 
    • construction: building software.
  • good practices differ for different kinds of software projects: business systems, mission-critical systems, embedded life-critical systems - page 31
  • typical architectural components: program organization, major classes, data design, business rules, user interface design, resource management, security, performance, scalability, interoperability, internationalization/localization, input/output, error processing, fault tolerance, architectural feasibility, over-engineering, buy vs. build decisions, reuse decisions, change strategy, general architecture quality.
  • technology wave - page 66
  • programming into a language (good) vs programming in a language (bad) - page 68
  • a "wicked" problem - one that can be clearly defined only by attempting to solve at least part of it - page 74
  • accidental and essential difficulties - page 77
  • desirable characteristics of a design: 
    • minimal complexity, 
    • ease of maintenance, 
    • loose coupling, 
    • extensibility, 
    • re-usability, 
    • high fan-in: having a high number of classes that use a given class, 
    • low-to-medium fan-out: having a given class use a low-to-medium number of other classes  (high cohesion), 
    • portability, 
    • leanness: designing the system so that it has no extra parts, 
    • stratification - design the system so you view it at one level without dipping into other levels,
    • standard techniques - page 81
  • design building blocks: 
    • major heuristics: find real-world objects, form consistent abstractions, encapsulate implementation details, inherit - when it simplifies the design, hide secrets, identify areas likely to change, keep coupling loose, look for common design patterns
    • minor heuristics: aim for strong cohesion, build hierarchies, formalize class contracts, assign responsibilities, design for test, avoid failure, choose binding time consciously, make central points of control, consider using brute force, draw a diagram, keep your design modular
  • design practices: iterate, divide and conquer, top-down and bottom-up approaches, experimental prototyping, collaborative design
  • Abstract Data Type (ADT) - page 126
  • semantic encapsulation - page 141
  • Liskov Substitution Principle (LSP) - you shouldn't inherit from a base class unless the derived class truly "is a" more specific version of the base class - page 144
  • "mixins" - classes, usually abstract, meant to be inherited from in multiple inheritance - page 149
  • shallow copies (reference objects) vs deep copies (value objects) - page 152
  • "gold-plating" - creation of functionality that isn't required and that unnecessarily adds complexity - page 154
  • "god class" - a class not to create - page 155
  • types of acceptable cohesion in a routine - page 168:
    • functional - performs one and only one operation - the ideal,
    • sequential - contains operations on shared data that must be performed in a specific order,
    • communicational - operations share data, but are otherwise unrelated,
    • temporal  - contains operations that are done at the same time.
  • types of unacceptable cohesion in a routine - page 170:
    • procedural - operations performed in order matching UI,
    • logical - performs one of contained operations based on an input flag,
    • coincidental - no relationship between operations.
  • defensive programming
  • assertions - "Error handling typically checks for bad input data; assertions check for bugs in the code." - page 191, but "For highly robust code, assert and then handle the error anyway" - page 193
  • preconditions
  • postconditions
  • robustness vs. correctness - page 197
  • barricade - page 203
  • debugging aids - page 205
  • PPP - pseudocode programming process - page 215
  • Principle of Proximity - keep related actions together - page 242
  • window of vulnerability, variable span - average number of statements between variable references, variable live time - max number of statements between references - page 245
  • hybrid coupling - two variables in one - page 256
  • the telephone test - "[...] if you can't read your code to someone over the phone, rename your variables to be more distinctive [...]" - page 283
  • write-time convenience vs. read-time convenience - page 285
  • dog-tag - a field added for error checking - page 326
  • tramp data - data passed to a routine only to be passed to another routine - page 338
  • guard clause - code that exits a routine early if it is not ok to proceed, to avoid deep nesting - page 392
  • safety counter - a counter variable that prevents infinite loops - page 396 and earlier
  • cyclic recursion - A calls B, B calls C, C calls A - page 396
  • table-driven approach - lookup information in a table rather than using logical statements - page 411
  • indexed access tables - page 425
  • stair-step access tables - page 426
  • DeMorgan's Theorems - use to simplify boolean tests - page 436
  • structured programming - you can build any program out of a combination of sequences, selections, and iterations - page 454
  • McCabe's cyclomatic complexity metric - the sum of decision points in a routine - 10+ is possibly too complex - page 458
  • quality gates - page 467
  • collaborative construction - page 480
  • formal inspections - page 485
  • walk-through, code reading, dog-and-pony show - page 492
  • black-box/white-box testing - page 500
  • structured basis testing - page 507
  • data flow testing - page 509
  • equivalence partitioning, error guessing, boundary analysis, compound boundaries, classes of bad/good data- from page 512
  • system perturbers - page 527
  • confessional debugging - page 547
  • brute-force debugging - page 548
  • voodoo programming - page 553
  • psychological distance - page 556
  • code-tuning: loops: unswitching, jamming, unrolling, sentinel values - page 616
  • strength reduction - page 630
  • phased vs incremental integration - page 691
  • top-down vs bottom up integration - page 694
  • integration types: sandwich, risk-oriented, feature-oriented, T-shaped - page 698
  • Fundamental Theorem of Formatting - page 732


Bottom line:

  • "Specifying requirements adequately is a key to project success [...]" page 39
  • "Once you understand that all technical goals in software are secondary to managing complexity, many design considerations become straightforward." - page 79
  • "Design is heuristic. Dogmatic adherence to any single methodology hurts creativity and hurts your programs." - page 123
  • "If a routine has bad cohesion, it's better to put effort into a rewrite to have better cohesion than investing in a pinpoint diagnosis of the problem." - page 169
  • "The name of a routine is an indication of its quality." - page 186
  • Define quality goals - page 469
  • "[...] effective software-quality program must include a combination of techniques [...]" - page 473
  • "[...] inspections quickly brought all the developers up to the level of the best developers [...]" - page 482
  • "The first priority of visual layout is to illuminate the logical organization of the code." - page 775.
  • "Holy Grail of legibility: self-documenting code. [...] In well-written code, comments are the icing on the readability cake." - page 779
  • Good comments: "[...] information that can't be expressed in code, intent comments, and summary comments." - page 788
  • "If you're figuring out code instead of reading it, it's too complicated. If it's hard, it's wrong. Make it simpler." - page 849
  • "A blanket attempt to avoid mistakes is the biggest mistake of all." - page 852


:-) Funny bits:

  • "In programming, if your requirements are contaminated, they contaminate the architecture, and the architecture in turn contaminates construction. This leads to '''grumpy, malnourished programmers''' and radioactive, polluted software that's riddled with defects."
  • "It's as if you were a contractor called to work on a house. Your customer says, "What will it cost to do the work?" You reasonably ask, "What do you want me to do?" Your customer says, "I can't tell you, but how much will it cost?" You '''reasonably''' thank the customer for wasting your time and go home."
  • Comparing productivity of higher and lower level languages: "You save time when you don't need to have '''an awards ceremony''' every time a C statement does what it's supposed to." - page 62
  • "You'd probably want to '''tar and feather''' a teacher who gave you a programming assignment, then changed the assignment as soon as you finished the design, and then changed it again just a s you were to turn in the completed program. But the very process in an everyday reality in professional programming." - page 75
  • "[...] the road to programming hell is paved with global variables [...]" - page 95
  • "A vague, wishy-washy [routine] name is like a politician on the campaign trail. It sounds as if it's saying something, but when you take a hard look, you can't figure out what it means." - page 222
  • "[About memory initialization] Alternatively, Brian Kernighan and Rob Pike suggest using the constant 0xDEADBEEF as a memory filler that's easy to recognize in a debugger [...]" - page 244
  • "You can't give a variable a name the way you give a dog a name - because it's cute or it has a good sound." - page 259
  • The optimum length for a name seems to be somewhere between the lengths of x and maximumNumberOfPointsInModernOlympics." - page 262
  • "It's OK to figure out murder mysteries, but you shouldn't need to figure out code." - page 267
  • "FALSE [...] would be a bad abbreviation for 'Fig and Almond Season'" - page 285
  • "By the time structured programming came and went, the term 'structured' had been applied to every software-development activity, including structured analysis, structured design, and '''structured goofing off'''." - page 454
  • "[...] compilers are dissembling little rascals, [...]" - page 549
  • "Some compilers get so excited after detecting the first error that they become giddy and overconfident; they prattle on with dozens of error messages that don't mean anything." - page 550
  • "Code as if whoever maintains your program is a violent psychopath who knows where you live." - page 777


Interesting observations:

  •  7 +/-2 is a number of discrete items a person can remember while performing other tasks. If a class contains more than about seven data members, consider splitting it into smaller classes. - page 143
  •  "A good way to think of assertions is as executable documentation [...]" - page 191
  •  "[...] code reviews were several times as cost-effective as testing [...]" - page 473



Criticism:

  • The Java Singleton example on page 151 is not correct, because it does not close the class for inheritance
  • The "Avoid classes named after verbs" recommendation on page 155 does not mention the Strategy pattern, where naming your behavior classes after verbs may be desired
  • The Visual Basic example of a centralized exception reporter on page 202 does not follow the rules of defensive programming (no parameter validation) and the law of Demeter ("thisException.TargetSite.Name"). ReportException() may itself throw an exception in some cases.
  • Some abbreviation guidelines on page 282, like "Remove all nonleading vowels", "Keep the most noticable sound in each syllable" make the code difficult to read for non-native English speakers.
  • The concept of coding into a language may be misused to make a C# program look and act like a COBOL program.
  • The author mentions C++, and Java often, but skips C# which has the same features - page 439
  • Writing numeric expressions in number-line order makes them difficult to read: you have to start in the middle of the line and read to the left and right at the same time. It looks good when you draw it, but it is awkward to read - page 440