说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

深度解析:清理烂代码

HTML文档下载 WORD文档下载 PDF文档下载
烂代码不一定是问题,只要它们没有出错,没有人会对它嗤之以鼻。但不幸的是,它们没被发现的概率太小了。错误会被发现。需要新的功能,新系统发布了。现在你不得不面对这堆恐怖的代码,试着去清理它们。

猜猜看怎么了!你正”继承“(接收)了一堆混乱的旧代码。恭喜你!现在都是你的了。混乱的代码可能来自任何地方。中间件,网络,可能来自你自己的公司。

你知道在一个角落里有一个家伙,没有人过去管他在做什么。猜猜看他一直在做什么?辛辛苦苦写出了代码,却是一堆烂代码。

你还记得这个模块是一个家伙几年前写的,在他离开公司之前。这个模块已经有20个不同的人加过补丁,进行过代码修复,而且他们也并不理解代码到底是做了什么。是的,就是这样的代码。

或者你从网上下载下的开源的软件,你知道它非常的可怕,但是它解决了一个非常专的并且对你来说非常棘手的问题,解决这个问题你可能要花上几年。

烂代码不一定是问题,只要它们没有出错,没有人会对它嗤之以鼻。但不幸的是,它们没被发现的概率太小了。错误会被发现。需要新的功能,新系统发布了。现在你不得不面对这堆恐怖的代码,试着去清理它们。这篇文章为这种不幸的情况提供了一些建议。

0. 值得清理么?

第一件你需要问问自己的事情就是代码值得清理么。我不是说当问到是否要清理代码时,你一定要回答是或者一定回答不是。是你对代码负有责任,也是你需要一直面对它们直到最终写出的代码是你乐意维护的,也是你很自豪的放入代码库的。

如果你觉得就算代码看起来很可怕,也不值得浪费你本来就很紧张的时间来修复它们。所以你仅仅做了最最微小的调整解救燃眉之急。

换句话说,你也可以将代码看作自己的,也可以看作是别人的。

两种情况都有优缺点。优秀的程序员看到烂代码时会觉得很难受。他们会拿出火把和叉子并且高呼:“太乱了,太乱了”。这是一种优秀的品质。

但是清理代码是一个繁杂的工作。很容易就低估了时间。甚至有时候和从头开始写代码一样的耗时。并且短期并没有带来任何的短期效应。两个星期的时间清理代码并不会带来任何新的功能,但有可能引入一些新的错误。

另一方面,如果长时间不清理代码可能会带来灾难性的毁灭。混乱是代码的杀手。

所以,这并不是一个容易做出的决定。需要考虑一些事情:

● 你期望对这段代码做多少改变?你是希望仅仅修改这个小错误呢,还是这段代码还要使用多次,所以你希望将它“调教”的好些,并且加上新的功能。如果仅仅是修复一个错误,那么最好是别打草惊蛇。然而,如果这个模块你需要长期折腾的话,那么现在开始花点时间来清理它吧,之后会省掉很多烦恼。

● 你需要或者是你想引入上游的更新吗?它是一个正在开发当中的开源项目吗?如果是的话,并且你想做改变的是上游的代码,那么你不能对代码有大的改动否则当你每次pull代码的时候都会经历一场merge的噩梦。所以你需要做一个友好的团队合作者,接受这个错误,将带有你修正的代码补丁发给代码的维护者。

● 要做多少工作?你一天内实际上能清理多少行代码?我们估计多于100行,少于1000行,好,我们假设是1000行。所以如果一个模块有30,000行代码的话,你可能需要一个月的时间。你有那么多时间吗?值得这么做么?

● 它是你核心的功能吗?如果这个模块只是边缘的模块,譬如字体渲染或者图像渲染,你可能并不在意它是否是乱七八糟的。你可能全盘不要,将来用另外的东西来代替,谁知道呢。如果这段代码关乎核心的性能,你需要慎重对待。

● 这段代码有多糟糕?如果代码仅仅有一点点糟糕,那么可能你还是可以忍受的。如果它是不可理喻的,令人崩溃的话,那么我们就必须对它下手了。

1. 建立测试用例

要认真清理一段代码意味着花一段时间来彻底清理它。你可能会毁坏它们。

如果你有一个比较好的测试用例,有一定的覆盖率,你将会很容易知道什么已经损坏了,并且你能够很快的知道你犯了什么愚蠢的错误。想要节省建立测试用例的时间在整个的清理代码的过程中是可笑的。建立测试用例吧。这是你第一件需要做的事情。

单元测试是最好的,但是所有的代码并不适应单元测试。如果单元测试过于繁琐,就换用集成测试吧。譬如,一个游戏关卡中需要一个人物完成一系列的动作和你清理的代码有关。

这样的测试更加耗时,所以不可能在每一次更改之后都测试一次,虽然这是最理想的情况。因为你将每一次改变都放到了版本控制系统中,所以情况还不是那么糟糕。所以每一段时间(比如,五个更改)就测试一次。当你发现了一个问题时,你可以通过二进制搜寻最近的几次commit中找到什么地方导致了问题的发生。

如果你发现了测试没有发现的问题,确保将这个也加入到测试中,以便将来可以测试它。

2. 使用代码版本控制系统

还有人需要被告知要使用代码版本控制系统吗?我希望没有。

清理工作是很关键的。你可能要做很多很多小的修改。如果什么地方出错了,你想回顾版本历史,你可能找到它错在哪。

如果你和我一样,你可能有时重构(清理愚蠢的类)的时候会出错,并且后来意识到这并不是个好的点子,或者这是个好点子,但是如果先做了什么之后所有的一切会变得更简单。所以你想快速的恢复一切到原状并且重新开始。

你的公司应该已经有代码控制系统了,你可以在不同的分支进行修改,在不打扰别人的情况下随意的commit。

就算情况不是这样的,你也应该使用版本控制。下载Mercurial(或Git),创建新的仓库,将代码从你们公司的愚蠢的系统中签出并放在这里。在库中commit你的更改。当你完成了之后你可以将所有的一切merge到那愚蠢的系统中。

拷贝库到一个代码控制系统中仅仅需要几分钟。很值得这么做。如果你不懂Mercurial,花一个小时学习它。你会为你这么做感到高兴的。如果你愿意的话,花30个小时学习下Git(我是开玩笑的!并不用这么久。现在是“nerd”战斗的时候了!)

3. 每次仅仅做一个小小的改动

有两种方法改进坏的代码:革命和改革。革命是用火把一切都烧掉,从新写一遍。改革是在不破坏的基础上每次只进行一点小小的改变。

这篇文章是关于改革的方法。我不是说革命的方法从来不是必要的。有时代码太糟糕了,需要用革命的方法。但是那些觉得改革的进度太慢的人们往往会鼓励改革,然而经常没有意识到问题的复杂性,并最终并没有比现存的系统更好。

Joel Spolsky写过一篇经典的文章,他没有掉入到这个紧张的争论的陷阱中。

改革的最好的方法就是一次只做一个小的改变,测试它,并且commit它。当一个改变很小时,它更容易理解改动的后果以及确保改动不会影响现有的功能。如果什么地方出错了,你仅仅需要核查很少的一部分代码。

如果你开始做更改并且意识到改得很糟糕,那么你恢复到上一次的commit,不会损失太多的无用功。如果你过了一段时间才发现什么地方有细微的差错,你可以在版本历史中使用二进制搜找到导致问题的更改。

最常见的错误就是一次进行多处更改。譬如,当去除不必要的类层次的势后,你发现API的方法并不是像你喜欢的使用方法,而你打算重新组织它们。不要这么做!先去除层次结构,commit之后再更改API。

聪明的程序员懂得组织,所以他们也不需要太聪明。

试着找一个途径,沿着这个途径你可以把代码变成你想要的模样,每次只有一点点改动。譬如,第一步你重命名方法,使之名字更合理。下一步,你可以将成员变量变成方法的参数。然后将算法变得更清楚些,等等。

如果你开始做更改,并且发现比你原先设想的改变要大,不要害怕又退回去,使用更小的更简单的步骤去完成同样的事情.。

4. 不要同时清理代码和修正代码

这是(3)的结果,但是仍然很重要。

这是一个常见的问题。你开始察看一个模块,是因为你想加入某个新功能。然后你发现这个代码相当的糟糕,所以你开始重新组织它并且加入新的功能。

问题在于清理代码和修正错误是完全不同的目标。当你清理的势后,你想让代码看起来更好,而没有改变它的功能。当你修正错误时, 你想改变功能。如果你同时清理代码和改正错误,很难保证清理不会改变什么。

先清理代码,然后再在一个干净的基础上,加入新的功能。

5. 删除你没有使用的功能

清理的时间正比于代码的数量,复杂性和糟糕的程度。

如果代码的功能你目前没有使用,而且在可预见的将来也不会使用,那么就删除它,这会减少你浏览的代码数,降低复杂度(删除不必要的概念和依赖)。你会清理的更快的,而且最后的结果会更简单。

不要留着代码仅仅因为“谁知道呢,你可能某一天需要它”。代码是有代价的 – 它需要被移植,修正错误,被阅读以及被理解。你有更少的代码,就更好。就算在最不可能的情况下,你需要这个旧代码,你也能从代码库中找到它。

6. 删除大部分的注释

烂代码很少会有好的注释。它们通常是这样的:

// Pointless:    // Set x to 3    x = 3;// Incomprehensible:    // Fix for CB (aug)    pos += vector3(0, -0.007, 0);// Sowing fear and doubt:    // Really we shouldn't be doing this    t = get_latest_time();// Downright lying:    // p cannot be NULL here    p->set_speed(0.7);

看看整个代码。如果一个注释对你来说不再有意义,也对你理解代码没什么帮助,那么就删除它。否则你只会浪费你的脑力去理解一堆对你理解代码没帮助的注释。

同样的删除那些已经被注释掉的代码。如果你还需要它的时候,它还在你的代码仓库中。

甚至如果注释是正确而且有用的,记住你还可以重构你的代码。可能当你完成重构后,这些注释不再正确了。这个世界上还没有一个单元测试能够告诉你注释是否已经损坏了。

好代码需要很少的注释因为代码自己已经自说明了而且很容易理解。拥有好名字的变量不需要注释去解释它们的用途。函数如果有好的输入输出,没有特殊情况时是不需要说明的。简单的写得很好的算法在没有注释的情况下也是容易理解的。而断言记录了条件和预测。

大部分情况下,最好的做法是删除所有旧的注释,专注于让代码变得干净和具有可读性,然后再在需要的地方添加代码 – 这些注释反应新的API的用途以及你对代码的理解。

7. 避免共享的可更改的状态

共享的可更改的状态是理解代码的最大阻碍,因为它允许隔一段距离的行动,一段代码可以改变另一段完全不同的代码的行为。人们常说多线程是困难的。事实上,是由于线程共享了可更改的状态,才导致了问题。如果你能避免它们的话,多线程并不复杂。

如果你的目标是写高性能的软件,你应该不能避免一切可更改的状态,但是你的代码仍然可以从减少它而获益。为了“大部分功能完善”而努力吧,确保你确切的知道什么状态在什么地方改变了,并且知道原因。

共享的可更改的状态来自不同的地方:

● 全局变量。最经典的例子。现在每个人都知道全局变量的坏处。但是要注意(有时人们会忘记),全局变量是唯一的会造成问题的共享的可更改状态。全局常量并不糟糕,Sprintf也不糟糕。

● 对象 – 装有乐趣的大袋子。对象能够集合很多方法,无疑可以共享很多可变的状态(成员)。如果一个懒惰的程序员需要将一些信息在方法之间传递的话,她可以建立一个新成员,所以可以依照需要来读它和写它。这非常像全局变量。多么有意思!当一个对象有越来越多的成员时,问题就越来越严重。

● 巨大的函数。你可能已经听说它们了。这种神秘的产物栖息在最黑暗的代码洞穴的最底层。心眼坏的程序员在阴暗的酒吧里谈论它们,他们的理智被他们遇见的代码摧毁了:“我不停地向下翻向下翻,我不能相信自己的眼睛。居然有12,000行。”当函数足够长的时候,它们本地变量将和全局变量一样糟糕。我们不可能知道改变2000行之后的一个局部变量会有什么效果。

● 引用和指针参数。引用和指针参数没有被声明为const被传进函数时,可以在被调用者,调用者以及任何能被传递相同的指针的对象之间充当共享的可变的状态。

这里有一些避免共享的可更改的状态的建议:

  • 将较大的函数切分成较小的函数。
  • 将较大的对象切分成较小的变量,将相关的成员放在一起。
  • 将成员变成private。
  • 将函数声明const,返回结果,而不是可更改的状态。
  • 将函数声明static,从参数获得值,而不是从共享状态那里取值。
  • 避免完全使用对象,实现纯净的功能,不要引入副作用。
  • 将本地变量声明const。
  • 将指针和引用声明const。

8. 避免不必要的复杂性

不必要的复杂性通常是过度工程化的结果 – 支持的结构(如序列化,引用计数器,虚拟接口,抽象工厂,访问者等等)会拖慢真正有实际功能的代码。

有时候过工程化是因为一些项目开始的时候有一些更大的野心,多于实际完成的。更多的情况,我想是因为程序员读了关于设计模式的书之后和瀑布模型之后的想法,他认为过工程化会形成更“坚固”和“高质量”的产品。

通常,这个笨重的,僵化的,过度复杂的模型不能适应功能需求,而这是设计师不期望的。那些功能可能之后用hack的方式来实现,成了在象牙塔最顶上的螺栓和后门,变成了神经错乱的混合结构。

治愈过度工程化的方法就是YAGNI(you are not gonna need it)-你不需要它!只有当需要一个东西的时候才建造它。当你需要它的时候才建立更复杂的东西,而不是在你需要之前。

避免不必要的复杂性的一些实际的方法:

  • 移除你没有用到的东西(就像上面建议的一样)。
  • 简化必要的概念,避免不必要的概念。
  • 移除不必要的抽象,用实际的实现来替代。
  • 移除不必要的虚拟化,并且简化对象的结构。
  • 如果一个设置曾经使用过,那么就避免在用另外的配置来运行这个模块。

9. 就这么多了

现在开始清理你的“房间”吧!

来自:伯乐在线

谈应用分发控制力:还是渠道为王 Unity亚洲开发者大会:手游半衰期越短,开发者手中的机会越多 《割绳子》开发者:俄罗斯双胞胎的奋斗史 曾应聘Rovio未果 Win7系统上常见IE 10问题汇总 如果苹果推廉价手机,市场份额会不会超过安卓? 移动互联网下,如何做儿童新音乐? 第三届“中科杯”全国软件设计大赛正式启动 注重稳定性 Docker 0.2.0发布 何谓机器学习 机器学习能做些什么? 艰难的决定:EA裁员10%,殃及PopCap 或提前落地!Amazon和Facebook急聘SDN工程师(Python优先) 轻松完成网站提速:来自Google、淘宝等的Nginx PageSpeed模块 Touch-Pay发布 移动联通在手机游戏领域联合推融合计费SDK 如何组织大型JavaScript应用中的代码? Robert Scoble:戴Google Glass两周后 再也不想摘下它 赶时髦?Facebook CEO 2013年将领取1美元年薪 蓝港在线CEO王峰:我在网络游戏行业十年从业记 CMDN Club 27期:从儿童音乐教育到移动碎片化管理 聚焦全球移动市场——你所不知道的俄罗斯 MemSQL:号称世界上最快的内存-关系型数据库 兼容MySQL但快30倍 PC衰落 Intel转投Google挖掘移动市场潜力 移动周报:500元体感、精确到0.01毫米的Leap Motion TUP第29期:王淮、龚世海谈如何打造优秀的技术团队 一网打尽13款开源Java大数据工具,从理论到实践的剖析 从用户体验的善与恶说起,做用户爱“玩”的教育应用 三大主流开源硬件对比:Arduino vs BeagleBone vs Raspberry Pi “BlackBerry 10移动应用开发大赛”应用推荐 Java程序优化的一些最佳实践 Heka:Go编写,来自Mozilla,高效、灵活的插件式数据挖掘工具 Anchora鲁为民:PaaS是我的兴趣 次世代IDE Light Table 0.4发布 带来众多更新和改进 深入浅出这本书过时吗? 急急急急急急急!但很简单! 深入浅出过时了吗? 关于浏览器的紧急求救 懂串口编程的哥们帮帮忙?? 如果数据窗口显示有数据,如何用代码实现数据窗口不显示数据? 怎样使JSP和Servlet共用一个Bean?急急急 如何才能获取运行时指定一表的字段信息和索引信息 请问如何定义任意组合的热键?请给例子 怎样让工具条缺省是漂浮着的啊?(先答先给分,50分全送) 3000-5000元寻求软件开发合作! 怎么把图片设为桌面? 3000-5000元寻求软件开发合作!!! tfilesteam怎么才能显示出文本 pb中如何执行sp_who并得到结果 3000-5000元寻求软件开发合作!! 怎么用IHTMLDocument2接口查询IHTMLElement接口 3000-5000元寻求软件开发合作!!!!! 日期数据类型的问题;MDI子窗口的问题。 top851 用VC打开SQL数据库问题! QR怎樣讓報表分列 诚征工程外包 我的AOUTOCAD总装不上? 如何实现在asp页面上操作,备份数据库? PB中发送HTML邮件问题 各位仁兄。我要在内存位图上作画。怎么搞。help.255' 刷新另一个页面的问题 ■■BCB没有PTR函数?DELPHI中的PTR对应BCB中的函数是什么?请高手指教■■ 我加不起分,怎么回事? 求一个位运算的算试 《深入浅出MFC》中一个小问题不明白! 关于键盘消息的问题 谁有《Linux内核源代码分析》.发给我或告诉我连接都给分 在SESSION STARTZ()中是不是不能用ASP脚本程序? 问一个菜鸟级的问题。答者有分。 为何我用CDialogBar生成的停靠栏上Button都是灰色的? Help!!help!!请教如何在vc程序将我的信息发到别人的手机中?? tapi播放语音 关于变量传递问题,请高手帮忙! 有谁在OnDraw()中用过MessageBox()?为什么不是死循环?怎么解释发生的现象? 关于播放flash的问题 把0显示成0.00怎么弄? 简单问题,怎样得到ListView一单元格中的内容,如用GetItemText请问里面的参数怎样添? 全新安装的redhat 7.2为什么启动kde后不能打开Konqueroer浏览器和主目录 研究生在毕业时真的比本科生有优势吗? 请教:谁知道自动控制原理根轨迹乃试图。。,的算法? 我的AOUTOCAD总装不上??? 爱恋是什么东西?是好人就来看!!! 新闻组(NNTP)怎么用? 为何我用 Delphi写的 MDI Child Window关闭后无法打开? 某氧气和二氧化硫的混合气体中,含氧元素的质量分数为60%,则该混合气体中氧气和二氧化硫的质量比为多少写出具体过程 100mg/kg是什么意思? 将0.2mol/l盐酸200ml与0.1mol/l氢氧化钠100ml混合后,其混合后的溶液显何性?通过计算说明显酸性.碱性.中性? 等质量的二氧化硫和氧气混合,混合气体中,硫元素与氧元素的质量比是?为什么 “100mg/kg/天”是什么意思? 室温下0.1mol/L溶液滴定amL某浓度的HCl溶液,达到终点时消耗NaOH溶液bmL.此时溶液中的氢离子浓度是 急求A 0.1/(a+b) B 0.1b/(a+b)C 1*10^7 D 1*10^-7 圆的半径由5厘米变成3厘米,其面积减少( )平方厘米(1)4π (2)16π (3)16 《求一个数的几分之几是多少》 中和0.2mol氢离子需要多少克氢氧化钠? 0.221028mg/kg=_ mg/100g 一个数的几分之几是多少 一块花布,用去9分之1,还剩9米这块花布全长多少米 meq/kg 换成g/100g 比例是多少? O.1mol/L的NH3.H2O与O.2mol/L的Hcl等体积混合后溶液中的离子浓度大小关系? 100mg等于多少克 100g/dm3换成kg/m3求大神帮我换算下 10ml 0.1mol/l HCL 和10mol 0.1mol/l NaCL能组成缓冲溶液吗? 100mg等于多少g 使溶质质量为100g,如何换算为kg 下列说法错误的是 A .0.1mol/L的HCl与0.1mol/L的NH3.H2O等体积混合,溶液中的c(NH4A:0.1mol/L的HCl与0.1mol/L的NH3.H2O等体积混合,溶液中的c(NH4+)>c(Cl-)B:PH=3的HCl与PH=11的氨水等体积混合,溶液中的c( 100mg/ml的液体现在要80mg要取多少ul?怎么算? 气体和氧气反应生成二氧化碳和二氧化硫,分子质量为60,问该气体是? 某商店库存的花布比白布的2倍多20米,如果每天卖出30米白布和40米花布,几天后白布全部卖完而花布还剩140米,原来库存这两种不共多少米?用一元一次方程解 世纪联华超市停车场客车的辆数是货车的2.5倍.客车开走50辆,货车开走5辆后,剩下的客车和货车的辆数相等,原来的客车和货车各有多少辆?(列方程解) 某含有O2 SO2的混合气体,其氧元素的质量分数为60%,则该气体中氧气与二氧化硫的质量比为多少?请写出具体步骤!最好说说做题心得 某商店里库存的花布是白布的2倍,如果每天卖30米白布和30米花布,几天后,白布全部卖完,而花布还剩下120米,原来库存花布多少米?请列式解答. 有一块花布长5米,正好可以做6条同样大小的童裤.每条童裤用布几分之几?每天童裤用布几分之几米? 一个数乘分数的意义与整数乘法的意义相不相同? 某商店库存的花布是白布的2倍,如果每天卖出30米白布,40米花布,几天后白布卖完,花布还剩120米,原来库存的两种布各是多少米? 有一块花布长5米,正好可以做6条同样大小的童裤,每条童裤用这块布的几分之几 要使100ml 0.1mol/l的Hcl溶液PH值增至7.0时,需加入固体NaoH多少克 某商店里花布是白布的2倍,如果每天卖30米白布和40米花布.几天后,白布全部买卖完,而花布还剩下120米,原来 库存花布多少米? 有一块花布长7米,正好可做8条同样大小的童裤.1、每条童裤用这块布的几分之几?2、每条童裤用布几分之几米? 若H2CO3.HCl.NH3.NaOH.KCl溶液浓度均为0.1mol每L,其按PH值递增的顺序是 某商店库存的花布比白布的2倍,如果每天卖出30米白布和40米花布,几天后,白布全还剩20米,而花布还剩180米.问原来库存花布有多少米?求详细过程,要算式,不要方程,谢谢! 有一块花布长7米,正好可做9条同样大小的童裤.1、每条童裤用这块布的几分之几?2、每条童裤用布几分之几米? 一个数乘分数的意义与分数乘整数的意义完全相同. 有花布495米,白布有330米.白布是花布的几分之几? 用一块花布和一块黑布,花布长3.5米,黑布长2.7米,妈妈用它们给小明分别做了一套大小相同的衣服.剩下的花布是黑布的3倍,做一套衣服多少米? mmol/kg到底是个什么单位(请帮我换算一个小例子吧,柠檬酸的分子量192.14,苹果酸的分子量134.09那么:2.5 mmol/kg 苹果酸+7.5 mmol/kg 柠檬酸,相当于在1KG的溶液中加入苹果酸与柠檬酸各多少克呢? 鸡比鸭多5分之1,则鸡比鸭少几分之几,鸭是鸡的几分之几,鸡是鸭的几分之几 将AgCl分别放入0.1mol/L的CaCl2溶液和0.1mol/L NaCl溶液中 AgCl在哪种溶液中的溶解度大? 请问(KOH)mg/g转换为 mmol/kg,如何 转换言? 鸡比鸭多7分之2,鸭与鸡的比是( ),鸭占鸡鸭总数的几分之几,鸭比鸡少几分之几 7.30mL 1mol/L NaCl溶液和40mL 0.5mol/L CaCl2溶液混合后,混合液中Cl-浓度为( )A.0.5mol/L B.0.6mol/L C.1.00mol/L D.2mol/L 请问mg/g的单位转换为mmol/kg,如何转换, 将一个半径5厘米的圆形铁片,裁剪成半径为4厘米的圆形铁片零件.铁片的面积还剩下多少平方厘米? 30mL 1mol/L NaCl溶液和40mL 0.5mol/L CaCl2溶液混合后,混合液中Cl-浓度为 答案是1mol/L我的疑问是,为什么混合液的体积能相加呢,不是说体积不能相加么.望高手解答体积相加的规则T-T mmol/L:带表什么?kg/h:代表什么?kg/次:代表什么?kg/s:代表什么?g/mol:代表什么?Pa:代表什 一个圆形铁片零件.外圆半径为30厘米,内圆半径为12厘米.这个贴片零件的面积是多少? 色拉油50g等于多少ml 面粉70g等于多少ml 花布长42米,比白布多3\4,白布长多少米?请大家讲讲 向含有等物质的量的HCl和AlCl3的混合溶液中滴入NaOH溶液至过量沉淀质量和n(NaOH)关系图象是怎样的? 一块长方形的铁板长6米,宽是长的3分之1,这块铁板的面积是多少?周长是多少?算式 有某氧气和二氧化硫的混合气体,氧元素的质量分数为百分之60,则该混合物中氧气和二氧化硫的质量比为多少? “赤霉素浓度100mg/kg”是不是100mg开1kg的水呢? 停车场客车的辆数是货车的1.5倍客车开走42辆后,剩下的客车和货车的车数相等原来客车和货车各有多少辆? 由氧和二氧化硫组成的混合气体,其氧元素的质量分数为60%,则该混合气体中氧和二氧化硫的质量比为______. 在0.1mol/L的NaOH溶液160mL与0.15mol/L的HCL溶液100mL混合后的溶液里,NaCL的物质的量浓度是多少?总体积似乎不能把160+100吧 200ml 0.2mol/L的HCl与100ml 0.1mol/L的NaOH混合后,氢离子浓度为多少?
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn