zoukankan      html  css  js  c++  java
  • 一道淘汰85%面试者的百度开发者面试题参考答案

    /**
    * 百度面试题 http://student.csdn.net/mcd/topic/235300/753730
    * 依序遍历0到100闭区间内所有的正整数,如果该数字能被3整除,则输出该数字及‘*’标记;如果该数字能被5整除,则输出该数字及‘#’标记;
    * 如果该数字既能被3整除又能被5整除,则输出该数字及‘*#’标记。
    */

    对算法没有什么研究, 只是觉得好的算法能给程序带来更快的速度, 所以我下面代码的重点不是算法,而是哪个运行耗时最少:

    public class Test {
    	
    	StringBuffer sBuffer;
    	StringBuilder sBuilder;
    
    	public static void main(String[] args) {
    
    		long start = System.nanoTime();
    		foo();
    		long end = System.nanoTime();
    		System.out.println("--------1-------");
    		long start1 = System.nanoTime();
    		Test test = new Test();
    		test.sBuffer = new StringBuffer();
    		test.foo1();
    		System.out.println(test.sBuffer);
    		long end1 = System.nanoTime();
    		System.out.println("--------2-------");
    		long start2 = System.nanoTime();
    		Test test2 = new Test();
    		test2.sBuilder = new StringBuilder();
    		test2.foo2();
    		System.out.println(test2.sBuilder);
    		long end2 = System.nanoTime();
    
    		System.out.println("--------3-------");
    		long start3 = System.nanoTime();
    		new Test().foo3();
    		long end3 = System.nanoTime();
    
    		System.out.println("--------4-------");
    		long start4 = System.nanoTime();
    		Test test4 = new Test();
    		test4.sBuilder = new StringBuilder();
    		test4.foo4();
    		System.out.println(test4.sBuilder);
    		long end4 = System.nanoTime();
    		
    		long start5 = System.nanoTime();
    		Test test5 = new Test();
    		test5.sBuilder = new StringBuilder();
    		test5.foo5();
    		System.out.println(test5.sBuilder);
    		long end5 = System.nanoTime();
    
    		System.out.println(end - start);
    		System.out.println(end1 - start1);
    		System.out.println(end2 - start2);
    		System.out.println(end3 - start3);
    		System.out.println(end4 - start4);
    		System.out.println(end5 - start5);
    		
    	}
    
    	/**
    	 * 方法一:直接使用+ 拼接
    	 * 
    	 * @author Administrator
    	 * @date 2014年4月24日
    	 */
    	private static void foo() {
    		for (int i = 1; i <= 100; i++) {
    			if (i % 3 == 0 && i % 5 == 0) {
    				System.out.println(i + "*#");
    			} else if (i % 5 == 0) {
    				System.out.println(i + "#");
    			} else if (i % 3 == 0) {
    				System.out.println(i + "*");
    			}
    		}
    	}
    
    	/**
    	 * 方法二:采用StringBuffer
    	 * 
    	 * @author Administrator
    	 * @date 2014年4月24日
    	 */
    	private void foo1() {
    		for (int i = 1; i <= 100; i++) {
    			if (i % 3 == 0 && i % 5 == 0) {
    				putBuffer(i, "*#");
    			} else if (i % 5 == 0) {
    				putBuffer(i, "#");
    			} else if (i % 3 == 0) {
    				putBuffer(i, "*");
    			}
    		}
    	}
    
    	/**
    	 * 方法三:采用StringBuilder
    	 * 
    	 * @author Administrator
    	 * @date 2014年4月24日
    	 */
    	private void foo2() {
    		for (int i = 1; i <= 100; i++) {
    			if (i % 3 == 0 && i % 5 == 0) {
    				putBuilder(i, "*#");
    			} else if (i % 5 == 0) {
    				putBuilder(i, "#");
    			} else if (i % 3 == 0) {
    				putBuilder(i, "*");
    			}
    		}
    	}
    
    	/**
    	 * 网友参考答案
    	 */
    	private void foo3() {
    
    		final int COUNT = 100; // 为什么是final , 使用final的好处是什么?
    		boolean isMod3;
    		boolean isMod5;
    		for (int i = 1; i <= COUNT; i++) {
    			isMod3 = i % 3 == 0;
    			isMod5 = i % 5 == 0;
    			if (isMod3 && isMod5) {
    				System.out.println(i + " *#");
    			} else if (isMod3) {
    				System.out.println(i + " *");
    			} else if (isMod5) {
    				System.out.println(i + " #");
    			}
    		}
    
    	}
    	/**
    	 * 更改参考答案
    	 */
    	private void foo4() {
    		final int COUNT = 100; // 为什么是final , 使用final的好处是什么?
    		boolean isMod3;
    		boolean isMod5;
    		for (int i = 1; i <= COUNT; i++) {
    			isMod3 = i % 3 == 0;
    			isMod5 = i % 5 == 0;
    			if (isMod3 && isMod5) {
    				putBuilder(i, "*#");				
    			} else if (isMod3) {
    				putBuilder(i, "*");
    			} else if (isMod5) {
    				putBuilder(i, "#");
    
    			}
    		} 
    	}
    	/**
    	 * 更改网友答案
    	 */
    	private   void foo5() {
    		int COUNT = 100; // 为什么是final , 使用final的好处是什么?
    		boolean isMod3;
    		boolean isMod5;
    		for (int i = 1; i <= COUNT; i++) {
    			isMod3 = i % 3 == 0;  // isMod3 = (i%3==0) 
    			isMod5 = i % 5 == 0;
    			if (isMod3 && isMod5) {
    				putBuilder(i, "*#");
    			} else if (isMod3) {
    				putBuilder(i, "*");
    			} else if (isMod5) {
    				putBuilder(i, "#");
    				
    			}
    		} 
    	}
    
    	/**
    	 * 添加符合要求的数字和所对应的字符
    	 * 
    	 * @param i
    	 *            数字
    	 * @param s
    	 *            字符
    	 * @author Administrator
    	 * @date 2014年4月24日
    	 */
    	private void putBuilder(int i, String s) {
    		sBuilder.append(i);
    		sBuilder.append(s);
    		sBuilder.append("
    ");
    	}
    
    	private void putBuffer(int i, String s) {
    		sBuffer.append(i);
    		sBuffer.append(s);
    		sBuffer.append("
    ");
    	}
    
    }

    程序运行时间:

    /*
    * 耗时: 
    * 1211687 直接拼接 
    * 153947 StringBuffer 
    * 103593 StringBuilder 
    * 1105859 参考
    * 131818  改参考后
    * 108725 不加final
    */

    单看,100次循环的耗时, 可以看出 , StringBuilder 耗时是最少,  加final的反而耗时更多.

    将循环次数, 该为100000,多次运行后各个方法所耗时为:

    //		291248482
    //		27186869
    //		37310223
    //		238034804
    //		57009133
    //		135859617
    
    //		291248482	//直接
    //		27186869	//StringBuffer
    //		37310223 	//StringBuilder
    //		238034804	//..
    //		57009133	//StringBuilder+..+final
    //		135859617	//StringBuilder+ .. 	
    		
    //		289988355
    //		94520451
    //		37578349 
    //		203889493
    //		48452840
    //		133518969
    		
    //		294954135
    //		27723121
    //		143139427
    //		272538045
    //		67523450
    //		135150816
    		
    //		280107789
    //		20859612
    //		135050429
    //		314615520
    //		47390279
    //		137197360
    		
    //		294913403
    //		37562313
    //		133788698
    //		286650573
    //		55538290
    //		138061072


    ...

    可以得出:

    StringBuffer 和StringBuilder 耗时比较少, 由于StringBuilder是线程不安全的,理论上是要比Stringbuffer更快;

    使用+ 拼接的是特别耗时的, final 在循环次数增多以后,其对于不加final来说,效果是明显的.

    同样,采用直接拼接字符, 没优化算法之前的方法一要比优化算法后的方法四耗时明显.


    相关权威理论,可以从<<Java编程思想>>P506 Stirng vs StringBuffer获得

    PS :

    性能优化无末日, 我们能做的很多  --  Tx某工程师

  • 相关阅读:
    C++17 filesystem文件系统
    简易版本vue的实现
    javaSE基础04
    javaSE基础03
    javaSE基础02
    JavaSE基础01
    Document对象和window对象
    进程和子进程及端口的常用命令
    vue分页组件二次封装---每页请求特定数据
    css图片垂直水平居中及放大(实现水平垂直居中的效果有哪些方法?)
  • 原文地址:https://www.cnblogs.com/aikongmeng/p/3697295.html
Copyright © 2011-2022 走看看