有口碑的宁波网站建设信息流优化师招聘
有口碑的宁波网站建设,信息流优化师招聘,夏邑县百城建设提质网站,しょうじょ少女直播确保代码完整性
在撸业务代码时候#xff0c;经常面对的是接口的设计#xff0c;在设计之初#xff0c;我们必然要先想好入参#xff0c;之后自然会有参数的校验过程#xff0c;此时我们需要把可能的输入都想清楚#xff0c;从而避免在程序中出现各种纰漏。但是难免面面…确保代码完整性
在撸业务代码时候经常面对的是接口的设计在设计之初我们必然要先想好入参之后自然会有参数的校验过程此时我们需要把可能的输入都想清楚从而避免在程序中出现各种纰漏。但是难免面面俱到有什么办法能覆盖整个入参的校验呢我们可以考虑黑盒测试用测试用例去覆盖我们编码之前考虑测试用例如果能先设计黑盒测试的测试用例那么自然我们需要注意的校验点就出来了。我们一般都从功能测试边界测试负面测试三方面设计测试用例确保代码的完整性。
错误的处理
我们在编码过程中会遇到各种各样的异常情况我们有3中方式将错误信息床底给函数的调用者。 第一种函数的返回值来告知调用者是否出错比如我们在API设计的时候给定返回对象中有一个状态用状态引擎的方式给定调用者具体的调用成功与否并且在返回值中给定错误对象信息这种方案最大的问题是使用不方便因为我们不能直接吧计算结果给调用方同时也不能将函数的计算结果直接作为参数传递给其他函数。第二种定义一个全局变量在发生错误时候我们设置全局变量值为某个特殊值这种方法比第一种要方便因为调用者可以直接使用返回值我们可以设计一个特定的函数用来判断返回值的分析判断是否错误。这种方案也有问题在于全局变量可能被人遗忘因为N多个调用方我只关注你给的调用结果你的实现多调用方应该透明。第三种异常这是微服务调用中常用的方式当函数运行异常时候我们抛出一个自定义异常。函数调用者更具异常信息就能知道错误原因从而做相应处理。这种问题在于抛出异常会打乱正常的执行顺序对程序的性能会有影响。
数值的整数次方 案例实现函数 double powerdouble base int exponent 求base的exponent次方不能使用函数库同时不需要考虑大数问题。 在java.lang包中有pow函数可以用来求乘方以上问题求解类似于pow函数的功能初见题目其实非常简单可以用一个循环得出如下代码
public static double power(double base, int exponent){if(base 0 || base 1){return base;}if(exponent 0){return 1d;}if(exponent 1){return base;}double result 1.0;for (int i 0; i exponent; i) {result * base;}return result;}指数次幂的大小直接左幂次的乘法如上只考虑了正整数次幂显然不是正确的解法我们可以有如下优化
/*** 求解一个数base 的exponent次幂* */public static double power(double base, int exponent){if(base 0 || base 1){return base;}if(exponent 0){return 1d;}if(exponent 1){return base;}double result 1.0;for (int i 0; i Math.abs(exponent); i) {result * base;}if(exponent 0){return result;}return 1/result;}如上实现方案中已经考虑到了边界值正负次幂情况基本上是一个健全的实现方案但是还有优化的空间例如我们在double的比较中直接判断的是base 0此处是有问题的因为在计算机内标识小数的时候double和float类型小数直接用 这种方式判断是误差的我在之前价格计算遇到的问题相关文章中也有过详细的解释。修改后判断两个小数是否相等只能判断他们只差的绝对值是不是在一个很小的范围内如果相差很小可以认为相等我们将 等于判断用如下equal方法电梯 /*** 浮点数判断是否相等* */public static boolean equals(double num, double num1){if((num - num1 -0.00000001) (num - num1) 0.00000001 ){return true;}return false;}最高效率的解法在上面的解法中每次求值都需要循环exponent次在求解数值的幂次时候我们想到的了之前 递归与循环中讲到的斐波那契数列的非大众解法也是时间复杂度最低的解法我们先有如下公式 情况一 anan/2∗an/2,n为偶数a^n a^{n/2}* a^{n/2} , n为偶数 anan/2∗an/2,n为偶数 情况二 ana(n−1)/2∗a(n−1)/2∗a,n为奇数a^n a^{(n-1)/2}* a^{(n-1)/2}*a , n为奇数 ana(n−1)/2∗a(n−1)/2∗a,n为奇数 我们求解a的n次幂可以按照如上公式来解决时间复杂度是O(nlogn)因此自然的想到了递归实现方式。如下实现
/*** 实现Math.pow(a,b)* */public static double powerWithUnsignedExponent(double base, int exponent){if(base 0 || base 1){return base;}if(exponent 0){return 1d;}if(exponent 1){return base;}double result powerWithUnsignedExponent(base, exponent 1);result*result;if((exponent 1) 1){result*base;}return result;}以上我们用二分法的思想做递归并在判断奇数偶数的地方用与操作进行判断奇数的二进制位 低位必然是1偶数正好相反是 0 因此我们让原数与 1 进行与操作可以区分出奇偶性。位运算相关的知识在之前的文章 数据结构与算法–位运算中有详细介绍。
打印1 到最大的n位数 题目输入数字n 按顺序打印出从1 到最大的n为十进制数。比如输入3则打印出1,23…999。 题目看去来非常简单一个循环可以搞定我们有如下代码 /*** 打印 1 ~ n位最大整数* ex n3 1~999* */public static void print1ToMaxOfNDigits(int n){int number 1;int i 0;while(i n){number *10;}for (int i1 0; i1 number; i1) {System.out.println(i1);}}看起来是没有问题并且程序能正常执行但是这里没有考虑到整数的表示范围问题 整型数据 32 位4 个字节能标识的范围是 -231 ~ 2 32长整型数据64位8 字节能标识的范围 -263~ 264 但是以上案例中的n是没有上限的也就是我们无论用long还是int都会达到最大数据无法标识问题因此必须用其他方案来实现这次的累加可以用字符串或者字符数组来模拟累加的操作。通过以上分析我们需要解决两件事情 用字符串标识数字上的模拟加法打印用字符串表达的数字。 有如下代码
/*** 打印 1 ~ n位最大整数* ex n3 1~999* */public static void print1ToMaxOfNDigitsByChars(int n){if(n0){return;}char[] number new char[n];for (int i 0; i number.length; i) {number[i] 0;}while (!increment(number)){printCharArr(number);}}/*** 字符模拟加法*/public static boolean increment(char[] chars){boolean isOverflow false;int takeOver 0;for (int i chars.length-1; i 0; i--) {//添加进位初始为0不影响int nSum chars[i] - 0 takeOver;//1 操作if(i chars.length-1 ){nSum ;}if(nSum 10){if(i0){isOverflow true;}else {nSum - 10;takeOver 1;chars[i] (char) (0 nSum);}}else {chars[i] (char)(0 nSum);break;}}return isOverflow;}/*** 打印数字取出首字母中0* */public static void printCharArr(char[] chars){if(chars null || chars.length 0){return;}boolean begin true;for (int i 0; i chars.length; i) {if(begin chars[i] ! 0){begin false;}if(!begin){System.out.print(chars[i]);}}System.out.println();}以上代码increment实现字符串number上的 加法printCharArr负责打印。 increment 需要注意的是进位的规则实现已经数据是否越界因为我们需要打印的是N位数当 我们遍历到 第N 位的时候并且第N位的大小 10 此时触发进位规则的时候就达到了我们的最大值。 printCharArr 打印功能虽然简单但是在字符串标识的数字中必然会有前n-x位的字符是无需打印的 ‘0’ 因为我们需要将093打印成 93 才是我们程序需要的值我们用一个标志位begin 来遍历之前的所有0 当达到第一个非0 操作的时候将begin标志位设置为true。才开始打印后面的字符。 终极解法以上思路是完全可以实现的但是用字符串来实现加法的 复杂度过于高即使我们能在短时间内写出来很可能也会有纰漏我们换一种思路我们需要打印0 ~ 999 也就是一个三位字符数组每一位数组都是0~ 9 这10 中情况我们将他看成一个排列组合只要将所有情况按照排列组合的顺序打印出来就可以变相的完成累加的工作。 全排列用递归表示非常容易。数字的第一位设置0~9 然后递归设置下一位0 ~ 9依次递归到第n位。如下实现 /*** 递归打印1 ~ 最大n位整数* */public static void print1ToMaxOfNDigitsRecursively(int n){if(n 0){return;}char[] number new char[n];for (int i 0; i number.length; i) {number[i] 0;}for (int i 0; i 10; i) {number[0] (char)(i0);print1ToMaxOfNDigitsRecursively(number, 0);}}public static void print1ToMaxOfNDigitsRecursively(char[] number, int index){if(index number.length -1){printCharArr(number);return;}for (int i 0; i 10; i) {number[index 1] (char)(0 i);print1ToMaxOfNDigitsRecursively(number, index 1);}}
如上递归实现我们在递归中只有在最高位完成字符串设置的时候才开始打印index number.length -1因为我们将整个字符数组看成是一个排列的一种可能性即使这个数字是001 我们也必须设置完后面的两个 0 才开始打印。
启示录
第一个陷阱在于大数问题需要找到合适的数据结构来表示大数据问题。第二个在于时间复杂度每个算法都应该考虑时间复杂度应该思考不同的方法时间效率问题。第三个考虑问题的全面新在整数的 n次幂问题中需要考虑到非常多的边界问题很多会忽略底数为0 指数为负的情况第四个还是n次幂中对效率的需求这个数学公式的运用还是需要靠积累靠临时来想是不可能的
上一篇数据结构与算法–位运算 下一篇数据结构与算法–代码鲁棒性案例分析
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/86373.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!