I often see ads on sites seeking people to do their CS assignments. I could do this though it’s generally pointless since all it does is cause ME to improve in some insignificant fashion and make some pittance of money and the customer graduates unable to do their job. However, I do respond when people are seeking tutors.
Tutoring (or teaching/coaching in general) requires a different effort than just coding their assignment yourself.
Software development is shockingly abstract in many ways. We say things like “Process a client’s request from the socket” but what does that really mean? Sure, I can bang up a protocol handler with framing, build a message dispatcher, and then handle messages in a queue. But think back to what it took to just “dash off” those steps.
For someone starting out, though, just the fact that TCP doesn’t respect message boundaries is a huge problem. In fact, if in reading this you don’t know that TCP doesn’t respect message boundaries … welcome to their world!
To make matters worse I’ve seen many assignments that are simply written shockingly poorly. Imagine being told to write a client/server and told to send the file size as 64 bits.
OK, I’ll bite: network byte order? Host byte order? Ascii string? Ascii string null-terminated? Space terminated?
The poor quality of protocols in assignments reflects very badly on the profs … but it also gives one an appreciation for why it’s hard to do remote software development. I’ve seen “protocols” from potential clients written equally badly. I often end up having to rewrite protocol specs because they simply can’t be interpreted in a single manner.
I’ve had to recommend clarifying questions more than once for the people I help to pose to their professors or TAs.
Once I understand what the assignment asks for, I can finally start helping.
Helping does not mean “writing the code and explaining it!” Helping means finding out what they know, determining if what they know is correct, and then asking questions or making tasks that are simpler than the assignment that lets them connect where they are to where they need to be.
Yay for gap analysis to use the formal term!
What I’ve found helpful is to break the problem into lots of small steps and recommend a program to exercise each step. That way, the person writes a few small programs each of which has a necessary part of the final program. Each program can be tested and understood in isolation.
Obviously, this is “divide and conquer” but what I’m really trying to teach isn’t network programming but “how to solve a problem.”
In networking those steps are nicely visible, which helps a lot.
For instance a simple message pump has this basic structure:
- Bytes come in, append them to a buffer.
- After each read, go through the buffer looking for complete messages (PLURAL).
- For each message found, dispatch it (enqueue it, handle it, whatever).
- Move whatever bytes are left to the start of the buffer.
- Do it again.
How would one test it?
Something I stress constantly is “Let’s make something and then immediately test it.” I guess “test driven training” instead of “test driven development.”
There are only a few things to test. What are they?
- What happens when a single complete message arrives in a single read?
- What happens when a partial message arrives in a single read?
- What happens when a set of messages arrive completely in a single read?
- What happens when a set of messages arrive in a single read with the last message not yet complete?
Testing for networking becomes harder and harder. Eventually, the testing requires doing things in the client (to send partial messages for instance).
Even without building suites of tests, thinking through what can happen helps. The computer is not abstract but our languages (human languages) are. Forcing everything to be explicit and concrete is needed to make it work.
Being abstract is the key to being productive though! I do love a good contradiction!
People have said that learning programming is “good” in general to help people think. I love programming so I’m biased, but really, is learning how to give instructions to something so stupid that it can only do the ultimately tiniest steps really the level of thinking in general we want?
Keep the Light!