It’s summertime here in the Pacific Northwest, and seven months into the first year of this blog. After thirty weekly posts, I thought it would be a good time to consider the themes that have come up so far this year. If you’re a new reader, I hope you’ll find this to be a useful primer.
When you’re stuck on a programming problem for a while (everyone has their own time threshold), it’s customary to look for a hint. If you’re working on a competitive programming problem from a past contest, they’re easy to find. Problems on uHunt are categorized by algorithm, so that’s a big hint already. Popular problems often have editorials (I have written a few myself) or even complete source code in multiple programming languages. On the other hand, if your problem has to do with a programming language or tool rather than a puzzle, Stack Overflow is the standard resource.
But what if your problem is more general than a programming puzzle or language quirk? What if you have the type of question that gets closed on Stack Overflow? In other words, what if you’re looking for advice.
This post is part of a series on Java syntax and libraries for solving the problems in each chapter of uHunt, a tool for competitive programming practice. You can find the rest of the posts in the series by visiting my uHunt Java post category.
A few months ago, I wrote two posts related to uHunt Chapter 1. The first post covers general lessons learned from completing the 39 starred problems in that chapter. The second one is a summary of the corresponding chapter of Competitive Programming 3, the companion textbook. Although I have covered Java language features in those and other posts, I thought it would be useful to provide an overall summary of the parts of Java that I found useful when solving the problems in that chapter.
Last week, I wrote about ways to improve runtime performance for a Java solution to UVa 732. This week I’m going to cover a process for analyzing Java program performance using the profiling features of the VisualVM Java troubleshooting tool. But first, a note about profiling. As I mentioned last week, even a highly optimized program can fail to be accepted by an online judge if it uses the wrong algorithm. In other words, you generally can’t profile your way out of a slow design. Nevertheless, looking at a VisualVM snapshot of your implementation can provide some useful performance insights. Just don’t spin your wheels for too long making tiny adjustments to your implementation. You may need to go with a different design instead.
Programming puzzles are often designed in such a way that getting your solution to complete under the time limit is at least as challenging as getting the correct result. To create such a challenge, a problem setter can adjust the size of the input until sub-optimal solutions no longer run in under the time limit.
Many puzzles can be solved using both a slower but easier approach and a more sophisticated method that runs within the required time limit. Among the uHunt starred problems, 732: Anagrams by Stack is one in which people have found performance particularly challenging, at least based on the forum threads. As with previous anagram problems, and performance-sensitive problems in general, getting Java to perform at the required level can be especially difficult. While some online judges provide wiggle room for languages with more overhead than C/C++, UVa Online Judge doesn’t seem to use that policy.
I believe in the importance of practicing programming fundamentals, especially through programming puzzles. But puzzle learning works best when you already have some experience with the programming language you’re using to solve them. By prompting you to exercise a core set of programming fundamentals, puzzles help strengthen basic coding skills. To get those basic skills in the first place, you need a starting point for learning. For a few years now, coding instruction in the browser has been a convenient option.
Unit testing is a controversial topic in developer circles. Opinions range from Most Unit Testing is Waste to You are not allowed to write any production code unless it is to make a failing unit test pass.
For those on the pro-unit testing side, there are numerous benefits to the practice, especially the test-first variety. In my experience, writing unit tests does provide a net gain in productivity compares to programming practices that don’t use them. These are the benefits that I find especially useful:
Programming is creative work. Given a problem, you have to find a solution, then explain it to a computer in a way that humans can also understand. But unless you’re working on your own project, you don’t have total creative freedom. You have to use the tools and technologies that your team has selected, and your technical decisions are generally reviewed by other developers. On the other hand, it’s rare that you are told exactly how to solve the problem. If someone already knows that much about the solution, they could just implement it on their own. So it’s up to you to work out the details.
Peopleware is one of those books that show up on recommended reading lists for software development managers. Joel Spolsky was recommending it back in 2002. (It was written in 1987 and revised in 1999 and 2013). Chapter 16 (in the 3rd edition) begins with this vignette:
Circus Manager: How long have you been juggling?
Candidate: Oh, about six years.
Manager: Can you handle three balls, four balls, and five balls?
Candidate: Yes, yes, and yes.
Manager: Do you work with flaming objects?
Manager: …knives, axes, open cigar boxes, floppy hats?
Candidate: I can juggle anything.
Manager: Do you have a line of funny patter that goes with your juggling?
Candidate: It’s hilarious.
Manager: Well that sounds fine. I guess you’re hired.
Candidate: Umm… Don’t you want to see me juggle?
Manager: Gee, I never thought of that.