Показаны сообщения с ярлыком study. Показать все сообщения
Показаны сообщения с ярлыком study. Показать все сообщения

пятница, 7 августа 2020 г.

How to handle a programming problem


A couple students whom I mentor through a software development course recently asked me for a generic advice on a way to approach a relatively large software development - something that would help them know where and how to start producing a solution. The question definitely provoked several pretty deep discussions. Since I do expect other students to seek advice of a similar kind I decided to devote a bit more time to the framing my advice.

While contemplating and discussing the topic I came up with a number of points that depict the approach that I use to build software. Sometimes I would follow this process to the point, in other cases I just adhere to the general line of thinking that it suggests - it definitely depends on the kind and size of a particular project. Thus, even though I present the approach as a sequence of steps, it is most reasonable to treat it as a description of a way of thinking about a programming problem.

Note that it so happened that I faced the question soon after going back to the Code Complete book to check a couple chapters. Moreover, I was reading How to Solve It by George Polya roughly at the same time. Because both of these have a lot to do with the topic at hand, the post definitely builds on the ideas found there. I absolutely recommend both of these books in case you didn't give these a try yet.

So, you find yourself with the task of producing a piece of software that would solve a particular issue. What should you do?
  1. First and foremost, state your problem in writing - what are you trying to solve?
  2. What requirements should the solution satisfy? Jot every one of these down as well.
  3. Imagine the final solution, state in writing what the thing that you are about to build will look like. Focus on the general shape of the final result here. See how it will solve the problem and meet the requirements.
  4. Think over the data model. Decide what kinds of data you will be handling, how to structure it better, where it comes from and where it should go. Imagine how the information is split into tables and collections, spot the relations between them. Consider which bits you need to store and how. Do this even if you don't have any kind of database - maybe building only a frontend application - data is something that you work with in any software and it definitely plays a great role in shaping the solution. Write all of this down.
  5. Decompose your future system or program based on what you have understood so far - think over how you can split the problem and the solution into pieces. Depending on the scale of the task you may be thinking on the level of services, modules or classes and functions here. The larger the problem - the larger should be the size of units considered on this design stage.
  6. In this process follow the breadth-first approach - e.g. don't go into designing functions before you produce an overview on the level of modules. List the large-scale units first, state their purpose clearly and only once this is done permit yourself to descend to the next level of detail. Notice when your start jumping between different levels of design - like thinking of modules, then functions, then modules again. If this happens stop and pull yourself back to the highest level that still needs clarifying.
  7. Don't overdesign and keep moving. Most of the technical design will happen while you're coding. Your key goal at the moment is to draw yourself a clear image of the whole solution, its components and relations that govern them and to see how you will meet every bit of requirements. Design can consume infinite time, so don't let yourself get lost in it - details will come.
  8. After facing your components think over your past experience - each component poses a smaller problem to solve and many of these smaller problems you may have solved in the past. If so, check which bits of previous projects you can use now - this may mean anything from pulling in a dozen existing files to just reviewing how you approached a particular issue a couple months ago.
  9. Throughout all these stages use pencil, draw figures, sketch stuff, write things down - it helps you think. Once you have started producing a diagram, your mind will follow. Draw how the system or its particular component is decomposed, outline relations between the pieces, sketch the data flow, chart user actions sequence.
  10. Devise a plan. Decide in which order you will build your components. Write that down (in any form or medium) - that will help you see and maintain progress, especially with longer projects
  11. Pick the first component on the list. Jot down the steps to build it. Think how to test it, list the functions to implement, decide on the order, add checkboxes. If you don't know how to pick the starting point, pick any single one of them. At this stage it’s most important just to start the job, so start anywhere. Even if you choose a wrong initial task, you will soon be able to see and correct that.
  12. Go and start writing the code. The first lines may go hard, but with all the preparatory work you should be able to break through them and the rest will follow easily.
  13. Don't try to write perfect code from scratch - start dirty. Starting is a challenge by itself, so simplify the task and relax the requirements. It is much easier to produce a dirty solution and clean it once you see it working. Just don't forget to always clean the mess.
  14. Write tests as you go to stay confident in the state of your code. Confidence does matter a lot here and the lack of it may slow you down significantly.
  15. Iterate. Pick small tasks, complete them, polish the solution, celebrate, step back to take a look at your design and plan, repeat.
  16. When you face challenges and are not sure where to go from there, take a pencil and think. State the problem that you're trying to solve, write out the required characteristics of the solution, draw, see it and then implement it.
  17. Yes, look for what others have to say about your problem - stackoverflow, github and google are your friends. Don’t just grab any code that you find on the web though - take time to understand what it does, why it works and what kind of new issues it may throw at you.
  18. When all else fails, go away for some time - take a walk, wash the dishes, smoke a pipe, use your hammock time. Let your brain wander away. Most times you will come back with new ideas. In the worst case you will get some rest and have more energy to continue attacking the problem.
And finally, if there are no more tasks to do, everything is polished and you feel happy about the result, celebrate the success, reward yourself, think over the lessons to learn from this project and go look for the next issue to solve. If you can program, there is an infinite number of problems waiting for you!

пятница, 5 сентября 2014 г.

There Is No Arcane Knowledge

When starting to learn things about the world of computer programming I was sure that there is some piece of knowledge that I had to discover to become an actual programmer. My perception was that there are facts, ideas and thoughts, which were not available to me at the moment due to some reasons, but that once I learn them, it will be the moment when a programmer is born.

In childhood I used to think this way about all the things that people do: for example, I could have learnt some elementary physics in school and thought that while it looks and feels like physics, that’s certainly not something actual scientists work with. I understood that to learn what real physicists do I should go to a university, spend several years and then one day, somewhere around the fourth or fifth year they will raise the curtains and show me what is the science about and how it is totally different from what I imagined.

I don’t know whether such mindset is a common thing for children and youngsters, but it is certainly not a very good thing for students. My confidence that really important knowledge will be opened to me only at some distant point in future was a serious blocker for learning. The problem here is that when you think that the things taught to you are not that important – at least not as vital as something else that you are supposed to face later – you are not going to learn much. Additionally, having to study something useless and feeling obliged to wait for important portions of knowledge leads to frustration, at best. What’s more, the feeling that I will be taught crucial stuff in future made me believe that the only thing that I must do is waiting, while what a student (and as you gradually discover, everyone) has to do is actually learning – that is trying to do things, asking questions and looking for answers everywhere their mind can reach.

This way, it turns out that the most valuable thing that I learnt in the university, while trying to become a programmer, is that there is no arcane knowledge, which someone is concealing from me. In other words, there isn’t a piece of any particular science or profession that one has to wait to learn and that, when finally discovered, turns the student into a professional, be it a programmer or a physicist. Instead, there are lots of details behind each and every subject and each of them might seem lacking significance, not important or even irrelevant at some moments. However, the truth is that one has to study as many of these details as possible to get a feeling and to draw some unifying concepts from the experience, which means understanding what one is learning.

Once I have come to appreciate this obvious idea the game has changed and it felt like lots of doors opened, letting me learn whichever subject I found worthy. It suddenly appeared to me that the only blocker to learning new ‘real’ stuff is the limited time that one can devote to it – apart from that you can go anywhere and study whatever you wish. A good finding, ain’t it?

The nasty part is that I still sometimes have to remind myself that there is no knowledge that someone is trying to hide from me, preventing me from being a better programmer, advancing from a junior to a senior position and so on. As before, I sometimes find myself thinking that one day I will learn the last piece required to be a great programmer and will finally turn into one, although I have already got used to telling myself that becoming a better programmer is not about studying a certain amount of required things. I will keep facing the idea that something is not available to me yet, but, unlike with my first years at the university, now I know that the reason is not that the knowledge is hidden, but that I didn't try the right things and didn’t ask the right questions yet. Hence, I should keep asking new ones and looking for answers to them, because that’s the only way to learn something new. What’s even more important, this process of searching for answers and bringing them to the world is what delivers me the experience and being a professional is more about the experience than anything else.

This said, eager to become a great software developer, instead of waiting for someone to teach me a magic trick or two I will better sketch some design diagrams and put together a bit of code – that seems to be the only reasonable way to achieve my goals.


пятница, 7 февраля 2014 г.

Learning: MOOCs

I first attempted to do MOOCs when the whole thing started with Andrew Ng’s ‘Machine Learning’ and Sebastian Thrun’s ‘Introduction to AI’ back in 2011. For sure, both the ‘Machine Learning’ that I chose to take then and the courses, which followed, impacted my life significantly not only allowing me to explore loads of interesting stuff, but also enhancing my study at the university and to some extent forming the scope of my interests. This made me think a lot about the new phenomena of MOOCs and how they fit into our life and the world of education.

суббота, 2 марта 2013 г.

Tutorials Are Not That Bad

From the time when I started to study programming in earnest I somehow disdained tutorials of any kind. There are dozens of them in the world of programming as well as in any other field involving operations performed by means of a personal computer. These tutorials composed of exercises or tasks, which end up being long lists of "go-there-type-this-click-that"s, sometimes interleaved with descriptions of "note-how-the-thing-changes" kind jump at you whenever you type a query involving a name of some technology or tool in Google. Moreover, almost every book dealing with some technology - a programming language, for instance, - contains such exercises. Maybe, it is even safe to say that the more exercises a book of this kind contains the better it is, so I don't state that all tutorials are useless and hardly deserve any attention and I am not even going to discuss the wide range of their quality. What I say is basically that during several years of study I used to think that an exercise inviting me to reproduce its author's actions is not worth the effort.
 
Actually, most of the tutorials, which I came across while exploring various languages and techniques, were very helpful and provided me with valuable insights, thus leaving me no reasons to lament the time spent. Furthermore, I really appreciate the work of people who produce such things just to make their knowledge and expertise accessible to others. Still, I had a reason or an excuse - the latter sounds closer to reality - to avoid tutorials when pursuing my learning goals. My explanation is as plain as possible: I merely used to believe that trying to apply a thing that is being studied to your own problems or to compose such a problem yourself for the purpose of learning and attempt to deal with it is a much more efficient approach, because it leaves a lot of room to creativity. At the same time I doubted that dumbly following the track of a tutorial can be that helpful and educating. I don't reject the idea that creativity is a rich source of both skills and knowledge, although now I barely think that the low level of creativity inherent to the process of doing most tutorials makes them bad equipment for learning.
 

Indeed, it is easy to spot a flaw in my reasoning about the educational value of tutorials. Above I have stated that following a track of an exercise dumbly wont teach you much - chances are high that this particular claim is correct. What is false is my belief that the only way to do tutorials is the stupid one, because obviously one can thoroughly inspect every step of the tutorial they struggle with and think over each action that they perform. Such an approach, even though it is guided, turns out to be quite intelligent and efficient. Moreover it seems to me that it is very difficult to do tutorials dumbly - even when I begin an exercise merely following the instructions in it, sooner or latter I find myself noting interesting features and how-to's highlighted by the author and imagining how I could use the tricks in my own solutions. So it's hard for me to accept the fact that I used to yell that tutorials are not proper learning tools.
 
It must have been my eagerness to do my own stuff, to invent things that made me reject other's expertise in the form of tutorials, but there are too many obvious benefits offered by such exercises to ignore them. First of all, their authors try hard to make one's first steps in a field as easy and as efficient as possible, so they tend to focus on the key aspects and to draw one's attention to the most important things of the technology or the tool under study. Therefore a tutorial usually provides one with understanding of the basics underlying all other matters that one is going to deal with. This is notably important whenever you explore something quite complex, incorporating dozens of features and cluttered with details, the purpose of which is hardly understandable from the first glance. Such focusing on the basics, that is delivered by tutorials and saves one from being totally overwhelmed by complexity, is made possible solely by the vast experience of their creators. Beside this, there is one more thing that an experienced teacher can give you through pages of a tutorial, and it has to do with creativity. The problem is that creativity has a dark side - the side that leads one to an invention of complex solutions to simple problems, which were, in fact, solved long ago. Unnecessary complexity of this kind is produced in huge quantities by those who study new fields and, although frequently the students learn the right way to achieve their goals later, sometimes these beasts survive in the minds for quite a long time so that later they can creep, for example, into production code. While I strongly appreciate creativity and acknowledge that even inventing a bicycle once more can be educating and worthy, I still think that when one starts to learn something new, it may be better for them to be shielded from such things by the experience of those who know the proper ways.
 
An interesting thing that I have noticed about doing tutorials while exploring SQL Server Analysis Services with the help of one is that the closer I follow the instructions in the exercise, the more it gives my. I mean that when I carefully inspect each statement that the author makes - even when some points are repeated - I end up with much better understanding, than in case I leap over instructions that seem obvious or too dull to me. Definitely, this has to do with the fact that when I skip something I risk missing minor aspects that turn out to be quite important, and this leads to holes in my mental models. These gaps, in turn, tend to produce mistakes later, but may be hard to spot at the same time. On the other hand, when deliberately examining each sentence in an exercise I focus not on achieving a goal itself, but on learning a good way to achieve it. This frees me from pressure - particularly, from the desire to complete a task as fast as possible and to leap to another problem - and allows me to keep a comfortable pace, stopping whenever I need to explore some aspect more thoroughly or think about a question. Surprisingly, learning how to achieve a goal and achieving a goal are not the same activities.
 
This said, my takeaway from the last tutorial that I have done are not only new skills and knowledge, but the obvious idea that one should not ignore other's experience merely for the sake of doing their own things and producing their own results. Experts always have a lot to say to us - newcomers - and the insights provided by their instructions may be much more valuable than the product of one's creative attempts to master something from scratch. Moreover, such intelligent and wise instructions can even spur a lot of creativity in students because they tend to provoke interesting problems and make one look for the solutions. In the end, you always learn something through facing questions and answering them - tutorials just encourage you to ask the right ones.
 

пятница, 20 июля 2012 г.

Learning to Program

About a year ago I took part in a vivid discussion of the best choice of the first programming language to study. The discussion didn't lead to any consensus thus making me think a lot about the question itself as well as remember the path along which I moved through the land of the programming craft.

вторник, 19 июня 2012 г.

A Justification for Excellent Marks


Being a fifth year student these days I am experiencing my tenth set of exams in university (oh, that's an anniversary!) As some students do I become tired and nervous when a semester draws to a close and consequently to exams - this particular semester is not an exception of any kind. These feelings usually are not caused by intensive studying during the term - instead these tend to be produced by insufficient studying. Moreover the lack of confidence is intensified by the simple fact that your knowledge and skills are to be condensed into a set of raw numbers or other symbols - your marks. 

I suppose that such state of affairs feels familiar to many students and I believe that some of them have faced an idea that the marks are frequently irrelevant as well. Saying 'irrelevant' I mean that marks do not reflect the level of student's knowledge and skills - the notion is evident considering the fact that generally it is too difficult to accurately assess the person's skills as well as knowledge by the means of a single examination and, besides that, such an assessment - even if it is accurate enough - can be much harder to map to the domain of numbers or symbols like A and D - the appearence of marks doesn't matter. This idea looks as obvious as safe, although some of it's derivatives turn out to be dangerous - it is very easy to decide not to perform any active preparation for exams if one believes that marks don't bear any meaning. Really, what can make you fight for treasures if you know these cost hardly anything?

Another problem that I see discouraging students from active studying in the end of a semester is seeming futility of some courses. It strikes hardly in most Russian universities where curriculum is fixed - that is the speciality you choose when enrolling or after the first year of study determines to the extent of 90% the set of courses which you will study. Such a system somehow simplifies student's life, but it also has significant drawbacks  - one of these is the possible and rather common failure to assure students that they actually need to study some particular discipline. This hardly helps students' training - particularly it fails to make them actively and properly study for exams. These arguments against preparation for exams may sound sensible - nevertheles I will try to partially overcome at least one of them - namely the idea that marks don't reflect the things they are supposed to reflect. 

Let us put the question "Should we actively prepare for exams?" aside for a moment and try to understand why don't marks reflect the level of student's knowledge. As I have said it may be rather difficult to evalueate the level of knowledge via an examination. These difficulties are generally caused by the nature of examinations - I mean the examinations that usually face. Commonly the person who tests you tries to evaluate your skills by analyzing your response to his or her questions. Moreover, examiner usually pays attention not only to the correctness of your answers but also to their completness as well as to your behaviour. Answering questions correctly and completely may require remembering a lot of things while making a proper impression on examiner is possible if you feel - or, at least, look - confident. I've already mentioned the possibility of significant problems with confidence during exams. As for remembering lots of details relevant to any particular course, I truly believe that such a thing is not of any importance if we speak of education and skills obtained through it. Moreover, the more we move towards the age of higly available learning and reference materials (or are we already there?) - the less inportant becomes one's ability to remember numerous low-level details. Here is a simple example: some programming language tutors (not very good ones usually) do prompt students to remember various very-low-level syntax features of the language being learnt, while from my point of view it is much more important to explain students the overall capabilities of the language and the key paradigms it is based upon. At the same time remebering low-level stuff seems to me not important - it will be developed through writing many programs - not through learning the things by heart. This idea becomes quite vivid when we speak of a language with complex syntax - say C++. I don't actually remember all the low-level details of this particular language, but it doesn't prevent me from writing programs in it because I usually need hardly a couple minutes to consult language reference available online about any particular detail that I need to use. Such an example of examiner's requirements may seem exaggerated but I do occasionally face something like this and encounters of this kind don't encourage me to study harder for exams - in fact these don't motivate to anything good at all.

From the other side the requirement to remember huge amount of non-important details is frequently delusive. The reason for this is that right-minded and experienced examiners usually ask questions that do not require all the irrelevant things like remembering low-level details - instead they know the questions that allow them to more or less accurately assess whether or not a particular student understands and feels the subject. So their questions prompt students just to combine good reasoning with their conceptual knowledge of the course subject. I aknowledge the fact that not all examiners behave like this, but I do hope that most teachers that one faces during his or her study do have preoper objectives and therefore perform examinations in a good way.

It turns out that thinking of your examiners as of the good ones is quite a good and helpful attitude because, besides the fact that it is the right way to think of other people, it also helps you switch the process of preparation for exams from attempts to memorize lots of facts to the study intended to develop deep understanding of the key concepts, problems, techniques and other high-level stuff that is truly relevant to the subject. However, even in case you believe that the person who performs examination is a dumb monster requiring only absolutely irrelevant things from you, the situation is not as bad as it may seem from the first glance. Firstly, it is common to have wrong impression about the examiner and secondly, even if you are not mistaken, the preapration for exam won't do any harm to you (except for consuming your energy, of course) - instead it will still help you dive deeply into the matter of the course and hopefully get out of there possessing really good understanding of the stuff. In fact, if one meets the need to memorize lots of details, one will firstly try to understand the forces that produce these details and the connections between them - that is, unwilling to remember many irrelevant things, one's mind will attempt to understand the relevant ones.

So the intensive preparation for exams seems to be worthwhile. That's why, while I still consider marks non-reflective of one's knowledge and skills, after posting this entry I am going to get back to studying for my next examination. To be honest, I should note that, despite my beliefs, I am still quite eager to get good ones - sometimes the contradiction feels confusing. However, there are at least two obvious ways to make marks meaningful: either do nothing, or study hard.