NCR is an American-based financial technology company with headquarters in Atlanta, but with offices in many countries around the world such as the one in Waterloo. Originally known for developing some of the first mechanical cash registers (NCR being an acronym for National Cash Register), NCR has been at the forefront of advances in the financial technology sphere. If you've used a point-of-sale(POS) machine or a self-serve kiosk at a restaurant, chances are it was made by NCR. NCR also has invested in the financial software industry, which is the department I was working in.
My role encompassed all aspects of working with the project codebase. This included development of new features, testing of implemented code and design and planning of upcoming development. I was on one of multiple Agile Scrum development teams working on an upcoming software project. I joined partway through development of this project, and needed to get up to speed on what progress had been made and what needed to be done next.
Initial setup of my development environment took about a week, after which I began working on issues and feature development. Development was in 2-week sprints, with standups and retrospectives a regular part of the daily routine.
About 4 months in to the work term the existing co-op on my team left and a new co-op took his place; I became the senior co-op of the team, responsible for 'showing the ropes' and getting the new co-op student up to speed.
I appreciate the integration of testing as one of the developer's main duties - While it might be extra work, having an understanding of how tests are built and what needs to be tested is invaluable in learning how to be a better developer.
The position advertised Java as a primary language needed for the role. Java formed the backbone of the application being developed and ran the test suites.
Testing was done using Cucumber: a testing framework that connects test functions to statements written in regular English.
Cucumber test statements were connected to Java functions that performed the tests.
Databases such as Cassandra, Redis and Elasticsearch were used to store application data. Continuous Integration(CI) software was used to test builds when new code was merged.
Docker and Kubernetes were also used as part of the project infrastructure, forming the backbone of the project's microservice-based architecture. I had a single-node cluster that I used for development and testing.
One of the biggest things to adjust to when working with a large codebase developed by multiple teams is the sheer number of interconnected, moving parts. While the goal would be to have individual, modular parts working together as a whole, reality is not as neatly divided. Seemingly minor, unrelated changes to one part of the codebase can have cascading effects that cause another part to break and can take a long time to debug.
Attempting to tackle an issue with the 'code first, look later' approach is doomed to failure as you will inevitably miss a detail that will require rewriting some or all of the code. Thoroughly understanding the problem before writing code is an idea often emphasized, but only understood once it becomes vital to developing with any form of efficiency.
As my Computer Science major did not have a group project class yet(there is one in 3rd year, and the sister Software Engineering major has multiple), this was my first experience with enterprise-scale team software development. It could be a challenge to communicate with different teams on a shared project, especially when the teams have other issues on the burner as well.
I've realized that requiring pull requests to a master codebase, mandatory code reviews, Agile meetings and planning - all of it is to facilitate the operation of large development teams. Without some sort of plan any team effort larger than a few people will just collapse from communication issues.
There's also a level of unpredictability that also goes beyond what you would get in academia. While dealing with the regular unexpected complexity creep and redesigning that can come with regular development, in the workplace you can get customer requests or urgent bug fixes that require sidelining your current plans. In school you rarely need to touch a project after the assignment is over, much less provide a bug fix on short notice - and class schedules don't change often without the classes' permission.
Coming in to this work term I had no experience in an Agile development environment - I had an idea of what the foundational concepts were but no experience operating in that environment.
Our work was organized into 2-week sprints. Every workday would have a standup meeting - a 10 minute meeting where each member of the team would say what they were working on and what was blocking them, if any. Later on in the work term I gave demos of features we had worked on to demonstrate that we had met all the requirements. We would also have meetings to plan upcoming sprints and retrospectives - discussions on what went well/badly last sprint and how we could improve in the future.
Agile development is a widespread methodology in the industry and I consider this to be tremendously valuable experience to bring forward in my career.
Looking back halfway through the work term, I consider this goal to be accomplished as I came out from this work term with a concrete understanding of what Agile processes are both in theory and in practice.
I made this goal halfway through my work term once I had gained more confidence and knowledge about my current role.
I had already set up and been maintaining a Kubernetes cluster as my development environment since the start of the work term. The cluster contained multiple pods interacting on many levels, so diagnosing problems was not a straightforward process and relies alot on prior experience with similar errors.
Determining and fixing the cause of an issue however gives good insight into how the different systems of the cluster interact with each other. Debugging a cluster error also really ingrains useful Kubernetes processes(checking pod logs, kubectl describe
-ing a pod to get error messages) and a methodical approach to tackling unknown issues.
The initial setup of my development environment lasted about a week. I found this to be too long, so during the work term I tried different ways to decrease the time needed to spin up a dev environment. I created an OVA archive of a working cluster and used that to assist in onboarding. The OVA file proved to be a bit ponderous and difficult to update, so I experimented with using Vagrant to make a sharable config file that could boot a development cluster. By the end of my work term I had created a dev VM for each member of my team that didn't have one, and reduced the full setup time to around 2 days.
I met less success in building a Kubernetes application - The business architecture was already mostly complete so there was not much opportunity to build something new with business value. The daily operations of maintaining a dev cluster and experimenting with cluster setup is valuable real-world experience with Kubernetes, so I consider this goal complete, and look forward to working more with Kubernetes in future jobs.
I had previous experience with Git in university, but that was limited to basic operations on a single repository with a single user (me). Working with multiple large Git repositories, with over 2 dozen developers working and making changes simultaneously, is an entirely different experience and a situation that is commonplace in the industry.
I worked with multiple Git repositories covering different aspects of the codebase. The repositories were shared across the different teams so there was a high traffic of commits - I regularly resolved merge conflicts between my local changes and upstream updates. Sometimes I needed changes from commits another team member had made - I added my team member's forks as remotes to pull commits when needed and encouraged the rest of my team to do the same.
By midway through the work term I was completely comfortable with the regular Git workflow(fork, make changes, pull request, merge). I had also gained familiarity with more one off operations, like setting a separate repository as a remote for a fork or resetting while keeping the reset changes. I consider this goal to be achieved. I will say that the number of different operations you can do in Git only seems to grow as I learn more about it!
A goal created midway through the work term, as I recognized I had a weakness in efficiently explaining technical situations and the reasoning behind some of my code changes. I often went into too much detail or didn't use concise terminology for explaining code, which made getting my idea across take much longer than it should have. Improving this has become a priority for me - The importance of being able to effectively communicate with your co-workers on issues can't be overstated.
Around this time a new co-op student joined my team - I considered this the perfect opportunity to work on technical communication. Explaining a concept to someone without the background experience is an excellent way to test your understanding and find areas in which you can improve.
Near the end of the work term I investigated on speeding up the setup of development environments using Vagrant, and demoed what I had created to the team. It was an excellent experience in 'selling' an improved methodology or new software - first explaining the problem, then demonstrating how the software solves that problem.
I didn't expect to be able to call this goal fully complete - improving is a continuous process. I do feel however that I have made progress on that this work term.
This goal was made at the start of my work term, before I had experience in Agile development. I had the idea that there were many specialized tools used in the Agile development. We did use Jira, which is a a combination of issue tracker and planning board. Beyond that though there were no tools we used that required specific training. I consider this goal technically achieved but would have made another goal had I known more about Agile development.
At the end of July NCR ran a global 2-day hackathon to develop new ideas for prizes. I partnered with 3 other-co-op students at the Waterloo office to work outside of our normal responsibilities. We ended up developing a kiosk-type app based on facial recognition, using React Native and Microsoft Azure services. Our project ended up making it to the global finals among 10 other entrants.
This was my first true hackathon and I really enjoyed it! It was definitely challenging getting a complete package done in a 2-day period. I will be on the lookout for more hackathons in the future!
There were a couple of big takeaways I got from the past 8 months. Collaboration and communication skills are essential. When working on a new task or issue, thoroughly researching and understanding the problem is way more effective than blindly jumping into code. Last but not least, having an efficient and organized infrastructure and workflow is vital for any large-scale development.
I would like to thank my team - Birinder, Atishay, Nidhi, Mitchell, Charlie and Marlon - for being so supportive and willing to help out when I had questions or when I got stuck. I would especially like to thank my team lead Jarrett, who was quite posssibly the best team lead a first-term co-op could have - incredibly receptive to my ideas and supportive of my work term goals. I would also like to thank Kamran who was an excellent teacher for the first 4 months.
Overall this work term has been an eye-opening experience for me in terms of discovering not only how software development works in the workplace, but how my skills translate to the workplace as well. The working experience in tech like Docker and Kubernetes is very valuable going forward.