oi里有啥优秀的调试技巧?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oi里有啥优秀的调试技巧?相关的知识,希望对你有一定的参考价值。
有很多人把算法框架设计归为算法设计,而把细节全部归为实现,个人认为这在算法竞赛中是十分糟糕的。如果你这么做,那么你在实现的过程中,就会有非常非常多、杂的细节需要去考虑,最终导致你难免会有考虑不到的地方。
建议把算法的细节归入算法设计。当你的算法设计涵盖了几乎所有的算法上的细节、以及足够多的纯实现上的细节,你在写代码的时候就有更多的精力用来放在你的程序是否严格地实现了你的算法上,在这样的情况下,如果你再有意识地去顾及这些,那么你的bug就很自然地变少了。
我也说个我自己的故事吧。我高二的时候大部分时间学校是不让停课的,然而我又并不喜欢在手机上写代码,于是我就选择了在纸上写代码(每天进教室前记几个题,然后上课的时候想&写,放学之后敲&debug)。可能更多的大佬们会有在手机上写代码的经历。但我觉得在纸上写题给我的帮助是另一方面的,因为在纸上写字是不能backspace的,于是它就强迫我想清楚框架再开始动笔、想清楚所有东西再写每一句话(当然,这也是因为我有一点强迫症,这个方法对那些【觉得纸上涂涂改改一堆都无所谓的人】可能并没有效果……)。
我考场上习惯先写暴力,然后写正解,用批处理挂起来对拍。这时候可以出去上个厕所,回来的时候对拍没挂就基本上对了。
(首先得保证暴力不挂。。。)
写正解的时候,可以写一部分调一部分,而不是整个程序写完再一起调。
比如写一个树剖,先把线段树的部分写好,自己出一些数据输进去测试一下。然后再写树上的部分,最后一起调试。
亲测这样可以避免很多SB错误,比如变量名打错,循环打反之类的。
首先是负数……如果见到负数那就大概是爆int了,这时我一般把所有的int都改成ll。
如果出现别的问题,我一般的做法是手算一遍。然后打出中间结果,看是从哪里开始和手算不合的。
唔...犹记候选队胡策的第一场...某钢琴大佬出了一道码农题..
我和吨老师和假老师连麦做胡策..说是开黑..结果变成了3个人怼3道题(选对题的我最后是唯一一个A掉题的人)
那场比赛让我发现了一个极其优秀的调试方法..
那就是..
尽量拒绝调试..
高三之后..由于高二的时候因为调试丢过很多分..于是个人喜欢在平时做题的时候..不把所有细节想完不动手。这些细节甚至细化到类似于这个函数我要用多少个临时变量..这样可以最大限度的减少你出错的概率。然后为了防止手误,我习惯把不同的变量名尽量区分开,比如用了N就不会用NN, N2这种东西。 同时尽量用大写变量名..因为小写的时候容易一下就晃过去了..大写的话你会习惯性确认一遍是不是大写了...然后有手误的话就会发现..
到退役前我经常是行云流水写完代码改完编译错误(基本上是没看到的手误, 体现了区分变量名的优越性)..自信sub返回AC..(虽然退役前的最后一道题就这么咖喱给给了)
比如胡策的时候那道码农题
我从看完题到写完它花了两个多小时, 期间吨老师和假老师听见我不断在吐槽这道题有多难写..结果编译通过之后就直接AC了..
总之我觉得人不能依赖调试, 调试是你效率最低的时候..在比赛上越调你就会越慌张..与其期待调试技巧, 不如尽量避免调试, 提高一次写对的概率..这件事情在oi里面其实是不难的, 只要平时写题养成好的习惯...就绝对可以做到..
以上
21期:chrome的调试技巧
来自罗立雄同学的分享:《chrome的调试技巧》
前言
开发最重要的环节之一就是调试,web端的开发和调试工具没有比chrome更优秀的了,下面就讲讲怎么通过chrome的开发者工具对网站进行迭代、调试和分析。
注意:以下例子均为Chrome版本 70.0.3538.102(正式版本) (64 位)
参考chrome开发者工具官方文档
1、打开Chrome 开发者工具
有以下3种方式:
1、快捷键:Ctrl+Shift+I/F12 (Windows) 或 Cmd+Opt+I (Mac)
2、在页面元素上右键点击,选择 “检查”
3、在Chrome菜单中选择 更多工具 > 开发者工具
2、一图搞定debug
2.1 文件区
在文件区选择要调试的文件index.js,这里展示的就是完整的项目目录
可以通过快捷键ctrl+p快速查找文件
2.2 代码区
在代码区找到要调试的代码行打上断点,按F5进入debug,可以看到代码停在断点(第4行)处
可以在devtools直接修改当前debug断点后的代码,ctrl+s保存文件后可以看到修改的代码效果,达到理想的效果可以**右键>save as...**保存修改后的debug文件
2.3 调试按钮
从左往右依次是:
Pause/Resume script execution:暂停/恢复脚本执行(程序执行到下一个断点停止)
Step over next function call:执行到下一步的函数调用(执行但不进入)
Step into next function call:进入当前函数(一步一步执行每一行代码)
Step out of current function:跳出当前执行函数
step:与Step into next function call一样
Deactive/Active all breakpoints:关闭/开启所有断点(不会取消)
Pause on exceptions:异常情况自动断点设置(Exception 断点)
2.4 参数区watch
在参数区可以添加想要监听的参数或表达式的变化
也可以直接在文件里通过鼠标悬停、选中表达式的方式查看它们的变化
2.5 例子
调试的原理很简单,找到想要调试的文件,打上断点,一路step+分析直到找到自己想要的。它的难点在于调试哪个文件、监听哪些参数,找到合适的切入点,调试真没什么。
如上图,加法器计算两个数字的和,1 + 2 = 12,这很明显不是我们想要的结果。
面对复杂项目或组件时,新手往往不知道从何debug起,其实只要找准你想了解什么功能,复杂的一个一个拆分就能分析了。比如加法器的debug。
1、在第4行打下断点
2、同时在watch里监听x、y两个参数
3、F5刷新进入debug调试
4、通过Step into next function call一步步调试代码,同时可以看到watch里两个参数的变化4.1、因为使用了jquery,Step into会进入到jquery内部,不要慌,Step out of current function跳出jquery,返回自己的函数
4.2、这里4、5行代码都用了jquery的val()方法,所以也可以使用Step over next function call跳过第4行直接进入第5行5、通过分析watch里的x、y参数发现,通过val()方法获取到的x、y是字符串,导致+变成字符串拼接了
6、parseInt将x、y转换类型就可以得到想要的结果了
3、资源面板(Sources)
开发过程中无法避免错误,新手最喜欢用的就是console.log来查找和修正代码中的错误,效率太低,只适合明确地只想看到极少数结果的情况。下面就讲讲怎么使用chrom devTools精准、高效的定位并解决问题。
断点有以下7种类型:
断点类型 | 描述 |
---|---|
Line-of-code | 在确切的代码区域 |
Conditional line-of-code | 在确切的代码区域,但仅在某些其他条件为真时 |
DOM | 在更改或删除特定DOM节点或其子节点的代码上 |
XHR | 当XHR URL包含字符串模式时 |
Event listener | 在触发事件(例如click)之后运行的代码上 |
Exception | 在抛出捕获或未捕获异常的代码行上 |
Function | 每当调用特定函数时 |
3.1、Line-of-code 断点
明确地知道自己想要调试的代码位置
1、打开Chrome开发者工具的Sources tab页
2、找到需要打断点的文件
3、在文件左侧的行号列(左键单击或者右键>Add breakpoint)打上断点
与line-of-code等效的还有debugger,两者的效果都是代码运行到断点前停止。debugger的缺点很明显,因为是写在代码里面的,需要删除断点的时候,要进去一个一个文件的删,实在太过低效,不建议使用debugger。 Chrome开发者工具提供了Breakpoints pane 管理断点,稍后会讲到。
3.2、Conditional line-of-code 断点
与line-of-code类似,需要明确地知道自己想要调试的代码位置,但是可以提供条件使代码进入断点
1、打开Chrome开发者工具的Sources tab页
2、找到需要打断点的文件
3、在行号列右键>Add conditional breakpoint
4、在弹框里输入断点条件,回车确定,可以看到一个橙色的断点形成
尝试改变断点的条件,可以发现在不满足条件时不会进入断点
管理 line-of-code 断点
在 Breakpoints pane右键操作,可以禁用 或 移除 line-of-code 断点
在 Breakpoints pane可以查看、管理所有的断点,比如暂时禁用断点,下次再激活,方便程度远胜debugger。 针对debugger,Breakpoints pane提供了Deactivate breakpoints来禁用:
console.log(1); debugger; console.log(2); debugger;
Deactivate breakpoints会禁用代码里所有的debugger以及(Conditional)line-of-code 断点,而Disable all breakpoints只会禁用掉(Conditional)line-of-code 断点
3.3、DOM断点
监听dom节点或其子节点变化时用到的断点
1、打开Elements tab页
2、找到需要打断点的element位置
3、右键点击选中的element,在弹出的菜单选择**Break on **,有3种属性可供选择
3.3.1、Break on三选一之Subtree modifications
在当前节点添加、删除、改变子节点时触发
<div id="div1"> // 在这里断点Subtree modifications <p id="p1">文本1</p> <p id="p2">文本2</p> </div> ...... // 通过jquery改变#div1下的p2的文本内容$(function () { var div1 = $('#div1') setTimeout(function () { div1.find('#p2').text('文本2变了') }, 1000) }) ...... // Remove any remaining nodeswhile ( elem.firstChild ) { elem.removeChild( elem.firstChild ); // 1秒后断点会跳转到jquery代码这里 } // 跳出断点后,#p2的文本改变为"文本2变了"
3.3.2、Break on三选一之Attributes modifications
在当前选定的节点上添加或删除属性时或属性值更改时触发
与Subtree modifications相似,通过jquery改变当前节点属性时,断点会跳转到对应的jquery代码处
3.3.3、Break on三选一之Node Removal
删除当前选定的节点时触发
与Subtree modifications相似,通过jquery删除当前节点属性时,断点会跳转到对应的jquery代码处
注意:Break on的3种属性有延迟性,即需要在页面初始化完成后再修改选定节点的时候触发,断点跳转到改变当前节点的js代码处
3.4、XHR 断点
在XHR的请求URL包含指定字符串时中断,devTools在XHR调用send()的代码行上暂停。用于快速定位页面发起请求的url不正确的代码位置。
1、打开Sources tab
2、进入XHR Breakpoints pane(一般就在Breakpoints pane下面)
3、点击面板空白处或者右上角的“+”添加需要监听的url字符串,回车确定
创建一个请求链接中包含org的XHR请求(比如用$.ajax)
如上图,可在ajax的xhr.send处看到options里的url中包含了org
3.5、Event listener 断点
暂停事件触发后运行的事件侦听器代码,例如单击、鼠标事件等。
1、打开Sources tab
2、进入Event listener pane(一般就在Breakpoints pane下面几个)
3、任选一个Event listener
如上图,可以看到,在没有打断点的情况下,勾选了Event listener Breakpoints下的click,当点击div1时,代码会在div1.addEventListener触发click事件的代码行中断。
注意:如果使用的不是原生的addEventListener,而是使用了库,比如jquery,Event listener 断点会在jquery内部监听click事件的代码行中断。
3.6、Exception 断点
在抛出捕获或未捕获的异常的代码行上暂停。
1、打开Sources tab
2、点击Pause on exceptions(“播放中”的样子)
3、勾选Pause On Caught Exceptions可以在未捕获的异常(Uncaught DOMException)代码行暂停
如上图,Exception 断点会在throw "whoops"处暂停,如果勾选了Pause On Caught Exceptions,以jquery为例,一路debug下去,会看到一个个的DOMException,类似下面这样的:
3.7、Function 断点
这是一个在chrome devtools控制台使用的断点方式,在chrome devtools控制台运行如下代码:
function add(a, b) { let result = a + b; // DevTools会暂停这行代码 return result; } debug(add); // 暂停sum函数,不能用字符串 add();
上面这段代码等效于 line-of-code 断点。一般我们在chrome devtools控制台运行代码是不能debug的,可以通过这种方式进入“VM1124”之类的文件调试我们在控制台运行的代码
4、网络面板(Network)
网络面板记录页面上每个网络操作的相关信息,包括详细的耗时数据、HTTP 请求与响应标头和 Cookie等等。
1、使用 Network 面板记录和分析网络活动
2、整体或单独查看资源的加载信息
3、过滤和排序资源的显示方式
4、保存、复制和清除网络记录
5、根据需求自定义 Network 面板
4.1、 网络面板概览
网络由五个窗格组成
1、Controls:使用这些选项可以控制Network面板的外观和功能
2、Filters: 使用这些选项可以控制在 Requests Table 中显示哪些资源。按住 Cmd (Mac) 或 Ctrl (Windows/Linux) 并点击过滤器可以同时选择多个过滤器
3、Overview: 此图表显示了资源检索时间的时间线。如果看到多条竖线堆叠在一起,则说明这些资源被同时检索。
4、Requests Table:此表格列出了检索的每一个资源。默认情况下,此表格按时间顺序排序,最早的资源在顶部。点击资源的名称可以显示更多信息。 右键点击任何一个表格标题可以添加或移除信息列。
5、Summary: 此窗格可以一目了然地显示请求总数、传输的数据量和加载时间。
提示:
1、启用Filters窗格的 Preserve log 复选框可以保留网络日志
2、在Overview窗格可以通过双击左键把选择范围放到最大
4.2、 捕捉屏幕截图
网络面板可以在页面加载期间捕捉屏幕截图,此功能称为幻灯片。
在Controls窗格点击摄影机图标可以启用/关闭幻灯片功能。重新加载页面可以捕捉屏幕截图。
1、可以通过屏幕截图分析页面渲染顺序
2、捕捉屏幕截图尚未结束时,切记不要切换到当前chrome窗口的其他标签页,这会导致捕捉失败
屏幕截图显示在概览(Overview)上方。双击屏幕截图可查看放大版本。
4.3、DOMContentLoaded 和 load 事件信息
网络面板突出显示两种事件:DOMContentLoaded 和 load。
解析页面的初始标记时会触发 DOMContentLoaded(dom内容加载完成)。 此事件将在 Network 面板上的两个地方显示:
1、Overview 窗格中的蓝色竖线
2、Summary 窗格中的蓝色文字处
页面完全加载时将触发load(页面上所有资源,包括图片、音频、视频等加载完成,在DOMContentLoaded被触发之后才触发)。此事件显示在三个地方:
1、Overview 窗格中的红色竖线
2、Requests Table 中的红色竖线
3、Summary 窗格中的红色文字处
点击资源名称可以查看与该资源有关的更多信息,比如大小、加载时间等。
点击任意资源,在右侧打开的窗格>Timing,在此可以查看文件的加载时间分析
4.4、模拟网络连接
可以通过 Network 面板开启网络调节。从下拉菜单中选择要应用网络节流和延迟时间操控的连接。
点击 Add... 选项可以自定义网络
结尾
文章到此结束,由于水平和经验有限,如有纰漏或建议,欢迎留言。如果觉得不错,欢迎关注海致星图,谢谢您的阅读。
以上是关于oi里有啥优秀的调试技巧?的主要内容,如果未能解决你的问题,请参考以下文章