📜 ⬆️ ⬇️

What can you learn about the candidate for the test task

Some time ago, a wave of articles about job search and job interviews swept through Habra. Employers and job seekers have also spoken many times. But, unfortunately, the topic of the test items was not sufficiently affected.

After all, the test task is not limited to the categories “fulfilled” and “not fulfilled”. Carefully observing the process and studying the final result, you can end up with a lot to say about a person for a single day without working with him. And sometimes, and learn something new.

I bring to your attention a test task, which I have been giving candidates for quite a long time to the candidates in the company where I work:
')
On the screen there is a grid M on N from colored squares. It is necessary to implement the following effect on this grid - by clicking from left to right with speed V, a wave runs through, changing the color of the squares to another (the same for the whole wave). The effect should work for any values ​​of M, N, V. The wave always starts at the left wall. At the same time can go several waves of different colors.
Animation example: http://dl.dropbox.com/u/3601116/wave.swf (click on the flash drive).


I have no doubt that this task will be easily made by all the programmers Habr's visitors.

And I got the following statistics:

  1. As a result, the task took a little more than 20 people.
  2. A couple of people did not do anything.
  3. Half of the remaining (according to my criteria) did not cope with it.
  4. Candidates are clearly divided into very interesting groups.

Think a little about how you would complete this task, and go under the cat, where I will tell you more about everything.

Disclaimer


In this article, I do not touch on ethics, complexity and the need for test tasks as such - I understand that everyone here has a different opinion on this topic. I will be glad to hear it in the comments as a supplement to the material, but I do not welcome the incitement of any holivors.

The task


A few words about the task. I didn’t care about what a person realizes it with, but two conditions were immediately discussed:


Groups


As I said, the candidates were divided into distinct (intersecting) groups, which will be discussed below.

A person entering a particular group can already tell a lot about him, both from the good and from the bad side. And this in no way means that the cross is immediately placed on the person. Being in a group only sets the topics for further communication, to find out whether the candidate is suitable for me and whether we are suitable for him.

Schaz everything will be! I'll do it tomorrow!

Of course, several people eagerly rushed into battle ... but they didn’t do anything. I immediately scored for those who disappeared immediately, but a couple of people persistently fed breakfast, and then eventually all the same merged somewhere.

Conclusion: I will know with whom you should not work either in the office or on freelancing. It was quite possible to write a letter and refuse further communication in order not to waste either my time or the candidate's time. As practice shows, the market is actually small.

It's simple, you need to do this and here

To my surprise, I stumbled upon people who had long (and volumetric) explained to me how to do this task, how to build architecture, how to optimize rendering. Technical terms were poured in and knowledge of win32 api was put on display. In the end, I could not stand it and spoke directly, they say, great, now go and do this task.

And you know what? .. They all had difficulties with him.

Conclusion: in practice, the theory and practice differ greatly. Often people create around themselves a thin shell of professionalism, behind which lies amateurish amateurism. It is good to understand and use it in time.

We were taught at the university with a second year

IMPERATIVE was written in huge yellow letters on the door of this group. As it is supposed to solve the problem from the second year of the university, the code included a matrix, a certain number of variables with the beginnings and ends of the waves, as well as variables i, j, k, m, n and others in large quantities.

The code was impossible to understand, and in most cases it worked with jambs and / or slowly.

So, i from zero to the point of wave propagation, j and k are symmetrical in both directions ... and this is the boundary condition ... so, and this is what m went now back to the border of the current color ... so, and this is why and how does it work ?? ! argh! fuck it!

The dialogue with the candidate was delayed by a dozen letters, in which each new one began with the words “corrected everything, now it works.” I felt like a computer science teacher. Needless to say, no one has completed the project to the end of this group. So much for Russian education.

Conclusion: Unfortunately, in the overheated IT market, most of the candidates have very mediocre knowledge and want just a lot of money from BMW. The test task (even in fact done) can tell a lot about how a person is used to writing code and his approach to solving algorithmic problems.

Add (new wave ());

Basically, the people, of course, immediately saw in the formulation that the task was divided into classes and elementary architecture — who controls whom. We create waves, and they already let them do something there.

At the same time, they also managed to manifest the wonders of the PLO of the Brain. But, nevertheless, the majority coped with the task.

Somewhere there were a couple of people who tried very hard not to get into the previous group, but still, they could not stand in some places and in the textbook OOP code grossly violated the encapsulation.

Conclusion: A good code structured according to the canons of OOP is a sign of an experienced developer who can competently split the task into modules and build an application from them. It should be attentive to the signs of overengineering and violation of abstractions.

The specificity of my work lies in the tight deadlines, in which there is no way you can allow yourself to be removed deep in the abstraction of architecture. And at the same time, it is necessary to adhere to the rules and not to scatter the same rake along the way.

I write everything from scratch

The task was not specifically set the framework for the use of languages, frameworks and libraries. But people from this group persistently chose a difficult solution path and wrote infrastructure for themselves (for example, displaying a mesh screen in 3d space). In the end, all coped with the task.

Conclusion: At first glance, the candidates had sufficient knowledge to implement the solution of the problem from scratch on their favorite tool and not get lost in the algorithm. But immediately there appeared a suspicion of “Not Invented Here Mentality” and doubts that a person would be able to effectively use already existing practices and third-party libraries.

I'm not looking for easy ways!

Strongly intersecting with the previous one, this group includes all those who were already close to creating a framework for developing applications with running color waves in a vacuum: waves moving in any direction, each in its own stream, drawing a picture unmanaged code from a managed application, and other monstrous solutions.

The person tried to show what can write multi-threaded high-load systems? On such a test task? ..

“Why did you do it like this?” After all, it could be done much easier.
- What for? I can do that!

Conclusion: It is worth thinking. A person is most likely an expert in his business and has extensive knowledge, but can he solve specific tasks quickly without creating a framework for solving such problems? Do you have a framework for which you can plant it?

I'm redrawing everything / I'm not redrawing everything

Many immediately realized that the algorithm of the motion of superimposed waves from left to right can greatly optimize the drawing. But, sadly enough, many of these have dug their own graves, entangled in their own code.

But there were a couple of interesting moments. For example, three or four, in one way or another, instead of adding a moving wave in terms of OOP, considered when and in what color the cell should be repainted. In essence, the “addition” of a wave only changed the existing temporary color switching program.

Conclusion: On the one hand, I absolutely didn’t care about an extra redraw if the application worked correctly and quickly. On the other hand, the person understood that everything can be done more optimally. But, did he first make a non-optimal working option, and only then began to optimize it? Often, no. And it makes you wonder.

I don't care what it looks like if it compiles

Several people sent completed tasks with frank graphical jambs. Even without reading the code, it was possible to understand that there is something wrong inside. It was impossible not to notice them, so the conclusion suggested itself: a man doesn't care.

Almost all agreed to solve problems with some speed or other, but one comrade surprised me. You see, he knows very well how to fix the jambs and the speed of rendering, but he believes that he will not spend an hour for a test task.

Conclusion: It is very important that the person closes the task only at the moment when he is sure that the work is done. Passing an application with an obvious jamb for checking (in the hope that it will not be noticed?), He spends not only his time, but also the time of the verifier. And a friend who knows how to solve a problem, but will not solve it, because ... he will behave in the same way at work.

I do not care how they will run it

Several times I had difficulty running the application:


The code was clear, but it was not possible to see the result. One candidate magically fell off at this stage ...

Yes, I myself wrote at the beginning of the article that I don’t care what the code was written on, but still it is worth to appreciate my time and attach, for example, a compiled file, a couple of lines of what and how best to open ... send solid projects, not a set of source files , eventually. Unless, of course, your task is not to write everything on Brainfuck and make fun of me (as suggested here below). But, you should understand that I can not appreciate such a move.


Conclusion: Also some unpleasant pofigistic attitude to the examiner. As a result, a lot of time was spent on additional correspondence.

Summary


Each candidate had a unique approach to solving a problem in one way or another. After studying it, you could immediately say a lot about a person as a developer:

  1. What is his experience and in what projects.
  2. As far as he thinks abstractly.
  3. Can it implement a simple algorithm?
  4. Can he himself clearly close the tasks.

Being in one group or another does not in itself mean that a person is bad or good. I have one need, you have another. I’m looking for some qualities and I’m wary at the sight of others, you probably have some of your own selection criteria.

Some decisions made me lose faith in humanity, from others the eyes became square, others seemed more or less interesting and unusual. You read the code, and as if you get into the head of its author - how he approached the problem, how he built the algorithm, and what difficulties he came across. After each solution I sent, I started to look at the whole problem differently.

Of course, the most popular was the OOP approach with creating instances of the Wave class, updating it by timer and cleaning when a certain criterion is reached. But, at the same time, people in different ways approached the spread of the wave and redrawing the grid.

I'm glad that some of the sources allowed me to learn something myself!

Decision


* Paragraph changed

The story would be incomplete if I had not put here my canonically correct decision.

In fact, it was not originally there. Only by the end of the second ten “tested works” I began to think, and how would I solve this problem ... One feature of all the solutions was interesting - all ... absolutely everyone looked at the problem, following the letter to the letter of its description at the beginning of the post: the grid, according to it a wave runs ...

If we abstract from the wave and to some extent from the grid, look at the problem from the other side, you can see that this effect is nothing but a cellular automaton on squares with some rules. But what?

Indeed, let a cell take an integer positive value from 0 to infinity. Each tick cell takes the maximum value of its four neighbors. It is not difficult to see that by setting the value of one of the left border cells to N + 1 (where N is the maximum value of the cells on the grid), we get exactly the wave propagation effect we need.

for (var i:uint = 1; i < Width-1; i++) {
	for (var j:uint = 1; j < Height-1; j++) {
		buffer.setPixel(i, j, Math.max(bmp.getPixel(i, j), bmp.getPixel(i-1, j), bmp.getPixel(i, j-1), bmp.getPixel(i, j+1)));
	}
}


, . , (https://gist.github.com/valyard/6084814):

var Size:uint = 10;
var Width:uint = int(stage.stageWidth/Size);
var Height:uint = int(stage.stageHeight/Size);
 
var bmp:BitmapData = new BitmapData(Width, Height, false, 0x000000);
var buffer:BitmapData = new BitmapData(Width, Height, false, 0x000000);
var display:BitmapData = new BitmapData(Width*Size, Height*Size, false);
var zeroPoint:Point = new Point(0, 0);  
var colors:Array = [0xFFFFFF];
 
addChild(new Bitmap(display));
 
stage.addEventListener(MouseEvent.CLICK, clickHandler);
stage.addEventListener(Event.ENTER_FRAME, frameHandler);
 
function clickHandler(e:MouseEvent):void {
	addWave((e.localY % display.height)/Size);
}
 
function addWave(position:uint):void {
	if (position == 0) position = 1
	else if (position >= Height-1) position = Height-2;
	
	bmp.setPixel(1, position, colors.length);
	colors.push(0xFF000000 + int(Math.random()*0xFFFFFF));
}
 
function frameHandler(e:Event):void {
	for (var i:uint = 1; i < Width-1; i++) {
		for (var j:uint = 1; j < Height-1; j++) {
			buffer.setPixel(i, j, Math.max(bmp.getPixel(i, j), bmp.getPixel(i-1, j), bmp.getPixel(i, j-1), bmp.getPixel(i, j+1)));
		}
	}
	bmp.copyPixels(buffer, buffer.rect, zeroPoint);
	
	var rect:Rectangle = new Rectangle(0, 0, Size, Size);
	for (i = 0; i < Width; i++) {
		for (j = 0; j < Height; j++) {
			rect.x = i*Size;
			rect.y = j*Size;
			display.fillRect(rect, colors[bmp.getPixel(i,j)]);
		}
	}
}


, . , .

Update: , , . , , . , . , .


, . - , , , , … … , !

P.S. .

Source: https://habr.com/ru/post/187894/


All Articles