zoukankan      html  css  js  c++  java
  • StackOverflow 周报

    这是 Stack Overflow 第三周周报,本周加入了 Python 的内容,原计划两篇 Java、两篇 Python。但明天过节所以今天就先把周报发了,两篇 Java、一篇 Python。公众号「渡码」为日更,欢迎关注。

    DAY1. 使用随机数打印"hello world"

    今天我们看一个有意思的例子,看看下面的代码为什么每次运行都能输出 "hello world"。

    public static String randomString(int i) {
        Random ran = new Random(i);
        StringBuilder sb = new StringBuilder();
        while (true) {
            int k = ran.nextInt(27);
            System.out.println(k);
            if (k == 0) {
                break;
            }
            sb.append((char)('`' + k));
        }
        return sb.toString();
    }

    调用代码:

    System.out.println(randomString(-229985452) + " " + randomString(-147909649));

    我们不禁会想,生成随机数不是随机吗,为什么每次运行结果都一样。

    要解释这个问题,我们需要了解 “伪随机” 的概念。只要随机数是由确定的算法生成的,那就是伪随机,也就是说它的生成看似随机但是有一定规律的。而“真随机”需要真实的随机事件取得,所以计算机只能生成伪随机数。

    知道了“伪随机”概念,今天的例子就好解释了。在之前的文章中我们看过生成随机数的代码,是根据当前种子(seed)通过特定的规则(算法)生成随机数并更新种子,因此 Random 生成的随机数是“伪随机”数。此外我们都知道算法有个特性叫确定性,也就是说相同的输入只能得出相同的输出。对于生成随机数这个算法来说,每次调用只要初始种子(seed)不变,那么一定会生成相同的随机数。这就解释了,为什么每次执行生成的随机数序列都是一样的。

    最后,生成的 int 类型随机数 k,通过 (char)('`' + k) 这行代码转成字符,这里用到的是 ASCII 码相关的知识,不再赘述。

    今天通过这个简单的例子了解了伪随机的概念。欢迎交流,关注公众号每天分享一个知识点。

    原文地址

    DAY2. Java 嵌套类的两种形式

    Java 中嵌套类有两种形式,官方定义为:如果嵌套类为静态的,则称为静态嵌套类,如果是非静态的则称为内部类。设计嵌套类有以下的好处:

    • 代码组织:如果我们定义的某个类只服务于当前类,而不会在其他命名空间中使用,那么将它定义在当前类的命名空间中是明智的。就像成员变量,在面向对象编程思想下,并不是所有的成员都要定义为全局的
    • 访问权限:嵌套类可以直接访问外部类的成员,即便是 private 修饰的
    • 便利性:没必要为每一个类创建一个文件

    下面看看这两种类的写法以及优势。先看看静态嵌套类:

    class OuterClass {
         private static int a =10;
         class StaticNestedClass {
         }
    }
    // 用法
    OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

    静态类初始化时除了类前面加“外部类."外,其他的跟使用一个普通类相同。并且在 nestedObject 对象上使用跟普通对象一样。静态类最大的优势在于可以直接访问外部类私有的静态成员。

    再看看内部类:

    class OuterClass {
        private int a = 10;
        class InnerClass {
        }
    }
    // 用法
    OuterClass outerObject = new outerObject();
    OuterClass.InnerClass innerObject = outerObject.new InnerClass();

    与非静态成员类似,InnerClass 都绑定在一个外部对象上。因此初始化 InnerClass 时,需要先创建 OuterClass 对象。内部类除了可以访问外部类的静态私有成员外,还可以直接访问外部类的非静态私有成员。当然,内部类使用时有个限制,不能声明 static 成员。

    原文地址

    DAY3. 是 Python 的设计缺陷吗

    先看一个问题,猜猜下面代码的输出结果是什么?

    def a():
        print("a executed")
        return []
    
    def b(x=a()):
        x.append(5)
        print(x)
    
    b()
    b()
    b()

    输出结果如下:

    a executed
    [5]
    [5, 5]
    [5, 5, 5]

    可以看到,每次调用 b() 时代码的输出都不一样。并且,a 函数只执行了一次。因此,我们可以确定,b 函数的默认参数是在函数定义时仅被计算了一次,而不是函数每次调用都会计算。这个问题可以这样看:Python 中函数也是一个对象而默认参数是对象的成员,所以,它会被保存、更新。但你可能会想,这是不是 Python 的设计缺陷。答案是否定的,如今的 Python 如此流行,如果仅仅是设计缺陷这么简单的问题,那么会很快被修复。那么,你可能还会想是不是可以让函数执行时再确定默认参数值,这样就可以避免上面的问题了。然而这样同样会有问题,看下面的例子:

    fruits = ("apples", "bananas", "loganberries")
    
    def eat(food=fruits):
        print(food)
    
    def some_random_function():
        global fruits
        fruits = ("blueberries", "mangos")

    假设,全局变量 fruits 被修改了, 然后我们调用 eat 时,她的默认参数值就跟之前的调用不一致了, 同样会令我们疑惑。而 Python 的设计者认为这种情况给语言使用者造成的疑惑更大,因此他们采用第一种的设计方式,在函数定义时确定默认值。

    其实这样的问题不光 Python 存在,任何语言都存在, 我们下面看一个 Java的例子。

    StringBuffer s = new StringBuffer("Hello World");
    Map<StringBuffer,Integer> counts = new HashMap<StringBuffer,Integer>();
    counts.put(s, 5);
    s.append("!!!!");
    for (Map.Entry<StringBuffer, Integer> entry : counts.entrySet()) {
        System.out.println(entry.getKey() + "	" + entry.getValue());
    }

    我们写入 counts 的字符串是 "Hello World",而输出是变成了 "Hello World!!!!"。这跟我们刚刚讨论的 Python 的问题类似,这里没有对错,无论使用什么方式,都会有人提出不同意见。到底使用哪种方式是语言的设计者考虑的问题,而每种方式有什么坑,我们作为语言的使用者应该提前了解且避免。

    以上便是 Stack Overflow 的第二周周报,希望对你有用,后续会继续更新,如果想看日更内容欢迎关注公众号。

    公众号「渡码」,分享更多高质量内容

  • 相关阅读:
    c++(递归和堆栈)
    Halcon算子翻译——dev_set_line_width
    Halcon算子翻译——dev_set_draw
    Halcon算子翻译——dev_set_colored
    Halcon算子翻译——dev_set_color
    Halcon算子翻译——dev_open_window
    Halcon算子翻译——dev_open_tool
    Halcon算子翻译——dev_open_file_dialog
    Halcon算子翻译——dev_open_dialog
    Halcon算子翻译——dev_map_var
  • 原文地址:https://www.cnblogs.com/duma/p/11509552.html
Copyright © 2011-2022 走看看