Internship Log (Part 2)
The internship is nearing its end, and the coding work for the basic version of the backend API server is essentially complete. Here’s a summary.
As the project team leader, my only knowledge about software project management comes from having read The Mythical Man-Month once during the winter break. Through this practical experience, I realized I’m still quite green. Nevertheless, I believe I’ve learned a thing or two.
Design
Compared to two years ago when I would immediately open Visual Studio to work on C language assignments without a second thought, I’ve clearly changed a bit today.
First of all, I haven’t opened VS in a long time.
In any case, over these two years, I’ve gone through several intensive coding experiences: the pure, naive period of learning Python, the training from writing the upper-computer software for the robotics team, the experience of writing crawlers for the academic affairs website (both teacher and student sides), and the file management tool I developed while participating in the Orange Juice project. At the very beginning, I certainly charged ahead recklessly, but I guess after suffering enough from inconsistencies, I learned the importance of upfront design. Once I stepped into the realm of design, the next question became one of degree—thus, this experience of overseeing the entire project has been a very beneficial exercise.
First, clarify what needs to be done. This question is crucial for a team genuinely wanting to build a product: defining your own product is a strategic-level task. However, it’s a pity that we didn’t have any particularly interesting ideas this time. With responsibility on my shoulders, my expectation for this internship was to seriously create a reliable, simple project.
In short, it’s a traditional web application with WeChat Mini Program as its flagship feature—specifically, a goal management system.
This has been done by so many people that modeling the tasks we’d face could draw from many mature solutions: such as project-oriented Worktile; personal life management-oriented WonderList; student-oriented My Study Life; and even Apple’s Reminders along with other tools I’ve heard of but never used. Synthesizing the characteristics of these tools, we distilled a classic, WeChat-flavored goal management system—this became our Seed.
Features It Should Have
So what should Seed be able to do?
- Have a simple user system for easy synchronization and increased user retention.
- Allow users to freely create and manage goals, similar to
projectsin Worktile. - Allow users to be invited into others’ goals.
- Goals are divided into daily check-in types (recurring) and project攻坚 types (one-time, possibly with milestones).
- The flagship frontend is the WeChat Mini Program.
- Also compatible with other potential clients.
From this perspective, Seed should be a small, streamlined, and practical service, which aligns perfectly with the original intent of WeChat Mini Programs.
Here, it’s essential to emphasize the characteristic of being “small and streamlined.” Why small and simple? First, limited manpower and time. Second, to avoid the mistake often made in second-system projects mentioned in The Mythical Man-Month: blind arrogance,疯狂地 adding endless redundancy to a project. This is a thankless and foolish endeavor, especially since—we’re not dealing with advertising revenue. A simple example: Mac OS版迅雷 vs. Win版迅雷, obviously everyone prefers the streamlined and usable Mac version.
It must also have good compatibility with WeChat Mini Programs. To provide a smooth user experience, it should support both email as a login identifier and WeChat openId as a login credential.
System Structure
As mentioned above, we aim to build a web application with the WeChat Mini Program as its flagship feature, meaning Seed has the capability and ambition to be compatible with other frontends. Therefore, a RESTful-style API becomes the best choice: complete decoupling of frontend and backend, clear structure, and easy consumption.
Thus, Seed should consist of a WeChat Mini Program and other potential forms as the frontend, consuming resources provided by the backend via the HTTP protocol.
The backend provides secure and reliable services through APIs.
In the process, I also learned a bit and encountered the concept of HATEOAS (Hypermedia As The Engine Of Application State). Though not yet mature, it represents a possible future.
Implementation
Since I only participated in the coding work for the API server, I’ll only discuss the backend implementation here.
I like to categorize design as the strategic level (the “道”), while the remaining work falls into the tactical level (the “术”). Therefore, the choice of technology and the specific methods to implement a system can be considered here.
Technology
Due to internship requirements and a desire to use the Java language appropriately, we chose the Spring Framework as the backend framework, along with the Spring ecosystem:
- Spring Boot as the application container
- Spring Framework for implementing business logic
- Spring Data as the DAO
- Spring Session for session management
- Spring test for testing
Additionally, tools like Git, TravisCI, and Heroku were used to improve the development experience.
Development Process
As mentioned earlier, the experience of writing Spring Controllers is quite similar to that of the Python Flask web framework. Perhaps Flask drew some inspiration from Spring? Resource-oriented controller classes feel much more compact compared to the traditional Java Web approach of writing a Servlet for each resource.
Spring advocates test-driven development, but actually implementing it isn’t easy, as testing isn’t always a popular task. Assigning a dedicated person to write test code would involve high learning costs and some interpersonal issues. So during development, I decided to have each person responsible for testing their own code, with me ultimately reviewing it.
Summary
The noteworthy aspects about Seed itself have been covered. Now, let’s talk about other things.
Self-Reflection
I learned a lot during the internship, but problems remain.
As a project manager, I was pretty terrible. There were significant shortcomings in controlling progress, allocating personnel, and handling other details.
For example:
- Lack of knowledge about frontend technologies likely means only the API server will be functional by the end of this project.
- Only half of the project team members truly participated.
- Training for those who did participate felt hollow and lacked patience.
Clearly, I still need further training. However, simultaneously acting as both project manager and developer led me to ponder another issue.
Discussion on Two Capabilities of a Software Engineer
The ability to architect and oversee an entire system and the ability to choose, tailor, and apply algorithms to implement a single function.
The classroom education in our university’s software school seems to focus only on the latter. This isn’t particularly strange, as mastery of algorithms is easily measurable. One could say differences in ability are显著, akin to solving math problems—under strict preconditions and constraints, people’s creativity is very easy to evaluate. However, the ability to reasonably set these so-called “strict preconditions and constraints,” though important, is difficult to measure.
As for why this is self-contradictory, here’s a simple, understandable, though perhaps not entirely apt, example: everyone knows it’s幼稚 and unrealistic for parents to strictly forbid their children from early relationships for fear of affecting studies, yet expect them to immediately start a family after graduation. Similarly, implicitly expecting students to become all-round talents after graduation solely based on good academic performance is a slightly扭曲 notion. The difference lies in the latter contradiction being less尖锐 than the former.
I believe such internships are indeed a compensation for the shortcomings of classroom education and offer an opportunity to avoid the矛盾 between grades as a cultivation method and capability as a cultivation goal—the things these two symbols represent.