这是 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() + "\t" + entry.getValue());
}

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

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

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

StackOverflow 周报 - 高质量问题的问答(Java、Python)的更多相关文章

  1. 编写高质量代码:改善Java程序的151个建议(第二章:基本类型)

    编写高质量代码:改善Java程序的151个建议(第二章:基本类型) 目录 建议21:用偶判断,不用奇判断 建议22:用整数类型处理货币 建议23:不要让类型默默转换 建议24:边界还是边界 建议25: ...

  2. 编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则)

    编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则) 目录 建议1: 不要在常量和变量中出现易混淆的字母 建议2: 莫让常量蜕变成变量 建议3: 三元操作符的类型务 ...

  3. StackOverflow 周报 - 第四周高质量问题的问答(Java、Python)

    这是 Stack Overflow 第三周周报,由于本周周四外出,所以只有三篇内容.两篇 Java.一篇 Python.公众号「渡码」为日更,欢迎关注. DAY1. 枚举对象 == 和 equals ...

  4. 《编写高质量代码:改善Java程序的151个建议》笔记

    To fight the unthinkable,you have to be willing to do the unthinkable.   不要在循环中使用try catch,应该放在循环的外面 ...

  5. StackOverflow 周报 - 与高关注的问题过过招(Java)

    本篇文章是 Stack Overflow 周报的第二周,共收集了 4 道高关注的问题和对应的高赞回答.公众号「渡码」为日更,欢迎关注. DAY1.  serialVersionUID 的重要性 关注: ...

  6. StackOverflow 周报 - 这些高关注的问题你是否都会

    我从 Stack Overflow 上找的了一些高关注度且高赞的问题.这些问题可能平时我们遇不到,但既然是高关注的问题和高点赞的回答说明是被大家普遍认可的,如果我们提前学到了以后不管工作中还是面试中处 ...

  7. 怎样编写高质量的java代码

    代码质量概述     怎样辨别一个项目代码写得好还是坏?优秀的代码和腐化的代码区别在哪里?怎么让自己写的代码既漂亮又有生命力?接下来将对代码质量的问题进行一些粗略的介绍.也请有过代码质量相关经验的朋友 ...

  8. 100个高质量Java开发者博客

    ImportNew注:原文中还没有100个.作者希望大家一起来推荐高质量的Java开发博客,然后不段补充到这个列表.欢迎你也参与推荐优质的Java开发博客.(声明一下:我们的数学不是体育老师教的!:) ...

  9. 博友的 编写高质量代码 改善java程序的151个建议

    编写高质量代码 改善java程序的151个建议 http://www.cnblogs.com/selene/category/876189.html

随机推荐

  1. 探秘最小生成树&&洛谷P2126题解

    我在这里就讲两种方法 Prim 和 Kruscal Kruscal kruscal的本质其实是 排序+并查集 ,是生成树中避圈法的推广 算法原理如下 (1)将连通带权图G=<n,m>的各条 ...

  2. UEM“探针”技术及用户体验管理

    随着互联网产品越来越多,用户群体越来越庞大以及用户品位的多样性增加,我们会发现这样的一个规律,就是相同类型的产品,比如播放器中的QQ影音和暴风影音,再比如小游戏平台中的腾讯游戏和联众等等,他们的功能是 ...

  3. Iphone使用过程中遇到的问题

    Q1:同一个Apple ID不同设备之间的通话记录保持同步 解决方法: Step1:"设置"--"电话"--"在其他设备上通话"--选择关闭 ...

  4. python开发基础--思维导图

    开始学习python,相当于零基础 非自学,自学的痛苦不想体会和尝试,毕竟不会很友好,知乎上看到很多说自学的好处啊噼里啪啦的.嗯,说的很对,但是我偏不听,略略略.锻炼我的自学能力,这还需要锻炼吗,百度 ...

  5. 100天搞定机器学习|Day16 通过内核技巧实现SVM

    前情回顾 机器学习100天|Day1数据预处理100天搞定机器学习|Day2简单线性回归分析100天搞定机器学习|Day3多元线性回归100天搞定机器学习|Day4-6 逻辑回归100天搞定机器学习| ...

  6. 我的第一个CAD程序

    [步骤1]新建项目 启动Visual Studio 2010,然后选择一个C#类库,设置好名称和保存位置,点击[确定] [步骤2]添加引用文件AcMgd.dll和AcDbMgd.dll 首次使用时,[ ...

  7. 迁移学习(Transformer),面试看这些就够了!(附代码)

    1. 什么是迁移学习 迁移学习(Transformer Learning)是一种机器学习方法,就是把为任务 A 开发的模型作为初始点,重新使用在为任务 B 开发模型的过程中.迁移学习是通过从已学习的相 ...

  8. 最大层内元素和----leetcode周赛150_1002

    题目描述: 给你一个二叉树的根节点 root.设根节点位于二叉树的第 1 层,而根节点的子节点位于第 2 层,依此类推. 请你找出层内元素之和 最大 的那几层(可能只有一层)的层号,并返回其中 最小 ...

  9. Console也要美颜了,来给Console添色彩

    我们在开发过程中,经常需要将不同的信息用颜色标记出来,这可以让我们快速关注到重点信息.想必大家都知道,可以通过Console. ForegroundColor设置输出文字的颜色,背景颜色可以通过Con ...

  10. Redis之对象篇——Redis对象系统简介

    Redis之对象篇--Redis对象系统简介 前言     之前几篇文章,简单介绍 Redis用到的所有主要数据结构,简单动态字符串(SDS).双端链表.字典.压缩列表.整数集合.跳跃表. 图解Red ...