Java 调试中你可能会遇到的问题以及如何解决他们

[TOC]

原文链接

当你的生产环境发生了异常的时候,事情变得艰难.Made Up Stats™ 的科学研究表明开发者团队会收到比平时更大的压力,咖啡杯脏的比平时快3倍而且上帝杀死了两只小猫因为一只是不够的(嗯…. 这个猫的梗有点污,原文是 god kills 2 kittens because one is just not enough. 查了一下取自一个梗…每当你手淫的时候,上帝会杀死一只猫).在下面的内容中我们将会分析你在调试生产环境的代码面对的主要的问题.接下来让我们用一个正直的警告来开始,这是我们的法律部门强迫我们放在这里的.

警告: 下面的内容包含一些开发者会觉得困扰的生产环境的 bug 的准确描述.

Read More

实现键值对存储 第五部分 Hash table 实现

实现键值对存储-第五部分: Hash table 实现

原文链接

这篇文章是 IKVS 系列的第五部分,”实现一个键值对存储”.你也可以查看 Table of Contents 来查看其他部分.

在这篇文章中,我将会学习C++中实际的 hash table 来理解它的瓶颈在哪里.Hash 函数是 CPU-密集型的操作应该要进行优化.然而,大多数的 hash table 的机制都只是关注于高效的内存和I/O读取,这也是这篇文章主要的焦点.我将会学习三种不同的 C++中的hash table 的实现,同时包含内存中的和硬盘中的,并且会观察这些数据都是怎么组织和访问的.这篇文章将会包含以下内容.

[TOC]

kvstore-part5-intro

Read More

LeetCode 8. 字符串转整数

[Chinese ver]

8. 字符串转整数 (atoi)

[TOC]

实现一个 atoi 方法来将一个 string 转换成一个 integer.

提示:仔细的思考所有可能的输入情况。如果你想要一个挑战,请不要看以下内容并问你自己什么是可能的输入情况。

注意:模糊的指定输入范围就是这个题目的目的(比如没有给输入规范)。你负责收集前面所有的输入要求。

Read More

Serializable

Serializable

通过实现 java.io.Serializable 可以让 class 实现序列化的功能,否则无法使用序列化的功能。一个实现序列化的类的子类都是可以进行序列化的。Serializable 接口没有方法,字段等只是一个标记它是可以序列化的作用。

序列化是指将数据结构或对象状态转换成可取用格式(例如存成文件,存于缓冲,或在网络中传送),并在需要的时候恢复原先状态的过程。

当子类实现了 Serializable 接口而父类没有实现的时候,父类要有一个可以访问的无参构造函数。

在反序列化的时候,没有实现序列化的类字段将会使用 public 或者 protect 的无参构造函数进行初始化。无参构造函数必须是实现序列化的子类可访问的,

如果需要在序列化和反序列化的时候进行一些特殊操作的话,需要自己实现以下某些方法:

Read More

LRU 缓存的魔力

LRU 缓存的魔力

场景

假设这么一个情况,当你需要多次展示同一个图片的时候,如果你重复从硬盘中加载图片的话,那么会造成资源的浪费,甚至可能会OOM.

这个时候我们可以使用 cache 来避免这种情况,我们只从硬盘中加载一次到内存中,然后在需要的时候反复使用这个照片.

但是,当这个 cache 里的资源已经装满的时候,那么我们就必须移除cache里面的某些数据,来给要加入的数据腾出空间.

解决方案

在这种情况下,我们应该选择移除哪些资源才是最有优的呢?显而易见的,我们应该移除之后不会用到的资源,还有就是间隔最久才会用到的资源.这里有一个详细的最优算法如下:
$$
T = m * T_m + T_h + E
$$
其中:

T = 平均内存引用时间

Read More

贪婪算法

贪婪算法

贪婪算法(Greedy Algorithm)也叫算贪心法,贪婪法.它是一个遵循启发式解决问题的算法范式.它的核心思想就是通过在每一步的选择中都选用当前步骤下最优的选择,期望结果是最优的算法.如 旅行推销员问题.

贪婪算法尤其适用于有最优子结构的问题中,最优子结构的意思是局部的最优解可以导出全局的最优解.贪婪算法与动态规划 的不同在于贪婪算法对每一个子问题都作出选择,不能回退;动态规划则会保存以前的运算结果,根据以前的结果对当前进行选择,可以回退.

贪婪算法可以解决一些最优化(如最大值最小值等)问题,比如求图中的最小生成树、求哈夫曼编码…其他大多数的情况都不适用贪婪算法,一旦一个问题可以使用贪婪算法来解决,那么贪婪算法一般是解决这个问题的最好办法.由于贪婪算法的高效性以及其答案比较接近最有结果,也可以作为辅助算法或直接解决一些结果要求不那么精确的问题.

原理

步骤

  1. 建立数学模型来描述问题,并建立一个备选答案区

Read More

LeetCode 7. 数字反转

[Chinese ver]

7. Reverse Integer

颠倒一个 integer 的前后位数。

例子: x = 123, return 321
例子: x = -123, return -321

注意:
输入是一个32位的有符号 integer . 当颠倒的 interger 溢出的时候你的函数应该返回0。


Read More

LeetCode 6. 锯齿形转换

[Chinese ver]

6. ZigZag Conversion

字符串”PAYPALISHIRING”是通过一个如下给定行数的锯齿模式书写的:(你可能想要使用一个固定的字体来更好的显示它)

1
2
3
P A H N
A P L S I I G
Y I R

然后一行一行的读取这个字符串:”PAHNAPLSIIGYIR”
编写代码实现获取一个字符串然后根据给出的行数来实现这个锯齿转换:

1
string convert(string text, int nRows);

convert(“PAYPALISHIRING”, 3) 应该返回 “PAHNAPLSIIGYIR”.

Read More

LeetCode 5.最长的回文字符串

5. Longest Palindromic Substring

给定一个字符串s,找出其中最长的回文格式的子字符串。你可以假设长度的最大值为1000.

Example:

1
2
3
Input: "babad"
Output: "bab"

Note: “aba” is also a valid answer.

Example:

1
2
3
Input: "cbbd"
Output: "bb"

一开始以为palindrome是重复的意思,走了很大的弯路,后来才知道指的是回文格式,就是一个顺着读和反过来读都一样的字符串。
由此可知他有两种情况,一种是奇数的情况,中间的一个字符独立,其余的字符以中间为轴两两对应。另一种是偶数的情况,所有的字符都以中间为轴两两对应。

Read More

LeetCode 4. Median of Two Sorted Arrays [Chinese ver]

[Chinese ver]

4. Median of Two Sorted Arrays

这里有两个有序数组nums1和nums2,他们各自的大小为m和n.
找到这两个数组的中间值,总的时间复杂度应该为O(log (m+n)).

1
2
3
4
Example 1:
nums1 = [1, 3]
nums2 = [2]
中间值是 2.0
1
2
3
4
Example 2:
nums1 = [1, 2]
nums2 = [3, 4]
中间值是 (2 + 3)/2 = 2.5

方法一:

首先尝试了一种比较笨的方法

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
public class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
//需要几个数值
int needNum = 0;
//数值位置
int needIndex = 0;
//中间值
double median = 0;
int big = 0;
int stand = 0;
//合成的数组
int[] insertnum ;
int m = nums1.length;
int n = nums2.length;
if((m+n)%2==0){
needNum = 2;
needIndex = (m+n)/2-1;
}else{
needNum=1;
needIndex = (m+n)/2;
}
insertnum = new int[m+n];
//nums1的下标
int j =0;
//nums2的下标
int k = 0;
for(int i =0;i<m+n;i++){
if(k==n){
insertnum[i] = nums1[j];
j++;
}
else if(j==m){
insertnum[i] = nums2[k];
k++;
}else if(nums1[j]>nums2[k]){
insertnum[i] = nums2[k];
k++;
}else{
insertnum[i] = nums1[j];
j++;
}
}
if(needNum == 1){
median = Double.valueOf(insertnum[needIndex]);
}else{
median = Double.valueOf(insertnum[needIndex]+insertnum[needIndex+1]) /2.0;
}
return median;
}
}

Read More
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×