0%

矩阵和向量

大写字母-矩阵,小写字母-向量(特殊的矩阵)

  • 加减,数乘
  • 数据矩阵乘参数向量
  • 矩阵乘矩阵-大量运算打包,有结合律无交换律
    多变量线性回归
    特征量,训练样本数
    定义第0个向量
    多元梯度下降法
    特征缩放:使不同特征的取值在相近的范围内(例如-1~+1),梯度下降法能更快收敛,减少迭代次数。

方法:

  1. 将特征除以最大值
  2. 均值归一化,使特征值的均值为0 <= 减均值,除以范围。
    解决细长的椭圆等高线,梯度下降时来回波动,速度较慢的问题。
    Debug
    根据代价函数随迭代步数增加的变化曲线,判断是否已经收敛。或自动判断,选择合适阈值。
    若发散或反复升降,选择更小的学习率。
    选择学习率α
    大致按3的倍数取值,结合代价函数随迭代步数增加的变化曲线。
特征选择—多项式回归

使数据与模型更好的拟合。
特征缩放更显重要。

正规方程

不再像梯度下降中,迭代地求最优解,而是直接一次性求解0最优解。–> 求导,导数置零。
加额外的特征变量x_0,用所有的特征变量构造矩阵
设计矩阵(特征矩阵的转置)
不需要做特征缩放!
在Octave中使用命令:

1
pinv(x'*x)*x'*y

对比梯度下降法与正规方程法:
梯度下降法 | 正规方程法
—|—
需要选择学习率α | 无需选择学习率α
需要多次迭代 | 无需多次迭代
适用于大样本量 | 样本较多时速度较慢,O(n^3)
当样本量大于10^6时,更适合采用梯度下降法。样本量较小时,正规方程法更优。
正规方程法适用于线性回归,不适合复杂的算法。

正规方程以及不可逆性

不可逆的矩阵(奇异或退化矩阵),很少发生,在软件中可得到正解。–>数值计算问题

原因:可能是因为我们使用了冗余的特征,或是我们使用了太多的特征(特征的数量超过了样本的数量)
解决:去掉多余特征或使用正规化方法

监督学习vs无监督学习
  • 监督学习:通过算法来对一些离散的数据进行一个监督。回归问题&分类问题
  • 无监督学习:通过给予算法大量的数据,来让算法找出数据的类型结构。聚类算法。

从数据的角度来讲, 监督学习和无监督学习的区别就在于每一个数据样本是否包含一个准确的输出值。

单变量线性回归

(Linear regression with one variable = Univariate linear regression)
代价函数(平方误差代价函数):每个样例的估计值与真实值之间差的平方的均值。

++梯度下降+代价函数=线性回归算法++,用直线模型拟合数据
优化目标:代价函数最小
优化算法:
梯度下降法:给定初始值(0或其他),不停的改变参数以找到局部最小值。要注意同步更新多个θ!

  • 梯度:代价函数对每个θ的偏导。
  • 学习率α:梯度下降时,迈的步子大小。

初始状态不同,可能得到不同的局部最低点。用于线性回归的代价函数总是一个凸函数(Convex Function)。这样的函数没有局部最优解,只有一个全局最优解。所以使用梯度下降的时候,总会得到一个全局最优解。
Batch梯度下降

Description

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Example:

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode * addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *tmp1 = l1->next, *tmp2 = l2->next;
ListNode *res = new ListNode((l1->val + l2->val) % 10);
ListNode *tmp = res;
int flag = (l1->val + l2->val) > 9 ? 1 : 0;
int k;
while (tmp1&&tmp2)
{
k = tmp1->val + tmp2->val+flag;
tmp->next = new ListNode(k%10);
flag = k / 10;
tmp1 = tmp1->next;
tmp2 = tmp2->next;
tmp = tmp->next;
}
while (tmp1)
{
k = tmp1->val+flag;
tmp->next = new ListNode(k % 10);
flag = k / 10;
tmp1 = tmp1->next;
tmp = tmp->next;
}
while (tmp2)
{
k = tmp2->val+flag;
tmp->next = new ListNode(k % 10);
flag = k / 10;
tmp2 = tmp2->next;
tmp = tmp->next;
}
if(flag)
tmp->next = new ListNode(1);
return res;
}
};
lessons

题目思路其实就像平时算加法一样,从后向前算,考虑进位。开始傻傻地想要把两个list倒过来,得到两个整数进行相加,然后发现长整形的范围远不能满足题目要求,所以才改成了上面那样。看了看别人的代码,发现我的三个while循环实在有些冗杂,可以整理成一个循环,主要考虑对第一个while循环条件进行修改( && -> || ),后面的做法就比较类似了。有点乏了,先不改了,就这样吧。

Description:

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

本来想找道很简单的题目消磨时间,出了好几次错之后,觉得自己的水平真是,惨不忍睹——不仅至今没有处理异常的习惯,连整数数组里面出现负数的情况都没有考虑……

最先想到的是直接遍历的方法,时间复杂度为O(n^2):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> a;
for(int i=0;i<nums.size();i++)
{
int x = target - nums[i];
for (int j = i + 1; j < nums.size(); j++)
{
if (nums[j] == x)
{
a.push_back(i);
a.push_back(j);
return a;
}
}
}
throw "Bad Input !";
}
};

Virtual Bank

模拟银行的多线程程序,实现如下要求:

  1. 银行于某时刻开始营业,运行若干时间后下班,窗口最上方会显示营业或下班的信息。到了下班时间,不再产生新的客户,只将等待的客户处理完,然后银行关门。
  2. 营业期间有多名顾客随机地来银行存钱、取钱,顾客的原有存款金额是随机生成的,此次交易需要的时间以及交易金额也是随机生成的。不允许透支,若取钱时余额不足,则退出本次操作。在窗口显示当前客户的序号、交易时长、操作金额和余额;
  3. 只有一名工作人员提供服务,若顾客数为0,则进行等待;
  4. 每次存取钱,在窗口显示当前有多少顾客在等待,以及银行目前的金额;
  5. 银行处理完所有的交易,关门时再报告今日受理客户总数以及银行余额;
  6. 程序运行的过程中在控制台打印出今日所有的交易记录。

    自定义类型:

  • Customer:客户类;

  • CustomerLine:客户队列;

  • CustomerGen:客户生成器;

  • Teller:工作人员

  • MyWindow:银行信息窗口

  • VirtualBank:模拟银行(主程序)

    运行效果

    • avatar
    • avatar
    • avatar

主类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class VirtualBank{

public static void main(String[] args)throws Exception {
//银行交易显示窗口
MyWindow myWindow=new MyWindow();
myWindow.display();

//客户队列
CustomerLine line=new CustomerLine(50,myWindow);
CustomerGen gen=new CustomerGen(line,myWindow);

//银行工作人员
Teller teller=new Teller(line,myWindow);

gen.start();
teller.start();

//下班时间到了,不再接待客户
TimeUnit.SECONDS.sleep(5);
gen.exit = true;
TimeUnit.SECONDS.sleep(4);
teller.exit = true;

//处理完剩余业务,银行关门
TimeUnit.SECONDS.sleep(1);
myWindow.textField_5.setText("交易完毕");
System.out.println("剩余的业务处理完毕 银行剩余钱数:"+teller.total+" 今日受理客户总数:"+teller.num);

}

}

客户类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class Customer 
{
public int balance;//客户余额
public int time;//客户服务时长
public boolean deposit;//客户操作类型,如果为true则为存款,false为取款
public int money;//客户操作金额
public MyWindow w1;//银行窗口显示信息
public Customer(int balance,int time,int depos,int money,MyWindow w)
{
this.balance=balance;this.time=time;this.money=money;
w1=w;
if(depos==0)
{//存钱
deposit=true;
}
else
deposit=false;
}
public synchronized boolean withdrawal()
{//取钱
w1.textField_9.setText("时长:"+time);
if(balance<money)
{//余额不足
System.out.print("时长:"+time+" 原存款:"+balance);
w1.textField_2.setText("取款:"+money);
w1.textField_3.setText("余额:"+balance+"(不足)");
System.out.println(" 取款:"+money+",余额:"+balance+"(不足) 操作失败");
return false;//取钱失败
}
else{
System.out.print("时长:"+time+" 原存款:"+balance);
balance=balance-money;
w1.textField_2.setText("取款:"+money);
w1.textField_3.setText("余额:"+balance);
System.out.println(" 取款:"+money+",余额:"+balance+" 操作成功");
return true;//取钱成功
}
}

public synchronized void deposit()
{//存钱
System.out.print("时长:"+time+" 原存款:"+balance);
w1.textField_9.setText("时长:"+time);
balance+=money;
w1.textField_2.setText("存款:"+money);
w1.textField_3.setText("余额:"+balance);
System.out.println(" 存款"+money+",余额:"+balance);
}
}

客户队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*ArrayBlockingQueue:
A bounded blocking queue backed by an array. This queue orders elements FIFO (first-in-first-out).
Once created, the capacity cannot be changed.
Attempts to put an element into a full queue will result in the operation blocking;
attempts to take an element from an empty queue will similarly block.
*/
class CustomerLine extends ArrayBlockingQueue<Customer>
{//客户队列
public MyWindow w2;//银行窗口显示信息
public CustomerLine(int maxSize,MyWindow w)
{
super(maxSize);
w2=w;
}
}

随机产生客户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//随机产生顾客
class CustomerGen extends Thread
{
Random rand=new Random();
public boolean exit=false;//false表示银行仍在受理新来客户,可以继续产生客户
CustomerLine line;//客户队列
public MyWindow w3;//银行窗口显示信息
//得到顾客的队列
public CustomerGen(CustomerLine line,MyWindow w)
{
this.line=line;
w3=w;
}

public void run()
{
try
{//一直产生新的客户
while(!exit)
{
//随机时间里面产生顾客,产生的顾客需求也是随机地,客户的初始余额也是随机的
TimeUnit.MILLISECONDS.sleep(rand.nextInt(1000));
//然后队列里面添加一个随机地顾客
line.put(new Customer(rand.nextInt(1000),rand.nextInt(1000),rand.nextInt(2),rand.nextInt(1000),w3)); //随机的顾客需求
}
}
catch(InterruptedException e)
{
System.out.println("顾客线程出错!");
e.printStackTrace();
}

w3.textField.setText(" 下班时间到了");
System.out.println("\n工作人员要下班啦!不再受理新来客户\n");
}
}

工作人员

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

//工作人员
class Teller extends Thread
{
public boolean exit=false;//false表示没有下班
public int num=0;//已服务的客户数
private CustomerLine line;//顾客队列
public int total=10000;//银行余额
public MyWindow w4;//银行窗口显示信息
public Teller(CustomerLine line,MyWindow w)
{
this.line=line;
w4=w;
}

public void run()
{
try
{
while(!exit)
{
if(line.size()==0)
{
//若没有客户,则进行等待
w4.textField_8.setText("0");
continue;
}
//Retrieves and removes the head of this queue,
//waiting if necessary until an element becomes available.
//队列里面排第一个的顾客脱离队伍,接受服务
Customer customer = line.take();
//这个要被服务的时间队列需要停顿,停顿时间有当前的customer决定
TimeUnit.MILLISECONDS.sleep(customer.time);

//显示顾客信息
if(customer.deposit)
{//存钱
customer.deposit();
total+=customer.money;
}
else
{//取钱
if(customer.withdrawal())
total-=customer.money;
}
w4.textField_6.setText(""+total);

//服务客户数量加一
// synchronized(this)
{
num++;
w4.textField_1.setText("第"+num+"位客户");
w4.textField_8.setText(""+line.size());
w4.textField_6.setText(""+total);
System.out.println("当前服务顾客数:"+num+",当前等待人数:"+line.size()+",银行余额:"+total);
System.out.println();
}
}
}
catch(InterruptedException e)
{
w4.textField_1.setText("银行服务线程出错!");
System.out.println("银行服务线程出错!");
e.printStackTrace();
}
}
}

银行窗口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//银行窗口
class MyWindow extends JFrame{
public static JPanel contentPane;
public static JTextField textField;//显示“上班时间”或“下班时间”
public static JTextField textField_1;//第几位客户
public static JTextField textField_2;//交易金额
public static JTextField textField_3;//客户余额
public static JTextField textField_4;
public static JTextField textField_5;//交易状态
public static JTextField textField_6;//银行余额
public static JTextField textField_7;
public static JTextField textField_8;//正在等待的人数
public static JTextField textField_9;//交易时长


/**
* Launch the application.
*/
public void display()throws Exception {
//显示窗口
MyWindow frame = new MyWindow();
frame.setVisible(true);
}

/**
* Create the frame.
*/
public MyWindow() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);

textField = new JTextField();
textField.setBackground(Color.PINK);
textField.setText(" 正在营业 ");
textField.setColumns(10);

textField_1 = new JTextField();
textField_1.setText("第0位客户");
textField_1.setColumns(10);

textField_2 = new JTextField();
textField_2.setText("交易:0");
textField_2.setColumns(10);

textField_3 = new JTextField();
textField_3.setText("余额:0");
textField_3.setColumns(10);

textField_4 = new JTextField();
textField_4.setText("银行余额");
textField_4.setColumns(10);

textField_5 = new JTextField();
textField_5.setBackground(Color.PINK);
textField_5.setText("正在交易");
textField_5.setColumns(10);

textField_6 = new JTextField();
textField_6.setText("0");
textField_6.setColumns(10);

textField_7 = new JTextField();
textField_7.setText("等待人数");
textField_7.setColumns(10);

textField_8 = new JTextField();
textField_8.setText("0");
textField_8.setColumns(10);

textField_9 = new JTextField();
textField_9.setText("时长:0");
textField_9.setColumns(10);

//布置文本框位置
GroupLayout gl_contentPane = new GroupLayout(contentPane);
gl_contentPane.setHorizontalGroup(
gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(84)
.addComponent(textField, GroupLayout.PREFERRED_SIZE, 222, GroupLayout.PREFERRED_SIZE)
.addContainerGap(112, Short.MAX_VALUE))
.addGroup(gl_contentPane.createSequentialGroup()
.addGroup(gl_contentPane.createParallelGroup(Alignment.TRAILING, false)
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(157)
.addComponent(textField_3))
.addGroup(Alignment.LEADING, gl_contentPane.createSequentialGroup()
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
.addComponent(textField_7, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(textField_8, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(61)
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING, false)
.addComponent(textField_2)
.addComponent(textField_1, 0, 0, Short.MAX_VALUE)
.addComponent(textField_5, GroupLayout.DEFAULT_SIZE, 87, Short.MAX_VALUE)
.addComponent(textField_9))))
.addPreferredGap(ComponentPlacement.RELATED, 69, Short.MAX_VALUE)
.addGroup(gl_contentPane.createParallelGroup(Alignment.TRAILING, false)
.addComponent(textField_6)
.addComponent(textField_4)))
);
gl_contentPane.setVerticalGroup(
gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addGap(15)
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(18)
.addComponent(textField_5, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.UNRELATED)
.addComponent(textField_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(textField_9, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(38)
.addComponent(textField_4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(textField_6, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(textField_2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(35)
.addComponent(textField_7, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addGap(18)
.addComponent(textField_8, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(textField_3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
contentPane.setLayout(gl_contentPane);
}
}

UDP通信

DatagramSocket socket用于发送和接收报文
DatagramPacket packet用来表示报文
socket.send(package)/receive(package);

packet.getData()得到byte数组
packet.getAddress()得到InetAddress
InetAddress.getByName(hostname)

集合框架Holding Objects

集合中只能容纳对象

对象容纳的方式

数组 Arrays类

fill(),equals(),sort(),binarySearch()

数组元素的比较:
  1. implements Comparable 接口,compareTo(T o),Arrays.sort(Object[]a)
  2. implements Comparator 接口,compare(T o1,T o2),equals(Object obj)
    Arrays.sort(Object[]a,Comparator c)
    数组需要先排序,再查找。
    数组长度确定、类型确定,不够灵活
    集合Collection,Map
    Collection:ArrayList(),LinkedList(),HashSet()…
    Collection c; c.add()
    Map m; m.put(key,value)
    Map的key值、set类不可重复,List可重复
    Collection接口
    Iterator iterator()返回迭代器,size(),contains(),containsAll(Collection c),retainAll(Collection c)删除集合c中不包含的元素…
    迭代器Iterator
    hasNext(),remove(),next()返回集合元素的引用
    Set接口
    Set接口集成Collection接口,不允许存在重复项
    对象是否相同:hashCode()&&equals()
    HashSet
    Object都有hashCode()方法
    List列表
    ArrayList、Vector、LinkedList双向链表
    Map
    HashMap
    hashCode()
    TreeMap
    key有序-Comparable\Comparator

…implement Externalizable
实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)
函数中调用(out.writeObject()/in.readObject())

readExternal()需要无参public构造方法

StreamTokenizer(Reader r)

Reader:以字符为单位的输入流

  • 对输入流进行解析,调用nextToken()
  • public int ttype,ttype的常数值:TT_WORD(字符串存入String nval),TT_NUMBER,TT_EOL

A TreeMap can keep keys in sorted order.
Counter()计数器、Set、Collection

StringTokenizer

正则表达式

(java.util.regex)
Pattern p=Pattern.compile(“…”)
Matcher m=p.matcher(“……”)
m.find()

Scanner文本扫描器

构造方法(File)(String)(InputStream)

网络编程

  • 使用URL
  • TCP编程
  • UDP编程

    URL类

    统一资源定位符(Uniform Resource Locator)
    构造方法
    (“http://www.nankai.edu.cn")
    (String Protocol(协议),String host,int port(缺省80端口),String file)

获取信息:getProtocol(),getHost(),getRef(),getPort(),getFile()…

利用URL获取网络资源
  • 创建URL对象
  • 使用URL对象的使用openStream(),返回InputStream
  • 从InputStream读入信息

    InetAddress类

    代表一个IP地址
    创建方法:static InetAddress getByName(“…”)
    获取本机地址:
  • getLocalHost()
  • getByName(null)
  • getByName(“127.0.0.1”)
  • getByName(“localhost”)
TCP:有连接的、可靠的数据流的传输有通信协议

使用:
Socket类(进行通讯)、ServerSocket类(提供监听)
(客户端只使用Socket,服务器端两个都需要)

Server端:

一个服务器可服务多个客户端->多客户机制->多线程
ServerSocket(int port,int count)
ServerSocket.accept(),返回Socket.若未返回,则线程阻塞
OutputStream<==>InputStream
Socket.getInputStream()

Client端:

Socket(String addr,int port)

UDP:无连接的、数据报的方式

使用DatagramPacket类(报文)、DatagramSocket类(发送或接收)

DatagramPacket构造:
  • 接收:(byte[] recvBuf,int readLength)
  • 发送:(byte[] sendBuf,int readLength,InetAddress,int port)
    socket.send(packet)
    socket.receive(packet)
    广播通信
    MulticastSocket

输入输出流

RandomAccessFile(file,mode)
mode:”r”,”rw”
EOFException:读到文件末尾

InputStream、OutputStream

过滤流

FilterInputStream(InputStream in)
FilterOutputStream(OutputStream out)
在原有输入输出流的基础上提供新的功能

  • BufferedInputStream(有缓冲区,不必每次访问外设)
  • DataInputStream:基本数据类型的读写,readInt/Float/Boolean
  • PipedInputStream(PipedOutputStream src)
    构造:PipedInputStream(PipedOutputStream src)
    connect(PipedOutputStream src)

    字符流

    reader
    read()
    readLine()
    markSupported()
    生成流对象 public BufferedReader(Reader in)
    PrintWriter(new FileWriter(“test.txt”),true)
    InputStreamReader 字节流和字符流的中介
    public InputStreamReader(InputStream in,String enc(编码格式))
    public String getEncoding()
    System.in:以字节为单位的输入流

    System类

    重定向:System.setIn(InputStream)
    流结束的判断
    read()返回-1
    readXXX()返回EOF
    readLine()返回null
    I/O异常

    Object Serialization

    InputStream子类:ObjectInputStream对象输入流
    对象的序列化
  • 支持远程方法调用(RMI)
  • 支持本地存储(JavaBean)
  1. 实现接口Serialization(可串行化)才可以被序列化,作为标志。
  2. 调用readObject(),writeObject()

从对象输入流读对象时需要.class文件(当前目录下) ClassNotFoundException

Serialization控制方法:
  1. 关键字transient(该数据不会被写入,文件中为null)
  2. 实现Externalization接口,writeExternal()方法,readExternal()需要不带参数的public构造方法

创建线程

实现Callable接口
V call() (有返回值,区别于run())

ExecutorService接口
Future submit(Callable task)提交线程

Future接口,异步返回结果
方法:isDone(),isCancelled(),get(),cancel()…
通过Executor接口创建,包含execute方法

Executors类,提供方法:newCachedThreadPool()线程池,返回ExecutorService

创建线程池fixed\single\cached Thread,减少线程开销

最后需关闭线程池shutdown()

FutureTask类 implements
可作为线程/Fututre使用

并发与Swing

Swing组件属性的修改->事件分派线程处理
SwingUtilities.invokeLater(Runnable)主线程中的操作放到事件分派线程
invokeandWait()阻塞

Daemon threads守护线程,其子线程也是守护线程
若无其他线程,则结束
isDaemon(),setDaemon(true/false)

线程优先级setPriority()
子线程继承父线程优先级

yield()与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会。

第九章 输入输出处理

File类

构造:File(filedir,filename);
列出目录中的文件名String[] list();list(FilenameFilter)
FilenameFilter,accept方法

Arrays.sort()

读输入流,写输出流

  • 字节流-stream byte为单位
  • 字符流-reader,writer 16位unicode码为单位

InputStream/OutputStream

基本方法:
  • read(),skip(long)跳过n个字节,markSupported(),mark()当前位置做标记,reset()回到最近一次标记处,close()
  • write(),flush(),close()
RandomAccessFile类

随机访问,实现了dataInout,dataOutput接口,可以有格式读写
dataInput接口:readInt(),readLine()…
dataOutput接口 同理

  • 构造方法:RandomAccessFile(String name或File file,String mode)
  • 指针操作:getFilePointer()偏移量,seek(),skipBytes()
    close(),length(),

线程

方法:

  1. 自定义实现runnable接口
    重载run()操作,作为参数创建Thread
  2. 继承Thread类
    extends Thread,间接实现runnable
    run(),start()开始执行run(),Thread implements Runnnable
Thread构造方法

参数:无参、线程名、runnable
内部类保存了外部类的指针

Thread.sleep(100)休眠一百毫秒

注意使用try-catch(sleep可能被打断)
==native==方法:调用本地的、底层的代码,主要用于执行run()

对共享数据的访问不完整性=>解决方法:
  • 做成一个整体:synchronized,修饰方法或代码段,每个包含synchronized的对象使用一把互斥锁
  • 使用时避免死锁
  • 若修饰一个静态方法,所有对象共用一把互斥锁

    线程生命周期

    新建、就绪、执行、阻塞/消亡
    yield()放弃run()回到就绪
    blocked:I/O操作、wait()释放互斥锁、sleep()和suspend()不释放互斥锁

wait()与notify():
消费者生产者模式,实现线程间通信

但可能造成死锁,synchronized,同时等待对方放弃自己需要的资源