Home 2021 Pinkoi Tech Career Talk - Decoding the High-Efficiency Engineering Team
Post
Cancel

2021 Pinkoi Tech Career Talk - Decoding the High-Efficiency Engineering Team

2021 Pinkoi Tech Career Talk - Decoding the High-Efficiency Engineering Team

Decoding the high-efficiency engineering team at Pinkoi Tech Talk

Decoding the High-Efficiency Engineering Team

2021/09/08 19:00 @ Pinkoi x Yourator

My Medium: ZhgChgLi

About the Team

Pinkoi’s work is composed of multiple Squads:

  • Buyer-Squad: Focuses on buyer-side features
  • Seller-Squad: Focuses on designer-side features
  • Exploring-Squad: Focuses on browsing and exploration
  • Ad-Squad: Focuses on platform advertising
  • Out-Of-Squad: Primarily supports, infra, or process optimization

Each Squad is composed of various function teammates, including PM, Product Designer, Data, Frontend, Backend, iOS, Android, etc.; long-term and ongoing work goals are accomplished by the Squad.

In addition to Squads, there are also cross-team Projects that run, mostly short to medium-term work goals, where the initiator or any team member can act as the Project Owner, and the task is closed upon completion.

At the end, there is also how Pinkoi’s culture supports teammates in solving problems, if friends who are not interested in the actual content can directly scroll to the bottom of the page to view this section.

Relationship Between Team Size and Efficiency

The relationship between team size growth and work efficiency, from startups with 10 people to teams of hundreds (not yet challenged by thousands), but just jumping from 10 to 100, the 10x difference is significant in many aspects.

With fewer people, communication and handling things are quick; discussing and resolving issues in person can be done swiftly, as the “human connection” is strong, enabling synchronous collaboration.

However, in situations with more people, direct communication becomes challenging because with more collaborators, each discussion can take up a whole morning; and with many people collaborating, tasks need to be prioritized, and non-urgent matters cannot be addressed immediately, requiring asynchronous waiting to work on other tasks.

Having more diverse roles join can lead to more specialized work division, increased productivity or quality, and faster output.

But as mentioned earlier, conversely; there will be more collaboration with people, which means more time spent on communication.

Moreover, small issues can be magnified, for example, if one person used to spend 10 minutes daily on a task like posting reports, it was manageable; but now, assuming there are 20 people, it multiplies, and each day, more than 3 hours are spent on posting reports; optimizing and automating this task becomes valuable at this point, saving 3 hours daily, which amounts to wasting an extra 750 hours over a year.

As the team size grows, for the App Team, there are these roles that collaborate more closely.

Backend — API, Product Designer — UI, these do not need to be mentioned, Pinkoi is an international product, so all functional texts need to be translated by the Localization Team. Also, because we have a Data Team doing data collection and analysis, besides developing features, we also need to discuss event tracking points with the Data Team.

Customer Service is also a team that frequently interacts with us. Besides users sometimes directly providing feedback on order issues through the marketplace, more often users leave a one-star rating saying they encountered a problem. At this time, we also need the customer service team to help with in-depth inquiries, such as what problem did you encounter? How can we help you?

With so many collaborative relationships mentioned above, it means there are many communication opportunities.

However, remember, we are not avoiding or minimizing communication as much as possible; excellent engineers also need good communication skills.

What we need to focus on is important communication, such as brainstorming, discussing requirements, content, and schedules; do not waste time on confirming repetitive issues or vague communication. Avoid situations where you ask me, I ask him, and so on.

Especially in the era of the pandemic, communication time is precious and should be spent on more valuable discussions.

“I thought you thought what I thought” — this sentence perfectly illustrates the consequences of unclear communication.

Not just in work, in daily life, we often encounter misunderstandings due to different perceptions, and in life, harmony relies on mutual understanding; but in work, it’s different. If different perceptions are not discussed in depth, it’s easy to find out during the production stage that things are not as expected.

Interface Communication

The idea introduced here is to communicate through a consensus interface, similar to the Dependency Inversion Principle in object-oriented programming in SOLID principles (if you don’t understand, it’s okay); the same concept can be applied to communication.

The first step is to identify areas of communication that are unclear, need to be confirmed repeatedly, or require specific communication to be more focused and effective, or even situations where this delivery does not require additional communication.

Once the issues are identified, you can define an “interface.” An interface is a medium, which can be a document, process, checklist, tool, etc.

Use this “interface” as a bridge for communication between each other. There can be multiple interfaces, use the appropriate interface for each scenario; when encountering the same scenario, prioritize using this interface for initial communication. If further communication is needed, it can be based on this interface for focused discussion of the issues.

App Team’s Collaboration with External Parties

Here are 4 examples of interface communication in collaboration with the App Team:

  1. The first one is the situation with Backend collaboration before any interface consensus, as shown in the above image.

For how to use the API, if simply providing the API Response String to the App Team, there can be areas of ambiguity, for example, how do we know if date refers to Register Date or Birthday? Also, the scope is broad, many fields need confirmation.

This communication is also repetitive, requiring confirmation each time there is a new endpoint.

This is a classic case of ineffective communication.

  1. App and Backend lack a communication interface between them. There are many solutions, and it doesn’t necessarily have to be a tool; it can be a manually maintained document.

Pinkoi uses Python (FastAPI) to automatically generate documentation from the API code, PHP can use Swagger (previous company practice); the advantage is that the framework and data format of the document can be automatically generated from the code, reducing maintenance costs, only needing to handle field descriptions.

p.s. Currently, new Python 3 will use FastAPI, and the old parts will be gradually updated. For now, PostMan is used as the communication interface.

The second one is collaborating with the Product Designer, which is similar to the Backend in principle, but the focus shifts to confirming UI Spec and Flow.

If the color codes and fonts are scattered, our App will also suffer. Setting aside the fact that requirements are like this, we don’t want situations where the same title has the same color but the color code is off or the UI at the same position is not consistent.

The most basic solution is to have the designer organize the UI components library, establish a Design System (Guideline), and mark them when designing UI.

Based on the Design System (Guideline) in the Code Base, we create corresponding Font, Color, and Button, View based on the component library.

When templating, use these established components for templating, making it easy for us to quickly align with the UI design draft.

But this is easily messed up and needs dynamic adjustments; it cannot cover too many exceptions, nor can it be rigid and not expand.

p.s. Collaboration with Product Designers at Pinkoi is mutual, where Developers can also suggest better practices and discuss with Product Designers.

The third one is the interface with Customer Service. Product reviews are crucial for products in the marketplace, but it involves a very manual and repetitive communication process.

Because we need to manually check for new reviews from time to time, and if there are customer service issues, we need to forward the issues to customer service for assistance, which is repetitive and manual.

The best solution is to automatically synchronize marketplace reviews to our work platform. You can spend $ to buy existing services or use my developed ZhgChgLi / ZReviewTender (2022 New).

For deployment methods, tutorials, and technical details, refer to: ZReviewTender - Free and Open-source App Reviews Monitoring Bot

This bot is our communication interface. It will automatically forward reviews to a Slack Channel, allowing everyone to quickly receive the latest review information, track, and communicate on it.

The last example is the dependency on the Localization Team’s work; whether it’s a new feature or modifying old translations, we need to wait for the Localization Team to complete the work and hand it over to us for further assistance.

The cost of developing our own tools is too high, so we directly use third-party services to help us break the dependency.

All translations and keys are managed by third-party tools. We just need to define the keys in advance, and both sides can work separately. As long as the work is completed before the deadline, there is no need for mutual reliance. After the Localization Team completes the translation, the tool will automatically trigger a git pull to update the latest text files in the project.

p.s. Pinkoi has had this process since very early on, using Onesky at that time, but in recent years, there are more excellent tools available, which you can consider adopting.

Collaboration within the App Team

We talked about external factors, now let’s talk about internal factors.

When there are fewer people or when one developer maintains a project, you can do whatever you want. You have a high level of mastery and understanding of the project, which is fine. Of course, if you have a good sense, even if it’s a one-person project, you can handle all the things mentioned here.

But as the number of collaborating teammates increases, everyone is working under the same project. If everyone still works separately, it will be a disaster.

For example, doing API calls differently here and there, often reinventing the wheel wasting time, or not caring at all and just putting something online haphazardly, all will incur significant costs for future maintenance and scalability.

Within the team, rather than calling it an interface, I think it’s too formal; it should be about consensus, resonance, and a sense of teamwork.

The most basic and common topic is Coding Style, naming conventions, where to place things, how to use Delegates… You can use commonly used tools like realm / SwiftLint for constraints, and for multilingual sentences, you can use freshOS / Localize for organization (of course, if you are already using a third-party tool for management as mentioned earlier, you may not need this).

The second is the App architecture, whether it’s MVC/MVVM/VIPER/Clean Architecture, the key point is cleanliness and consistency; no need to pursue being trendy, just be consistent.

The Pinkoi App Team uses Clean Architecture.

Previously at StreetVoice, it was purely MVC but clean and consistent, making collaboration smooth.

Next is UnitTest, with many people, it’s hard to avoid the logic you’re working on from accidentally being broken; writing more tests provides an extra layer of protection.

Lastly, there’s the aspect of documentation, about the team’s work processes, specifications, or operation manuals, making it easy for teammates to quickly refer to when they forget, and for new members to quickly get up to speed.

Besides the Code Level interface, there are other interfaces in collaboration to help us improve efficiency.

The first is having a Request for Comments stage before implementing requirements, where the developer in charge roughly explains how this requirement will be implemented, and others can provide comments and ideas.

In addition to preventing reinventing the wheel, it can also gather more ideas, such as how others might expand in the future, or what requirements to consider later on… etc., as onlookers see more clearly than those involved.

The second is to conduct thorough Code Reviews, checking if our interface consensus is being implemented, such as: Naming conventions, UI layout methods, Delegate usage, Protocol/Class declarations… etc. Also, checking if the architecture is being misused or rushed due to time constraints, assuming the development direction should move towards full Swift development, and whether there are still Objective-C code being used… etc.

The main focus is on reviewing these aspects, with functionality correctness being secondary assistance.

p.s. The purpose of RFC is to improve work efficiency, so it shouldn’t be too lengthy or seriously delay work progress; it can be thought of as a simple pre-work discussion phase.

Consolidating the team’s internal interface consensus functions, finally mentioning the Crash Theory mindset, which I think is a good behavioral benchmark.

Applying it to the team means assuming that if everyone suddenly disappeared today, can the existing code, processes, and systems allow new people to quickly get up to speed?

Recap the meaning of interfaces, internal team interfaces are used to increase mutual consensus, external collaboration is to reduce ineffective communication, using interfaces as a means of communication without interruption, focusing on discussing requirements.

Reiterating that “interface communication” is not a special term or tool in engineering, it’s just a concept applicable to collaboration in any job scenario, it can simply be a document or process, with the sequence being to have this thing first and then communicate.

Assuming each additional communication time takes 10 minutes, with a team of 60 people, occurring 10 times per month, it wastes 1,200 hours per year on unnecessary communication.

Improving Efficiency - Automating Repetitive Work

The second chapter wants to share with everyone about the effects of automating repetitive work on improving work efficiency, using iOS as an example, but the same applies to Android.

It won’t mention technical implementation details, only discussing the feasibility in principle.

Organizing the services we use, including but not limited to:

  • Slack: Communication software
  • Fastlane: iOS automation script tool
  • Github: Git Provider
  • Github Action: Github’s CI/CD service, will be introduced later
  • Firebase: Crashlytics, Event, App Distribution (to be introduced later), Remote Config…
  • Google Apps Script: Google Apps plugin script program, to be introduced later
  • Bitrise: CI/CD Server
  • Onesky: As mentioned earlier, a third-party tool for Localization
  • Testflight: iOS App internal testing platform
  • Google Calendar: Google Calendar, to be introduced for what purpose
  • Asana: Project management tool

Issues with Releasing Beta Versions

The first issue to address is the problem of repetitiveness. During the development phase, when we want to allow other team members to test the app in advance, the traditional approach is to directly build it on their phones. If there are only 1-2 people, it’s not a big problem. However, if there are 20-30 team members to test, just helping with installing the beta version would take up a whole day of work. Additionally, if there are updates, everything has to start over.

Another method is to use TestFlight as a medium for distributing beta versions, which is also good. However, there are two issues. First, TestFlight is equivalent to the production environment, not the debug environment. Second, when there are many teammates working on different requirements simultaneously and needing to test different requirements, TestFlight can become chaotic, and the builds for distribution may change frequently, but it’s still manageable.

Pinkoi’s solution is to separate the task of “installing beta versions by the App Team” and use Slack Workflow as an input UI to achieve this. After inputting the necessary information, it triggers Bitrise to run Fastlane scripts to package and upload the beta version IPA to Firebase App Distribution.

For more information on using Slack Workflow applications, refer to this article: Building a Fully Automated WFH Employee Health Status Reporting System with Slack

Firebase App Distribution

Firebase App Distribution

Teammates who need to test simply follow the steps provided by Firebase App Distribution to install the necessary certificates, register their devices, and then choose the beta version they want to install or directly install it by clicking the link.

However, please note that iOS Firebase App Distribution is limited to Development Devices, with a maximum registration of 100 devices, based on devices rather than individuals.

Therefore, you may need to consider a balance between this solution and TestFlight (which allows external testing by up to 1,000 people).

At least, the Slack Workflow UI Input mentioned earlier is worth considering.

For advanced features, consider developing a Slack Bot for a more complete and customizable workflow and form usage.

Recap the effectiveness of automating the release of beta versions, the most significant benefit is moving the entire process to the cloud for execution, allowing the App Team to be hands-off and fully self-service.

Issues with Packaging Official Releases

The second common task for the App Team is packaging and submitting the official version of the app for review.

When the team is small and follows a single-line development approach, managing app version updates is not a big issue and can be done freely and regularly.

However, in larger teams with multiple concurrent development and iteration needs, the situation depicted above may arise. Without proper “interface communication” as mentioned earlier, everyone may work independently, leading to the App Team being overwhelmed. The cost of app updates is higher than web updates, the process is more complex, and frequent and disorderly updates can disrupt users.

The final issue is management. Without a fixed process or timeline, it’s challenging to optimize each step.

The solution is to introduce a Release Train into the development process, with the core concept of separating version updates from project development.

We establish a fixed schedule and define what will be done at each stage:

  • New version update every Monday morning
  • Code Freeze on Wednesday (no more merging of feature PRs)
  • QA starts on Thursday
  • Official packaging on Friday

The actual timeline for QA and the release cycle (weekly, bi-weekly, monthly) can be adjusted according to each company’s situation. The key is to determine what needs to be done at specific times.

This is a survey on version release cycles conducted by foreign peers, with most opting for a bi-weekly release.

When it comes to weekly updates and our multiple teams, it will be as shown in the image above.

The Release Train, as the name suggests, is like a train station, and each version is a train.

If you miss it, you have to wait for the next one. Each Squad team and project choose their own time to board.

This is a great communication interface, as long as there is consensus and adherence to the rules, version updates can proceed smoothly.

For more technical details on Release Train, please refer to:

Once the process and schedule are determined, we can optimize what we do at each stage.

For example, packaging the official version manually is time-consuming. The entire process from packaging, uploading, to submission takes about 1 hour. During this time, work status needs to be constantly switched, making it difficult to do other tasks; this process is repeated for each packaging, wasting work efficiency.

Now that we have a fixed schedule, we directly integrate Google Calendar here. We add the tasks to be done at the expected schedule to the calendar. When the time comes, Google Apps Script will call Bitrise to execute the Fastlane script for packaging the official version and submission, completing all the work.

Using Google Calendar integration has another benefit. If there are unexpected situations that require postponement or advancement, you can directly go in and change the date.

To automatically execute Google Apps Script when the Google Calendar event time arrives, currently, you have to set up the service yourself. If you need a quick solution, you can use IFTTT as a bridge between Google Calendar <-> Bitrise/Google Apps Script. For the method, you can refer to this article.

p.s.

  1. Currently, the Pinkoi iOS Team adopts the Gitflow workflow.
  2. In principle, this consensus is to be followed by all teams, so there should be no requests that break this rule (e.g., special requirement to deploy on Wednesdays). However, for projects involving external collaboration, if there is really no other way, flexibility should be maintained, as this consensus is within the team.
  3. HotFix for critical issues can be updated at any time and is not subject to the Release Train regulations.

Here, more applications of Google App Scripts are mentioned. For details, please refer to: Forwarding Gmail emails to Slack using Google Apps Script.

The last one is using Github Action to enhance collaboration efficiency (PR Review).

Github Action is Github’s CI/CD service, which can be directly linked to Github events, triggered from open issues, open PRs, to merging PRs, and more.

Github Action can be used for any Git project hosted on Github. There are no restrictions for Public Repos, and Private Repos have a free quota of 2,000 minutes per month.

Here are two features:

  • (Left) After completing PR Review, it will automatically add the reviewer’s name Label, allowing us to quickly summarize the status of PR reviews.
  • (Right) It will organize and send messages to the Slack Channel at a fixed time every day, reminding teammates of which PRs are awaiting review (similar to the functionality of Pull Reminders).

Github Action still has many automation projects that can be done, and everyone can unleash their imagination.

Like the issue bot commonly seen in open-source projects:

[fastlane](https://github.com/fastlane){:target="_blank"} [fastlane](https://github.com/fastlane/fastlane){:target="_blank"}

fastlane / fastlane

Or automatically closing PRs that haven’t been merged for too long can also be done using Github Action.

Recapping the effectiveness of automating the packaging of the official version, simply use existing tools for integration; in addition to automation, also incorporate fixed processes to double work efficiency.

Apart from the manual packaging time, there is actually an additional cost in communicating version times, which is now directly reduced to 0; as long as you ensure to get on board within the schedule, you can focus all your time on “discussions” and “development”.

Calculating the effectiveness brought by these two automations, it can save 216 working hours per year.

Automating along with the communication interface mentioned earlier, let’s see how much efficiency can be improved by doing all these tasks together.

Apart from the tasks just done, we also need to evaluate the cost of switching flow. When we continue to work for a period of time, we enter a “flow” state, where our thoughts and productivity peak, providing the most effective output; but if we are interrupted by unnecessary things (e.g., redundant communication, repetitive work), to get back into the flow, it will take some time again, using 30 minutes as an example here.

The cost of switching flow due to unnecessary interruptions should also be included in the calculation, taking 30 minutes each time, occurring 10 times a month, 60 people will waste an additional 3,600 hours per year.

Flow switching cost (3,600) + unnecessary communication due to poor communication interface (1,200) + automation solving repetitive work (216) = a loss of 5,016 hours in a year.

The time saved from the previously wasted work hours can be invested in other more valuable tasks, so the actual productivity should increase by another X 200%.

Especially as the team continues to grow, the impact on work efficiency also magnifies.

Optimize early, enjoy early benefits; late optimization has no discount!!

Recapping the behind-the-scenes of an efficient working team, what have we mainly done.

No Code/Low Code First Prioritize choosing existing tool integrations (as in this example) if there are no existing tools available, then evaluate the cost of investing in automation and the actual income saved.

About Cultural Support

Everyone can be a problem-solving leader at Pinkoi

Everyone can be a problem-solving leader at Pinkoi

For solving problems, making changes; the vast majority require a lot of teamwork to make things better, which greatly needs the support and encouragement of company culture, otherwise, it will be very difficult to push forward alone.

At Pinkoi, everyone can be a problem-solving leader, you don’t have to be a Lead or PM to solve problems, many of the communication interfaces, tools, or automation projects introduced earlier were discovered by teammates, proposed solutions, and completed together.

About how team culture supports driving change, the four stages of problem-solving can all be linked to Pinkoi’s Core Values.

Step One: Grow Beyond Yesterday

  • Strive for improvement. If problems are identified, regardless of size, as the team grows, even small issues can have a magnified impact.
  • Investigate and summarize problems to avoid premature optimization (some issues may only be temporary transitions).

Next is Build Partnerships

  • Actively communicate and gather suggestions from all aspects.
  • Maintain empathy (as some problems may have the best solution from the other party, balancing is essential).

Step Three: Impact Beyond Your Role

  • Utilize your influence.
  • Propose problem-solving plans.
  • Prioritize automation solutions for tasks related to repetitive work.
  • Remember to maintain flexibility and scalability to avoid Over Engineering.

Lastly, Dare to Fail!

  • Courage to practice.
  • Continuously monitor and dynamically adjust solutions.
  • After achieving success, remember to share the results with the team to facilitate cross-departmental resource integration (as the same problem may exist in multiple departments simultaneously).

The above is a sharing of the secrets of Pinkoi’s high-efficiency engineering team. Thank you all.

Join Pinkoi now >>> https://www.pinkoi.com/about/careers

For any questions and feedback, feel free to contact me.

===

本文中文版本

===

This article was first published in Traditional Chinese on Medium ➡️ View Here



This post is licensed under CC BY 4.0 by the author.

Using Google Apps Script to Forward Gmail Emails to Slack

Crashlytics + Big Query: Creating a More Immediate and Convenient Crash Tracking Tool