I wouldn't try too hard with a codebase as small as 30-40k lines, but for an actually large codebase, there are a bunch of different things that can help:
- examine a class or function hierarchy and call graph. If you have tools to do so and the codebase is set up for it, go ahead. If not, set up the tools and codebase to be processed for this - you'll learn stuff about the code just by hooking these tools up.
- pick medium-level routines in the code base that you are interested and run the applicaiton in the debugger with breakpoints set on them. Take a look at the callstacks, step through the callers, look at the arguments, etc.
- you can also get a bunch of knowlege of the structure of the app by single stepping in the debugger - "step over" to see the high level control flow, and "step into" subsystems you want to explore.
- documenting the existing code using a tool such as doxygen can help you learn it while at the same time providing useful documentation for other team members.