開源日報 每天推薦一個 GitHub 優質開源項目和一篇精選英文科技或編程文章原文,堅持閱讀《開源日報》,保持每日學習的好習慣。
今日推薦開源項目:《背景消失魔術 Background-Matting》
今日推薦英文原文:《Find and Fix Bugs Like a Pro With Divide and Conquer》

今日推薦開源項目:《背景消失魔術 Background-Matting》傳送門:GitHub鏈接
推薦理由:科學發展到一定程度就會變成魔術這句話可不是吹的。這個項目能夠將背景去除做到更高層面——不再需要那個突兀的綠色背景板,即使是對於正常的背景環境,它也能識別並清除,讓主體基本沒有違和感的保留下來。唯一的缺點估計就是,隨著它的發展,造假的視頻也會獲得更好的技術吧。
今日推薦英文原文:《Find and Fix Bugs Like a Pro With Divide and Conquer》作者:Szymon Adamiak
原文鏈接:https://medium.com/better-programming/find-and-fix-bugs-like-a-pro-with-divide-and-conquer-d55f3cf91154
推薦理由:我相信不少人在剛學習調試代碼的時候都喜歡把代碼一分為二

Find and Fix Bugs Like a Pro With Divide and Conquer

If I could learn only one thing about debugging, I』d learn to divide and conquer

Divide and Conquer

Divide and conquer is an algorithm design type. It works by recursively breaking a problem in two (or more) smaller problems of a similar nature. If you can solve the little issue, you can solve a bigger one too. Divide and conquer is used primarily for sorting or finding the closest pair of points.

But divide and conquer is more than that. It』s a mindset you can use to debug your apps.

Debugging

Debugging is a tiring task for many developers. You need to know your intended inputs and outputs. You need to understand the code and the flow of the app. Often finding a mistake is much harder than fixing it.

Countless programmers hate debugging for another reason. We prefer making things than fixing them. It』s a lot more satisfying to create new code than to spend half a day seeking an error and finally changing two lines.

The naive approach to finding bugs is going through the code line by line, logging data, or setting breakpoints. You can use that in trivial apps or if you know almost exactly where the mistake is.

But typically, you need to debug a big application, frequently before you can familiarize yourself with the codebase. Making tons of logs will take forever. You have to do better than that.

Basic Divide and Conquer

The straightforward use of divide and conquer in debugging is to split the codebase in half, and add a log there. If the log works and prints correct data, we can assume that everything up to that point works fine; if not, the error is in the first half of the code.

Next, we take the suspicious half of the code and put another log in the middle. We repeat the procedure until we discover the issue. Each time we cut the remaining codebase in half, so we should find the error in just a few steps. That』s a lot better than logs all over the code, but we can go a step further.

Educated Guesses and Divide and Conquer

Imagine your app consists of thousands of lines. It』s hard to find the middle, and you』ll need dozens of logs to discover the culprit. Now it』s the time to take a step back and think before adding logs.

Start with answering a few questions and making some hypotheses.

What broke? Is it likely that some string transformation failed; maybe data returned is not in the type you expected, or is there another issue?
  • Do you have some tests or checked parts of the code? If so, the bug probably isn』t there.
  • When did the bug occur? Did everything work fine before? What changed? Maybe inputs are different now, or maybe the code worked two commits back.
When you answer these questions, you』re ready to make an educated guess about the nature of the bug.

Every assumption can prove wrong, but your goal isn』t to be correct. It』s to find the most probable culprit so you can pinpoint the suspicious parts of code.

When you have a few hypotheses, zoom in on the most likely and use divide and conquer. If you find the bug, that』s great. If not, proceed to the next hypothesis.

Divide-and-Conquer Example

I』ll show you a real-life example of divide-and-conquer debugging. The code below takes an HTML form and creates a PNG image of it. Later, it sends both the image and the form data to the server and redirects to another page.

Specifically:
  • toPng takes the HTML element and returns an image (base64-encoded data)
  • dataUrltoFile takes base64-encoded data and returns a file
  • saveFormScreenshot and saveDraft send data to the server
  • setRedirect redirects to another page
The code worked well in Chrome, but I had a problem with Safari. The program didn』t return anything — no data, no error.

My (naive) approach

I』ve logged a response right before the middle of the code, between lines 4 and 5. The log never ran, so the issue was above.

My next step was to log formAsFile between lines 2 and 3. That log didn』t run either.

Now I got my answer — the bug is hidden in the first line. The function toPng never finished.

Educated-guess approach

In the first place, I should have analyzed why I didn』t get an error. I should have gotten one if there were issues with the request to the server. So the most probable place of failure was in lines 1 or 2. A simple log in the second line would suffice to tell me I never got the image out of the HTML.

Conclusion

Divide and conquer is a handy approach to finding bugs. You need it in your toolkit.

And if you』re wondering what the underlying bug was — the HTML element was too big for Safari to convert to the image.
下載開源日報APP:https://openingsource.org/2579/
加入我們:https://openingsource.org/about/join/
關注我們:https://openingsource.org/about/love/