Java 解惑阅读笔记 第10章(部分)

简述:

读《Java解惑》 第10章 阅读笔记 


谜题 86  添加括号导致的编译器错误

添加括号会产生编译期错误的情况

int, 或者long, 最小值的绝对值比正数绝对值要大1

添加了括号后




谜题 87 紧张的关系 “==” 符号的非自反性

Transitive.java

package com.anialy.test.java_puzzlers.chapter_10.紧张的关系_87;

public class Transitive {

	public static void main(String[] args) {
		long x = Long.MAX_VALUE;
		double y = (double) Long.MAX_VALUE;
		long z = Long.MAX_VALUE - 1;
		
		System.out.println("x == y : " + (x == y));
		System.out.println("y == z : " + (y == z));
		System.out.println("x == z : " + (x == z));
		System.out.println("Float.NaN == Float.NaN : " + (Float.NaN == Float.NaN));
		
	}
}



输出:




谜题 88 原始类型的处理


程序中的p是属于原始类型Pair的,所以它的所有实例方法都要执行这种擦除。在一个实例方法声明中出现的每个参数化的类型都要被其对应的原始部分所取代。我们程序中的变量p是属于原始类型pair的,所以它的所有实例方法都要执行这种擦除。


谜题 89 泛型迷药,外围类和内部类使用相同的类型参数名

首先看这样一段代码


run之后报错信息如下,



说明:

避免内部类遮蔽外部类的类型参数名字,一个泛型的内部类可以访问到他的外围类的类型参数


优化:

优先使用静态成员类而不是非静态成员类,LinkedList.Node的一个实例不仅含有value和next字段,还有一个隐藏的字段,包含对外围的LinkedList实例的引用。虽然外部类的实例在实例在构造阶段会被用来读取和修改head,但是一旦构造完成,它就变成一个甩不掉的包袱。


使用static修饰Node之后的代码

package com.anialy.test.java_puzzlers.chapter_10.泛型迷药_89;

public class LinkedList<E> {
	private Node<E> head;
	
	private static class Node<T> {
		T value;
		Node<T> next;
		Node(T value, Node<T> next) {
			this.value = value;
			this.next = next;
		}
	}
	
	public void add(E e){
		head = new Node<E>(e, head);
	}
	
	public void dump(){
		for(Node<E> n = head; n != null; n = n.next){
			System.out.println(n.value + ", ");
		}
	}
	
	public static void main(String[] args) {
		LinkedList<String> list = new LinkedList<String>();
		list.add("world");
		list.add("Hello");
		list.dump();
	}
}

谜题90 荒谬痛苦的超类 引用外层类super函数的问题

编译后就不通过,原因如下:

要想实例化一个内部类,入Inner1, 需要提供一个外围类的实例给构造器。一般情况下,它是隐式传递给构造器的,但是它也可以以exception.super(args)的方式通过超类构造器调用。如果外围类实例是隐式传递的,编译器会自动产生表达式:它使用this来指代最内部的超类是一个成员变量的外围类。在本例中,那个超类就是Inner1.因为当前类Inner2间接扩展了Outer类,Inner1便是他的一个继承而来的成员。


显示传递合理的外围类实例:


但是这个成员类真的需要使用外围类实例?如果答案是否定的,那么应该把它设为静态成员类

尽量使用静态嵌套类而少用非静态的。


谜题 91 序列杀手 序列化过程中,调用序列化对象的方法,由于状态不一致导致的问题


SerialKiller.java

package com.anialy.test.java_puzzlers.chapter_10.序列杀手_91;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerialKiller {
	public static void main(String[] args){
		Sub sub = new Sub(666);
		sub.checkInvariant();
		
		Sub copy = (Sub)deepCopy(sub);
		copy.checkInvariant();
	}
	
	public static Object deepCopy(Object obj){
		try {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			new ObjectOutputStream(bos).writeObject(obj);
			ByteArrayInputStream bin = new ByteArrayInputStream(bos.toByteArray());
			return new ObjectInputStream(bin).readObject();
		} catch(Exception e) {
			throw new IllegalArgumentException();
		}
	}
}

Sub.java

package com.anialy.test.java_puzzlers.chapter_10.序列杀手_91;

public class Sub extends Super {
	private int id;
	
	public Sub(int id){
		this.id = id;
		set.add(this);
	}
	
	@Override
	public int hashCode (){
		return id;
	}
	
	@Override
	public boolean equals(Object o){
		return (o instanceof Sub) && (id == ((Sub)o).id);
	}
	
	public void checkInvariant(){
		if(!set.contains(this)){
			throw new AssertionError("invariant violated");
		}
	}
}

Super.java

package com.anialy.test.java_puzzlers.chapter_10.序列杀手_91;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

public class Super implements Serializable {
	final Set<Super> set = new HashSet<Super>();
}

运行后输出:



说明:

HashSet类有一个readObject方法,它创建一个空的HashMap,并且使用HashMap的put方法,针对集合中的每个元素在HashMa中插入的一个键-值对。put方法会调用键的hashCode方法以确定它所在的单元格。三列映射表中唯一的键就是Sub的实例,而它的set字段正在被反序列化。这个实例的子类字段,即id,尚未被初始化,所以它的值为0,即所有int字段的默认初始值,Sub的hashCode方法将返回这个值,而不是最后保存在这个字段中的值666.因为hashCode返回了错误的值,相应的键-值对条目将会放入错误的单元格中。当id被初始化为666时,一切都太迟了。当Sub实例在HashMap中的时候,改变这个字段的值就会破坏这个字段,进而破坏HashSet,破坏Sub实例。


关键点:

1. 如果一个HashSet、Hashtable或HashMap被序列化,那么请确认它们的内容没有直接或间接地引用它们自身。

2. 在readObject或readResolve方法中,请避免直接或间接地在正在进行反序列化的对象上调用任何方法


谜题 92 私有成员变量不会继承

Twisted.java

package com.anialy.test.java_puzzlers.chapter_10.双绞线_92;

public class Twisted {
	private String name;
	
	public Twisted(String name) {
		this.name = name;
	}

	private void reproduce(){
		new Twisted("reproduce"){
			void printName() {
				System.out.println(name);
			}
		}.printName();
	}
	
	public static void main(String[] args) {
		new Twisted("main").reproduce();
	}
}


输出:


说明:

私有成员不会被继承,所以在这个程序中,name方法并没有被继承到reproduce方法中的匿名类中。所以,匿名类中对name的取值就只能关联到到外围(“main")实例而不是当前("reproduced")实例。这就是最小闭合作用域









































【6层】一字型框架办公楼(含建筑结构图、计算书) 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值