There was a period in my life when I was just starting programming. I then thought: “Programming is so simple ... Why do people specifically go to learn this?”, But with experience and education, it was understood that programming is difficult.
Either programming is easy, or I just don't understand anything. MemeGenerator.net')
Evaluating your success has always been important to me, because ultimately it doesn’t matter what others think, it’s important what you think about yourself. Analyzing my experience, I reflected on strengths and weaknesses, education, practice and personal growth. This process allowed me to learn new things and think about what it means to be a programmer.
Coding, programming, and keystrokes
Most of my time at my first technology work, I dedicated HTML, CSS, and JavaScript. I made the elements behave one way or another or weave visual plots with their help. At that time I did not think of myself as a programmer, and didn’t want to become one then. Only some time later, when I understood how to do other things in NodeJS, PHP and MySQL, I began to consider myself as such. Hindering in my head the thoughts of all the great things that exist in programming, I got my first job with the “programmer” name “Software Development Engineer”, within which I daily and actively solved various tasks.
“Experience has taught me that all this time I really only furiously knocked and hit the keys, and did not program”
Programming requires a thoughtful approach and an understanding of the various types of data, structures, and technologies for the maintenance of which programming languages ​​were invented. The difference is mainly in the choice of the process that is used in the work on specific tasks. My focus was not on data types or algorithms, design patterns, performance, or anything else related to the quality of code and applications. Instead, the emphasis was placed on the working mechanism and its aesthetic component, which often led to the birth of huge indomitable monsters. This was accompanied by feverish testing of the output data until the result began to be at least a bit like a feature. All this gave me some feeling that I was doing programming, but my approach could not be called pragmatic or thoughtful.
Thinking about data
Data structures are the area through which I realized how much I lack education. The basic idea is that you have different ways to store, call, sort, and search through data. When I first started programming, I never thought about the various tasks of working with data and performance when working with certain types of data. Very often, by default I used arrays (including hashes, json, dictionaries, and other terms for data sets with access by field names) whenever I wanted to save a set, sort it, or process it in a loop.
The sets, stacks, and queues seemed very interesting from the point of view of computer science, but when it came to their practice in Ruby, my enthusiasm diminished. In my understanding, stacks and queues are the same. They allow you to get information from different ends of a data set. The only difference between the queues is that in them you can only get the object added first. Acquainted with these concepts, I imagined them as placing objects into a processing list, in theory, allowing to reduce the load and send non-urgent tasks for background execution. However, practical application in a high-level programming language, such as Ruby, looks practically pointless, since the whole process is essentially pushing elements into an array or changing positions in it.
For example, you can implement a stack in Ruby using this simple code:
class Stack # init stack def initialize @set = Array.new() end # put a new item at the end of the stack def push(x) @set.push x end # get the last item in the stack def grab @set.pop end # is the set empty true false bool def empty? @set.empty? end end # implemented stack s = Stack.new s.push 'a' s.push 'b' s.push 'c' s.inspect #<Stack:0x48b66454 @set=["a", "b", "c"]> puts s.grab # "c" puts s.grab # "b" puts s.grab # "a" s.grab.inspect # nil
With queues, everything is also roughly in terms of the types of data being created. In addition, Ruby has
its own queue
class :
# ruby Queue Class q = Queue.new q << 'a' q << 'b' # Tests Examples using Queue puts q.length # prints 2 puts q.pop # prints a puts q.length # prints 1 puts q.pop # prints b puts q.length #prints 0
Despite its simplicity, in fact, we have a regular array. It certainly has its own beauty. In general, I can imagine their potential use in command line scripts, but otherwise it’s hard for me to figure out where else they can be used.
Binary search trees cause my genuine interest because of the optimization of search time, which they allow to achieve and the speed of sample retrieval. In practice, I often easily extracted data from arrays, but as the size of an array increases, searching it starts to take a lot of time. This is where the binary search trees come into play, described in this awesome Harvard
video . And although I have not had a chance to use them in practice, I really want to try it in a real project to compare this algorithm with native methods of working with arrays in Ruby and see how quickly binary trees will work in comparison with regular arrays or hashes. In the course of studying them and trying to find ways and scenarios for their use, I found these interesting articles:
Convenience support
My first web application was written simply out of hand in terms of maintainability. I didn’t use any design requirements at all, design patterns, methods for defining methods, namespaces, objects or models. If I had to go back to the code to fix the bugs (which I’m sure are there), it would probably be easier to rewrite everything from scratch, rather than trying to determine the method causing the bug.
Bad design creates spaghetti code. Spaghetti code begets sufferingOne of the problems that I had difficulty solving was nested conditional statements and cycles. In such cycles, there is often a whole carriage of if-statements and checks, but this problem actually follows from another - a misunderstanding of how to properly organize and separate the various parts of the program. I tried to do everything in large methods and did not pay attention to the individual components that could be reused or created as modules that extend the functionality of all objects or methods. Below is a real piece of the program, shortened and modified to save space.
print " <h3> Display Weekdays: </h3> ";
Of course, I'm not going to shift the blame on anyone else. This code was written by me, and I am responsible for it, but everything could be better, if I had a mentor, the ability to send a code for review or pull-requests. Today I am ashamed to look at this code, but there is a positive thing, because it shows how much I grew up as a developer. Mention should also be made of the freedoms and limitations that I encountered. For this project, I was forced to work on the LAMP stack, and this question was not subject to discussion. At the same time, this was the only restriction. I did not need to use design patterns or statistical analyzers and follow any style guides or policies on the format of the code. This creates a system in which the developer is free to do everything that he sees fit, but ignorance about the longevity of applications and bug fixes can seriously affect the final result.
Over time, I began to really appreciate text editors and the time savings they provide, analyzing potential errors in the code as it is written. But besides that, I also began to appreciate other smaller programming-related details. A well-written code base that follows documentation standards, clear requirements and style guidelines is also read fluently and simply as an e-mail or Internet article (provided that the sometimes used programming language itself contributes to this). In general, I also realized that I really like many of the principles described in the book
Clean Code A Handbook of Agile Software Craftsmanship by Robert Martin and other authors.
Development through testing
The benefits of developing through testing, in my opinion, speak for themselves, but I understand that not everyone agrees that testing has any value for the code base. I will not argue about the validity of testing, but I want to share with you how she helped me. Writing integration and unit tests for the code even before its actual creation gave me a lot of help. This approach allowed me to write cleaner code, to do it more efficiently, and to cope with tasks, the solution of which makes it difficult for me.
Writing cleaner and more efficient code is at the intersection of many other good programming practices. Development through testing, in particular, helped me improve readability, performance, and speed of writing. I found that I learned how to write code that does not need to be redesigned (or needs much less) before being sent to production or version control systems. Testing helped me not only reduce the number of bugs, but also the amount of time I spend on tracking and fixing them. I found that while I was fixing a bug, I could take the expected input or output, write the appropriate test, and work to ensure that this and all other tests began to give the correct result. This allows you to eliminate the bug, and the code continues to do what it is supposed to do.
Developing through testing helps me streamline thoughts before writing methods or objects. In cases of writing more complex features, it helps me to break it down into the minimum set of elements that is necessary for its correct operation. Often, it reminds me of the usefulness of writing pseudo-code, since current tests sooner or later lose their usefulness and need changes as the code develops. However, in general, borderline cases are borderline cases: it is much more difficult to think through them beforehand during code creation. In the end, I believe that developing through testing helps me as a programmer to grow.
