A painting representing the wisdom of the universe via a flowering tree and a dove

4 Tips to Help Beginner Programmers

For this post, I am as­sum­ing you al­ready have some pro­gram­ming skills, but feel stuck. There is a lot of stuff you could po­ten­tially learn. Yet, this di­ver­sity of op­tions makes de­ci­sion mak­ing dif­fi­cult. What will give you the best bang for your buck, so to speak? Well, I am go­ing to try giv­ing some ad­vice here. Some of this ad­vice will be ob­vi­ous, but some­times we need to re­peat­edly hear com­mon sense truths for them to sink into our psy­che. Thus, pro­gram­mers with years of ex­pe­ri­ence may not find much value in this post, but my early col­lege self would have ea­gerly ab­sorbed the knowl­edge–maybe you'll find the tips use­ful too.

To start, I'm go­ing to em­pha­size mas­ter­ing the fun­da­men­tals. When in doubt, re­view­ing and strength­ing your knowl­edge of the ba­sics is never a bad idea. Hard prob­lems are of­ten com­bi­na­tions of sim­ple prob­lems. It will be eas­ier to solve the mon­strosi­ties if we're not bel­lyflop­ping through the ba­sic stuff.

Data Structures

Data struc­tures are nec­es­sary to code much of any­thing–but it may be worth re­vis­it­ing these build­ing blocks. I find my­self reusing the same ones over and over again. This repet­i­tive­ness isn't nec­es­sar­ily bad. If it's not broke, why fix it? Yet, there may be new lev­els to this ish if we dig a lit­tle deeper. For starters, make sure you've mas­tered the ba­sics. You will never run out of rea­sons to use ar­rays, linked lists, sets, hash ta­bles, trees, graphs, heaps, etc. For the var­i­ous struc­tures, it may be worth re­view­ing the prop­er­ties and time-com­plex­i­ties for their op­er­a­tions. You should be able to com­pare their pros and cons. For ex­am­ple, why use an ar­ray over a linked-list? Or vice-versa? Sure, know­ing about data struc­tures is cool; how­ever, it's im­por­tant you also know how to uti­lize them ef­fec­tively in real-world ap­pli­ca­tions.


Of course, once you know a bunch of data struc­tures, you need to make use of them. Thus, let's bring on the al­go­rithms. While in­vest­ing time learn­ing and im­ple­ment­ing new al­go­rithms is worth it, I would en­cour­age you to learn al­go­rith­mic pat­terns. Some of the new prob­lems you run into will look like prob­lems you've al­ready seen. Be smart and lever­age that knowl­edge in­stead of rein­vent­ing the wheel.

In ad­di­tion, you should al­ready be fa­mil­iar with mea­sur­ing the run­time and space com­plex­ity of an al­go­rithm us­ing as­ymp­totic analy­sis. Asymptotic analy­sis gives a ma­chine-in­de­pen­dent way of mea­sur­ing per­for­mance. It's use­ful to say that merge­sort has an O(n log(n)) worse case run­ning time, which is su­pe­rior to bub­ble sort's O(n2) worse case run­ning time. If this no­ta­tion looks like hi­ero­glyph­ics to you, con­sider brush­ing up on this topic.

I would also rec­om­mend peo­ple get com­fort­able us­ing re­cur­sion. Yes, it's not al­ways use­ful and can some­times make the code more con­vo­luted. It can also have the op­po­site ef­fect. Look at the re­cur­sive al­go­rithm to solve the Tower of Hanoi game–and then com­pare it to the it­er­a­tive ver­sion. There are just some prob­lems in the world that lend them­selves to re­cur­sive so­lu­tions. Plus, it will help ex­pand your mind. Challenging your­self is worth it in the long run.

Learn a New Language Paradigm

With a few ex­cep­tions here or there, most peo­ple are in­tro­duced to pro­gram­ming nowa­days via an im­per­a­tive, ob­ject-ori­ented lan­guage. This, once again, isn't nec­es­sar­ily bad. Examples in­clude Java, JavaScript, Python, C++, C#, and Ruby. There's noth­ing wrong with any of these lan­guages, and you could prob­a­bly start your ca­reer by learn­ing any of them.

Yet, in my jour­ney so far, I have found it in­sight­ful to learn new lan­guage par­a­digms. This could mean learn­ing a whole new pro­gram­ming lan­guage or dis­cov­er­ing pre­vi­ously un­known abil­i­ties in your cur­rent fa­vorite lan­guage. Before I go any fur­ther, I should prob­a­bly de­fine some terms. After all, what do I mean by lan­guage par­a­digms?

Language par­a­digms are a way to clas­sify pro­gram­ming lan­guages based on their fea­tures. To note, lan­guages can fit into mul­ti­ple par­a­digms–they need not be mu­tu­ally ex­clu­sive.

Object-oriented is an ex­am­ple of a par­a­digm. Most read­ers are prob­a­bly al­ready fa­mil­iar with the no­tion of cre­at­ing ob­jects and defin­ing the re­la­tion­ships be­tween them. Yet, not all lan­guages are ob­ject-ori­ented. It's worth it to ex­plore. I rec­om­mend peo­ple try learn­ing ei­ther a func­tional lan­guage or a log­i­cal lan­guage.

An ex­am­ple of a func­tional lan­guage would in­clude Racket. If Racket's syn­tax doesn't ter­rify you, con­sider check­ing out some of the code ex­am­ples else­where on my web­site. To note, func­tional lan­guages place a lot of em­pha­sis on ap­ply­ing and com­pos­ing func­tions–and of­ten make use of im­mutable data struc­tures and re­cur­sion. Keeping in mind some of my ear­lier rec­om­men­da­tions, you could knock many birds with one stone.

Honestly, I've haven't done much with log­i­cal lan­guages. It's on my list of things I might learn one day. You, how­ever, can one-up me by div­ing into one of these lan­guages. An ex­am­ple would in­clude Prolog–but there are oth­ers. These lan­guages solve prob­lems us­ing for­mal logic so be pre­pared to brush up on some math.

There are many other lan­guage par­a­digms, and I am not go­ing to at­tempt to men­tion all of them here. You could, for ex­am­ple, ex­plore the dif­fer­ence be­tween dy­nam­i­cally-typed lan­guages and sta­t­i­cally-typed lan­guages. It's worth think­ing about why type sys­tems are use­ful in the first place. Another set of in­ter­est­ing par­a­digms would in­clude im­per­a­tive lan­guages vs. de­clar­a­tive lan­guages. I've al­ready men­tioned im­per­a­tive lan­guages. They al­low the pro­gram­mer to ex­plic­itly set the pro­gram's state us­ing state­ments. You're telling the com­puter what to do–step by step. In con­trast, a pro­gram­mer us­ing a de­clar­a­tive lan­guage only tells the com­puter what they wanted to be com­puted, typ­i­cally within the re­straints of some prob­lem do­main. The com­puter then fig­ures out how to solve the prob­lem. Examples of this kind of lan­guage would in­clude Prolog and SQL.

Master Your Tools

I of­ten over­look this one. Investing some time into mas­ter­ing the tools and pro­grams we use every day can pay div­i­dends later on. It could be as sim­ple as learn­ing a few key­board short­cuts. You should at the very least be com­fort­able in your fa­vorite text ed­i­tor–maybe use Google to try to find use­ful fea­tures you've over­looked. I would also rec­om­mend fig­ur­ing out how to use a ver­sion con­trol sys­tem, such as Git. If you know how to setup re­mote branches, fork pro­jects, han­dle merge con­flicts, and re­base, you may know more than many fresh com­puter sci­ence grad­u­ates. Trust me, I have sto­ries. Bored of my sug­ges­tions so far? You can al­ways just try new soft­ware. Download a new ed­i­tor and mess around. Use a new frame­work. You'll prob­a­bly learn some­thing use­ful.


I'm go­ing to end the post here, but there are ob­vi­ously many other skills to work on. This list isn't meant to be com­plete. I mostly tack­led top­ics I ei­ther cov­ered in col­lege or felt fa­mil­iar with. Also, many of these sec­tions are in­ten­tion­ally sparse. I am go­ing to leave it up to you to do some re­search on your own. Hopefully, in the fu­ture, I can ex­pand on some of these ideas in fu­ture posts.