head first java读书笔记
head first java读书笔记
1. 基本信息
- 页数:689
- 阅读起止日期:20170104-20170215
2. 标签
- Java入门
3. 价值
- 8分
4. 主题
使用面向对象的思路介绍Java的基础知识,从对象的基本概念、变量、方法,到函数库,集成与多态,静态,再到GUI,序列化,网络,数据结构,最后介绍发布和远程调用。
5. 纲要
- Java的基本介绍-第1章
- 对象的基本介绍(变量与方法)-第2-5章
- 函数库-第6章
- 对象的深入-继承、多态、构造函数-第7-9章
- 静态的变量或方法-第10章
- 异常处理-第11章
- GUI-第12-13章
- 序列化与IO-第14章
- 网络与线程-第15章
- 常用数据结构-第16章
- 包与发布程序-第17章
- 远程过程调用、servlets等-第18章
- 附录
6. 点评
本书最大的启发是建立面向对象的基本思想,万物皆在对象中,到底是如何组成和实现的。
7. 摘录
7.1 Java的基本介绍
Java程序包括:源代码、编译器、输出(class文件)、JVM;
最常用的java
public class ClassName {
public static void main(String[] args){
System.out.println("Hello World!");
}
}
Java不能像C一样使用整型做测试条件
(int)(Math.random()*length)
来出现随机数;
7.2 对象的基本介绍
- 对象本身已知的事物被称为实例变量,对象可以执行的动作被称为方法;
- 类是对象的蓝图;
- main的两种用途:测试真正的类,启动你的java应用程序;
- Java的程序在执行期是一组会互相交谈的对象;
- 变量有两种类型primitive主数据类型和引用;
- primitive主数据类型:boolean, char(0~65535), byte(-128~127), short(-32768~32767), int, long, float, double。
- 没有对象变量,只有引用到对象的变量;引用变量更像是对象的遥控器;
- 没有引用到任何对象的引用变量的值为null;
- 如果堆上的对象没有任何引用变量,便会被回收;
- 数组就像杯架,数组变量就是数组对象的遥控器;
- 将实例变量标记为private,将getter和setter标记为public;
- 实例变量永远都会有默认值,引用变量的默认值是null;局部变量没有默认值。
- 程序设计的方法:找出类应该做的事情,列出实例变量和方法,编写伪码,编写测试用的程序,实现类,测试方法,排错或重新设计。
- 伪码描述要做什么事情,而不是如何做。
- Interger.parseInt()只会在所给的String为数字时有用。
7.3 API
- ArrayList listName = new ArrayList();
- Java的API中,类是包含在包中的。使用时,必须import 类全名或直接打出去全名。除非是来自于java.lang这个包中,比如System, String, Math等。
7.4 对象深入
- extends表示继承,继承搜索方法时,会从底层向祖先搜索;
- 继承是是一个,实例变量是有一个;
- public会被继承,private不会被继承。
- IS-A是单方向的;
- 继承的意义有二:避免了重复的代码;定义出共同的协议;
- 多态为声明父类的对象引用指向子类的对象;
- 通过多态,可以写出即使引进新型子类时,也不必修改的程序;
- 继承虽然没有层次的限制,但一般不会超过2层;
- 标识出final的类可以确保方法都是自己需要的版本,final也可以防止特定的方法被覆盖,只要加在方法前;
- 覆盖父类方法需要满足两个条件:参数必须要一样,且返回类型要兼容;不能降低方法的存取权限;
- abstract表示抽象,抽象类不会被初始化;
- abstract可以放在方法前,直接以分号结尾。抽象方法只能放在抽象类中,所有的抽象方法在子类中必须被实现;
- Java中,所有的类都继承自object。object有equals,getClass,hashCode,toString等方法。
- 接口是为了解决多重继承的问题出现的,它没有实例变量。像是一个100%的纯抽象类,使用interface定义,所有的方法都是抽象的。其他类用implements来实现接口的方法。类是可以实现多个借口的。
- 如果新的类无法对其他类通过IS-A测试,就设计不继承的类;
- 只有在需要某类的特殊化版本时,已覆盖或增加新的方法来继承现有的类;
- 当你需要定义一群子类的模板,又不想初始化此模板时,使用抽象类;
- 如果定义出类可以扮演的角色,使用接口;
- 使用super关键字执行父类的方法;
- 抽象类可以带有抽象和非抽象的方法;
- 方法调用和局部变量在栈空间,所有的对象在堆空间;
- 构造函数没有类型,也不会被继承。通常一定要有没有参数的构造函数。如果有了一个有参数的构造函数,则没参数的构造函数必须自己写才会有,否则创建会出错。
- 通常状况下,类的构造函数是public。
- 构造函数的调用链是自顶向下的,即先运行父类,再运行子类。
- 子类的构造函数如果想调用父类,使用super();通常状况下,super会被编译器默认调用没有参数的版本,显示调用的话,必须要把super();放到第一行。
- 可以使用this(args)调用重载版的其他的构造函数,例如无参数的构造函数,加个默认值调用有参数的构造函数。this(Color.Red)
7.5 静态的变量或方法
静态方法不需要创建实例变量就可以调用,像Math.abs(-1);
如果类只有静态方法,即要限制非抽象类初始化,可以将构造函数设置为private;
静态方法不能调用非静态的变量或方法,例如在main中调用;但可以调用静态变量或方法。
类中静态变量的值,对所有实例都相同,均是共享的;即实例变量每个实例一个,静态变量每个类一个。
public static final double PI=3.1415
public表示可供各方读取,static表示不用创建实例即可使用,final表示不变;静态final变量默认取名大写,且必须初始化。final的变量代表不能改变,final的方法不能被覆盖,final的类不能被继承;
使用类似ArrayList时,要用到对主类型数据的封装。因为ArrayList设计成只接受类和对象。Java5.0之前,int不能直接加入ArrayList,5.0之后可以了,因为加入了autoboxing。Integer iWarp = new Integer(i); int unWrapped = iWrap.intValue();利用上述解包装;
主数据类型的静态方法:Integer.parseInt("2"), new Boolean("true").booleanValue();Double.toString(d);
格式化输出String.format("%,d",1000);
日期的格式化输出:%tc 完整的日期和时间,%tr是时间,%tA %tB %td 分别是星期,月份和日期。如果不想重复输入参数,可以使用String.format("%tA, %<tB %<td", today);
java.util.Calendar对象来操作日期
Calendar cal = Calendar.getInstance();
cal.set(2017,1,6,15,40);
cal.getTimeInMillis();
cal.HOUR_OF_DAY
cal.add(cal.DATE, 30);//月份滚动
cal.roll(cal.DATE, 30);//月份不动
cal.set(cal.DATE, 1);
//重要的方法
add(int field, int amount)
get(int field)
getInstance()
getTimeInMillis()
roll(int field, int amount)
set(int field, int amount)
set(year,month,day,hour,minute)
setTimeInMillis(long millis)
//关键字段
DATE / DAY_OF_MONTH
HOUR / HOUR_OF_DAY
MILLISECOND
MINUTE
MONTH
YEAR
ZONE_OFFSET
import static java.lang.System.out;静态的import可以到方法,然后直接调用out即可,不建议使用;
7.6 异常处理
Java通过throws语句来告诉你所有的异常行为;把有风险的程序放在try块中,用catch块摆放异常的处理程序;异常时Exception类型的对象;
会抛出异常的方法必须要声明它有可能会这么做。方法可以抓住其他异常,异常总会丢回给调用方;
public void takeRisk() throws BadException{
if (abandonAllHope){
throw new BadException();
}
}
public void crossFingers(){
try{
anObject.takeRisk();
}catch (BadException ex){
System.out.println("Aaargh");
ex.printStackTrace();
}
}
try/catch块用来处理真正的异常,而不是程序的逻辑错误。
开发与测试期间发生RuntimeException是不会受编译器关于是否声明它会抛出RuntimeException的检查的,也不会管调用方是否认识到该异常;
无论成功或者失败都要运行的放在finally中;即使try和catch都有return也一样。
throws可以抛出多个异常。
throws Exception1, Exception2
;catch也可以用类似switch语句一样来分别处理,但是要从小到大;异常也可以是多态的,可以用所抛出的异常父型来catch异常。即可以用Exception ex来catch异常,但是不推荐这么做;
duck异常表示,当调用有异常的方法,也声明会抛出异常时,可以不把此方法的调用放在try/catch块中,但是不推荐这么做。
7.7 GUI相关
GUI的流程是创建frame,创建widget,加在widget,显示出来。
监听和事件源之间的沟通通过程序代码调用
button.addActionListener(this)
来向按钮注册。按钮会在事件发生时,调用注册该接口的方法actionPerformed(theEvent)
;import javax.swing.*;
import java.awt.event.*; public class SimpleGui1B implements ActionListener{
JButton button; public static void main(String[] args){
SimpleGui1B gui = new SimpleGui1B();
gui.go();
}
public void go(){
JFrame frame = new JFrame();
button = new JButton("click me"); button.addAcitonListener(this); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(button); frame.setSize(300,300);
frame.setVisible(true);
} public void actionPerformed(ActionEvent event){
button.setText("I've been clicked!");
}
}
frame默认有东西南北中五个位置来放置widget;
当有多个widget需要监听事件时,用内部类来解决;
public void go(){
//...
labelButton.addActionListener(new LaberlListener());
colorButton.addActionListener(new ColorListener());
label = new JLabel("I'm a label")
//...
}
class LaberListener implements ActionListener {
public void actionPerformed(ActionEvent event){
labnel.setText("Ouch!")
}
}
不同的事件有不同的对应回调函数,ActionListener对应的回调函数是actionPerformed,通过addActionListener添加。
每个背景组件都可以有自定义规则的布局管理器。BorderLayout表示五个区域,是frame默认的,FlowLayout表示从左至右,有必要时换行,是panel默认的;BoxLayout以垂直排列;
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(button);
frame.getContentPane().add(BorderLayout.North, panel);
JTextField文本框组件,JTextArea可滚动的文本框组件,JCheckBox组件,JList组件均为常用组件。
7.8 序列化与IO
储存对象的状态可以有两种办法,序列化(自己的Java程序读),纯文本文件(公共格式,其他程序可读)。
序列化写入的步骤:创建FileOutputStream对应一个文件xxx.ser,有FileStream创建ObjectOutputStream,由ObjectOutputStream写入object,关闭ObjectOutputStream。其中需要注意,能够写入ObjectOutputStream的object必须implements Serializable,但是不需要实现任何方法。
FileOutputStream fileStream = new FileOutputStream("MyGame.ser");
ObjectOutputStream os = new ObjectOutputStream(fileStream);
os.writeObject(characterOne);
os.close();
当一个类可以序列化时,必须所有的实例变量都能被序列化,如果某个变量不需要序列化,需要标记transient,例如
transient String currentID;
解序列化步骤,创建FileInputStream读取一个文件,创建ObjectInputStream,读取对象,转换对象类型,关闭。
FileInputStream fileStream = new FileInputStream("MyGame.ser");
ObjectInputStream os = new ObjectInputStream(fileStream);
Object one = os.readObject();
GameCharacter elf = (GameCharacter) one;
os.close()
读写文本文件。注意可以使用缓冲区的方法来减少磁盘IO。使用writer.flush()强制缓冲区内容写入磁盘。
import java.io.*;
class WriteAFile{
public static void main(String[] args){
try {
FileWriter writer = new FileWriter("Foo.txt");
writer.write("hello, foo!");
//BufferedWriter bWriter = new BufferedWriter(writer);
//bWriter.flush();
writer.close();
File myFile = new File("Foo.txt");
FileReader fileReader = new FileReader(myFile); BufferedReader reader = new BufferedReader(fileReader);
String line = null;
while((line = reader.readLine()) != null){
System.out.println(line);
}
reader.close();
} catch(IOException ex){
ex.printStackTrace();
}
}
}
java.io.File类的操作
//创建出File对象
File f = new File("MyCode.txt");
//建目录
File dir = new File("Chapter_8");
dir.mkdir()
//列出目录内容
if (dir.isDirectory()){
String[] dirContents = dit.list();
}
//取得绝对路径
dit.getAbsolutePath();
//删除文件
boolean isDeleted = f.delete()
每个对象被序列化的同时,都会带上一个类的版本的识别ID,即serialVersionUID。因此要注意版本。
7.9 网络与线程
网络接收消息的步骤:建立socket连接,输入到底层的InputStreamReader上,转换到缓冲区字符BufferedReader,读取数据;
Socket chatSocket = new Socket("127.0.0.1", 5000);
InputStreamReader stream = new InputStreamReader(chatSocket.getInputStream());
BufferedReader reader = new BufferedReader(stream);
String message = reader.readline();
reader.close();
写消息的流程是:建立socket,getOutputSream并建立PrintWriter,写入数据;
Socket chatSocket = new Socket("127.0.0.1", 5000);
PrintWriter writer = new PringWriter(chatSocket.getOutputStream());
writer.println("haha");
writer.close();
服务器端建立服务的流程为:建立ServerSocket,等待客户端连接,客户连接后,调用accept方法建立新的socket。
ServerSocket serverSock = new ServerSocket(5000);
while(true){
Socket sock = serverSock.accept();
PrintWriter writer = new PrintWriter(sock.getOutputStream());
writer.println("haha");
writer.close();
}
Thread类用于创建线程,它有void join();void start();static void sleep();等方法。
启动新线程的流程是:建立Runnable对象,建立Thread对象,并赋值Runnable任务;启动Thread。
Runnable是一个接口,它只有一个方法public void run()。它就是线程要执行的工作。
public class MyRunnable implements Runnable {
public void run(){
go();
}
public void go(){
System.out.println("top o' the stack");
}
} class ThreadTestDrive{
public static void main(String[] args){
Runnable threadJob = new MyRunnable();
Thread myThread = new Thread(threadJob);
myThread.start();
System.out.println("back in main");
}
}
新建线程线程有新建(new),可执行(start),执行中,三个状态,可执行和执行中两个状态是来回切换的,由JVM调度决定,是随机不可控的。最多只能靠sleep来影响最小保证时间。
线程不可重复启动。
线程的名字可以通过myThread.setName("Solon's Thread")来设定,并可通过调用Thread.currentThread().getName()来获取。
线程会产生并发性问题(concurrency),并发性问题会引发竞争状态(race condition),竞争状态会引发数据损毁。举个例子,两个线程共用一个余额,每次用钱时,先检查余额,再扣钱。这样会由于竞争原因出现负数。所以需要一把锁,来保证一个方法一次只能被一个线程调用,即用synchronized关键字。
private synchronized void makeWithDrawa(int amount){
//...
}
要注意锁是锁在对象上的,只有对象包含同步化方法时才起作用。对象就算有多个同步化方法,也还是只有一个锁。
同步化可以只修饰几行,这样可以减小原子操作的范围,提高效率。
private void makeWithDrawa(int amount){
//...
synchronized(this){
//...
}
}
两个线程和两个对象就可以引起死锁,各自占有一个资源,又需要调用彼此的资源。
静态的方法是运行在类上的,当要对静态的方法做同步化是,会使用类本身的锁。
7.10 常用数据结构与泛型
TreeSet一有序状态保持并可防止重复;
HashMap-KV来存储;
LinkedList-针对经常插入和删除的集合;没有ArrayList常用;
HashSet-防重复的集合,快速查找;
LinkedHashMap-类似HashMap,但可记住元素的插入顺序,可按照存取顺序来排序;
可用java.util下的Collections.sort(List list)来给ArrayList排序,此函数会直接改变list的顺序。
不用泛型时,任何object对象都可以加入ArrayList,造成混乱。使用泛型,只有任一单一类型可加入;
泛型有三件事是重要的:
new ArrayList<Song>(); //创建实例
ArrayList<Song> songList = new ArrayList<song>(); //声明指定泛型类型的变量
void foo(ArrayList<Song> list); //声明或调用指定泛型的方法
在说明文件中,一般用E表示指定类型;
public class ArrayList<E> extends AbstractList<E> implements List<E> ...{
public boolean add(E o)
}
运用泛型的方法可以使用未定义在类声明的类型参数。
public <T extends Animal> void takeThing(ArrayList<T> list)
//与后续的万用字符相同
public void takeThing(ArrayList<? extends Animal>)
//与下面不一样,下面的只能使用Animal,不能使用其子类
public void takeThing(ArrayList<Animal> list)
以泛型的观点来说extends可以代表extend或implement,表示是一个。
如果要对自定义类实现排序,有两种方法,一是实现该类的Comparable接口,这个接口有compareTo方法。可以调用已有的类型来辅助实现该方法;二是增加Comparator类的参数来比较。
可以调用HashSet的addAll方法,来生成ArrayList对应的队列;
同样如果要使用HashSet去除重复,针对自定义类,要覆盖equals方法和hashCode方法。它的比较过程是先比较hashCode(),如果相同,再比较equals。
class Song implements Comparable<Song>{
...
public boolean equals(Object aSong){
Song s = (Song)aSong;
return getTitle().equals(s.getTitle());
}
public int hashCode(){
return title.hashCode();
}
}
HashMap适合用KV场景存储数据
HashMap<String, Integer> scores = new HashMap<String, Integer>();
scores.put("Bert", 43);
System.out.println(scores.get("Bert"));
泛型参数和数组参数的区别
public void takeAnimals1(ArrayList<Animal> animals)
public void takeAnimals2(Animal[] animals)
//takeAnimals1(new ArrayList<Dog> dogs)会出错,编译错误
//takeAnimals2(new Dog[] dogs)不会出错
//前者可以防止在函数中进行Dog的特有相关操作,后者在执行期如果运行相关操作,会抛出异常
为了解决上述前者的问题,可以使用万用字符
public void takeAnimals3(ArrayList<? extends Animal> animals)
//为了防止此时,将ArrayList<Dog>中加入Cat,当用万用字符时,不能对队列做加入操作
7.11 包与发布程序
可以使用
-d class_path
来将源代码与类文件相分离,实现对源码的保护;javac -d ../classes *.java
jar类似tar命令,它有自己的规则。首先要确定所有的类文件都在classes目录下,其次要有manifest.txt文件来描述哪个类带有main()方法,最后执行命令打jar包
cat manifest.txt
Main-Class:MyApp
cd MiniProject/classes
jar -cvmf manifest.txt app1.jar *.class
如果jar包指定了manifest,则可以执行
java -jar app1.jar
。除非类是包的一部分,否则Java虚拟机不会深入其他目录去找。
用包防止类名冲突,可以把类放到各个包里。就像java.util.ArrayList。
而为了防止包命名冲突,一般反向使用domain作为包名称。
com.headfirstbooks.Book
com.headfirstjava.projects.Chart
选定包名称后,需要再类的源代码的第一行将类加入包中
package com.headfirstjava;
。然后要设定对应的目录结构。一般Java程序的路径为项目根目录下有source和classes两个文件,source目录下为包路径和源代码,这样用-d ../classes编译后,-d会在classes目录下建立对应的目录和class文件。
按照上述约定时,manifest文件也放在class目录下,一般为
Main-Class:com.headfirstjava.PackageExcise
。在classes目录下执行jar语句打包,这里只要指定com路径就行。
jar -cvmf manifest.txt packEx.jar com
使用
jar -xf packEx.jar
解压后会发现有META-INF
目录,其下有MANIFEST.MF
文件,即为写入的对应文件。JWS即Java Web Start,用户能通过网页上的某个连接来启动Java程序,一旦程序下载后,下次就能独立于浏览器来运行,它是通过网络来发布程序的一种手段。jnlp文件是个描述应用程序可执行JAR文件的XML文件。
制作可执行jar程序;编写jnlp文件;两者均放入Web服务器;Web服务器设定新类型
application/x-java-jnlp-file
;设定网页链接到jnlp文件<a href="MyApp.jnlp">Launch My App</a>
7.12 远程过程调用、servlets等
- 远程过程调用最早是为了利用Server端的强大处理能力。RMI全称Remote Method Invocation;
- RMI需要服务器与服务器helper和客户端与客户端helper。helper假装成服务,但其实只是真实服务的代理;
- 使用RMI时要确定协议,两端都是Java可使用JRMP协议,IIOP可以调用Java对象或其他类型的远程方法。
- 在RMI中客户端的helper称为stub,客户端的helper成为skeleton
- 创建远程服务的流程是创建接口(extends Remote),实现类(extends UnicastRemoteObject impements MyRemote),rmic产生stub与skeleton(
rmic MyRemoteImpl
),启动RMI registry(rmiregistry
),启动远程服务(Naming.rebind("Remote Hello", serviceMyRemote)
)。 - 客户端查询RMIregistry(
(MyRemote)Naming.lookup("rmi://127.0.0.1/Remote Hello")
),RMIregistry返回stub对象,客户端调用stub上的方法; - 注意点:启动远程服务前启动registry;参数和返回类型可序列化;
- servlet相当于Java的CGI,可以处理用户提交的请求,并将结果返回给浏览器的网页;
- 创建并执行serverlet的步骤:找到网页服务器可以存放servlet的地方;取得servlet.jar并添加到classpath上(其不是标准函数库的一部分);extends HttpServlet来编写servlet的类;编写html来调用servlet;给服务器配置html和servlet;
- servlet一般通过覆盖HttpServlet的doGet和doPost来创建;它输出带有完整标识的HTML网页;
- EJB是Enterprise JavaBeans,它具有一组光靠RMI不会有的服务,比如交易管理、安全性、并发性、数据库和网络功能等;EJB服务器作用于RMI调用和服务层之间。service helper调用EJB object,object调用Enterprise bean,后者再调用DB等操作;
- Jini也使用RMI,但具有自适应探索(接收服务注册和客户端调用查询)和自恢复网络(用心跳检查服务)的功能;
7.13 附录
按位非~,按位与&,按位或|,按位异或^;
右移>>,无符号右移>>>;
String具有不变性,放在String pool中,不受Garbage Collector管理。
包装类没有setter,其具有不变性。例如new Integer(42),永远都是42。
断言可以用来测试,它比println的好处是没有特别设定的话,它会自动被JVM忽略,也可专门打开断言调试程序。
assert (height > 0) : "height = " + height + " weight = " + weight;
//冒号后面的语句可以是任何返回非null值得语句,但一定要注意不要在这里改变对象的状态
//断言的编译和普通编译没差别,执行时有差异。
javac TestDriveGame.java
java -ea TestDriveGame
new Foo().go()
是一个调用go方法,但又不需要维持对Foo引用的方式;静态嵌套类,和普通类很像,可通过new Outer.Inner()来创建。可存取外层静态私有变量;
非静态的嵌套类,通常被称为内部类。
匿名内部类。
//button.addActionListener(quitListener); //通常是传递一个内部类的实例
//虽然ActionListener是个接口,而且我们不能声明一个接口的实例,但匿名内部类是个例外
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev){
System.exit(0);
}
});
public任何程序代码都可公开存取;default只在统一包中的默认事物能够存取;protected可允许不在同一包的子类,继承该部分;
对于常用的可变String,一般使用StringBuilder,Thread安全环境中,采用StringBuffer;
二维数组是指数组的数组,
new int [4][2]
其实是创建一个包含四个元素的数组,每个元素是一个长度为2的数组。枚举相对于普通常量的优势是限定了范围,其实际是继承了java.lang.Enum。声明时使用
public enum Members {JERRY, BOBBY, PHIL};
每个枚举都内置values()可以用于遍历操作;
可以在enum中加入构造函数,方法、变量和特定常量的内容;
8. 相关
暂无
head first java读书笔记的更多相关文章
- think in java 读书笔记 3 —— 数据报
目录 think in java 读书笔记 1 ——移位 think in java 读书笔记 2 —— 套接字 think in java 读书笔记 3 —— 数据报 概要 1. 数据报基本知识 2 ...
- think in java 读书笔记 2 —— 套接字
目录 think in java 读书笔记 1 ——移位 think in java 读书笔记 2 —— 套接字 think in java 读书笔记 3 —— 数据报 概要 1. 套接字基本知识 2 ...
- think in java 读书笔记 1 ——移位
目录 think in java 读书笔记 1 ——移位 think in java 读书笔记 2 —— 套接字 think in java 读书笔记 3 —— 数据报 在Think in Java中 ...
- Thinking In Java读书笔记--对象导论
Thinking In Java读书笔记--对象导论[对象]服务提供者==>将对象看做一个服务提供者[程序员分类][类创造者]/[客户端程序员] [访问控制存在的原因?][1]客户端程序员无法触 ...
- Java读书笔记1
Java逍遥游记读书笔记 前言 必须先来一句,这是入门级别,高手勿喷~ 写Android的时候总有一些语句不是很理解,其实大部分是Java的内容,所以想系统的学下Java. 这本书——<Java ...
- java读书笔记二
这是我的一些读书笔记: 我研究了一下面向对象: 面向对象符合人类看待事物的一般规律,对象的方法的实现细节是包装的,只有对象方法的实现者了解细节 我觉得面向过程是由过程.步骤.函数组成,过程是核心,面向 ...
- Effective Java读书笔记完结啦
Effective Java是一本经典的书, 很实用的Java进阶读物, 提供了各个方面的best practices. 最近终于做完了Effective Java的读书笔记, 发布出来与大家共享. ...
- Effective java读书笔记
2015年进步很小,看的书也不是很多,感觉自己都要废了,2016是沉淀的一年,在这一年中要不断学习.看书,努力提升自己 计在16年要看12本书,主要涉及java基础.Spring研究.java并发.J ...
- 【java读书笔记】——java开篇宏观把控 + HelloWorld
学完java有一段时间了,一直没有做对应的总结,总认为有一种缺憾.从这篇博客開始,将自己平时的学习笔记进行总结归纳,分享给大家. 这篇博客主要简单的介绍一下java的基础知识,基本的目的是扫盲.原来仅 ...
随机推荐
- C# IEqualityComparer 去重
1.去除list里某重复字段值的数据(相当于group by) public class CorrController { //方法 public void DoGet() { List<tes ...
- 【JSP】EL函数和自定义EL函数
简介 EL原本是JSTL1.0中的技术(所以EL和JSTL感情如此好就是自然的了),但是从JSP2.0开始,EL就分离出来纳入了JSP的标准了.但是EL函数还是和JSTL技术绑定在一起.下面将介绍如何 ...
- SIM900A基站定位调试笔记 -转
第1步:ATE1 握手并设置回显 第2步:AT+CGMR 查看SIM900的版本信号 第3步:AT+CSQ 查看信号质量 第4步:AT+CREG? 查看GSM是否注册成功 第5步:AT+CGREG? ...
- 数据库操作相关(sql语句-php)
文件:db.config.smarty.php 这个文件主要是用于数据库配置 <?php $db = array( 'host'=>'localhost', 'user'=>'roo ...
- oracle fm格式化
select to_char(0.56,'FM999,999,990.00' ) from dual 其中 9代表如果存在数字则显示数字,不存在显示空格 其中 0代表如果存在数字则显示数字,不存在则显 ...
- CentOS下mysql安装
一.检查环境 # 切换root 权限 su root # 检查是否安装过mysql rpm -qa|grep mysql # 删除所有mysql yum -y remove mysql* 1.上传文件 ...
- Linux下实现秒级定时任务的两种方案
Linux下实现秒级定时任务的两种方案(Crontab 每秒运行): 第一种方案,当然是写一个后台运行的脚本一直循环,然后每次循环sleep一段时间. while true ;do command s ...
- TFS二次开发09——查看文件历史(QueryHistory)
这篇文章给大家展示怎样获取一个文件的历史版本,内容很简单,直接上代码了. string tpcURL = "http://127.0.0.1:8080/"; TfsTeamProj ...
- SQL Fundamentals || Single-Row Functions || 通用函数 General function || (NVL,NVL2,NULLIF,DECODE,CASE,COALESCE)
SQL Fundamentals || Oracle SQL语言 SQL Fundamentals: Using Single-Row Functions to Customize Output使用单 ...
- hadoop HA架构安装部署(QJM HA)
###################HDFS High Availability Using the Quorum Journal Manager########################## ...