Quck Dev env for PHP
http://www.apachefriends.org/en/index.html
IDE: Eclipse PDT all in one.
http://www.apachefriends.org/en/index.html
IDE: Eclipse PDT all in one.
http://www.yesky.com/418/1743418_5.shtml
http://java.chinaitlab.com/line/10270.html
http://fanqiang.chinaunix.net/program/java/2005-07-04/3363.shtml
http://www.21tx.com/dev/2002/02/22/10107.html
http://www.ddvip.com/program/java/index2/79.htm
http://www.ddvip.com/program/java/index2/78.htm
http://www.21tx.com/dev/2005/04/07/14818.html
Java 语言本身提供了执行外部程序的机制,那就是java.lang.Runtime。改类自Java诞生就已经从在,这个可以从见JDK帮助文档的Since得到。随着Java的发展,该类也多次修订。http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Runtime.html
改类提供了6个重载的方法(截至目前1.5版本),我们把它拷过来,用作参考:
Process exec(String command)
Executes the specified string command in a separate process.
Process exec(String[] cmdarray)
Executes the specified command and arguments in a separate process.
Process exec(String[] cmdarray, String[] envp)
Executes the specified command and arguments in a separate process with the specified environment.
Process exec(String[] cmdarray, String[] envp, File dir)
Executes the specified command and arguments in a separate process with the specified environment and working directory.
Process exec(String command, String[] envp)
Executes the specified string command in a separate process with the specified environment.
Process exec(String command, String[] envp, File dir)
Executes the specified string command in a separate process with the specified environment and working directory
按照文档上说,这行exec,就会产生一个与操作系统相关的process,Java用Process与之相联系,就是在Process里面有个这个实际的Process的引用。类Process的说明如下:
The ProcessBuilder.start() and Runtime.exec methods create a native process and return an instance of a subclass of Process that can be used to control the process and obtain information about it.
就是说执行了exec,剩下的(输入,输出,等待结束,结束返回值等等)就交给Process具体的实现类来处理:
The class Process provides methods for performing input from the process, performing output to the process, waiting for the process to complete, checking the exit status of the process, and destroying (killing) the process.
网络上有很多介绍的文章,但是如果你看了还是不是很明白的话,其实最重要的还是回到JDK的帮助文档里来,在类Process的文档剩下的部分写的很明白:
The methods that create processes may not work well for special processes on certain native platforms, such as native windowing processes, daemon processes, Win16/DOS processes on Microsoft Windows, or shell scripts. The created subprocess does not have its own terminal or console. All its standard io (i.e. stdin, stdout, stderr) operations will be redirected to the parent process through three streams (getOutputStream(), getInputStream(), getErrorStream()). The parent process uses these streams to feed input to and get output from the subprocess. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.
The subprocess is not killed when there are no more references to the Process object, but rather the subprocess continues executing asynchronously.
There is no requirement that a process represented by a Process object execute asynchronously or concurrently with respect to the Java process that owns the Process object.
简单的说,所有的标准IO操作都会转给父进程,父进程需要用那三种流给子进程。更糟的是标准输入输出流的缓冲啊,就是buffer,有些操作系统给的是有限的(废话),那么不能及时写输入和读输出给子进程就或许导致子进程被block或者甚至死锁!
明白了上边的几点,我们来看一段例程,就比较清楚了:
直接使用参考文献1中的例程:
public class BadExecJavac
{
public static void main(String args[])
{
try
{
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(”javac”);
int exitVal = proc.exitValue();
System.out.println(”Process exitValue: ” + exitVal);
}
catch (Throwable t)
{
t.printStackTrace();
}
}
}
执行结果如下:
java.lang.IllegalThreadStateException: process has not exited
at java.lang.ProcessImpl.exitValue(Native Method)
at com.test.tools.test.book.Test.main(Test.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
什么原因呢? 查查文档,原来是说子进程还未结束,如果call exitValue()的话,就会报错。
老方法,查查文档,Process有个waitFor() 方法:
public abstract int waitFor()
throws InterruptedException
Process object has terminated. This method returns immediately if the subprocess has already terminated. If the subprocess has not yet terminated, the calling thread will be blocked until the subprocess exits. 0 indicates normal termination. InterruptedException - if the current thread is interrupted by another thread while it is waiting, then the wait is ended and an InterruptedException is thrown.好,我们立即改进我们的程序,使用waitFor():
public class Test
{
public static void main(String args[])
{
try
{
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(”javac”);
int exitVal = proc.waitFor();
System.out.println(”Process exitValue: ” + exitVal);
}
catch (Throwable t)
{
t.printStackTrace();
}
}
}
编译,运行。。。结果。。。结果。。。好像死在那里了#¥@%@@
好惨。。。立刻反省一下哪里错了?原来前文有提:我们没有处理输入,输出流×可能会×导致死锁! Javac执行如上的话,会把结果输入到stderr流中去的,结果父进程没有处理(所有的外部流都导给父进程,见文档),子进程等父进程处理,父进程等子进程结束(waitFor()),典型的死锁情节。下面,我们的程序需要加上流的处理的部分!
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Test
{
public static void main(String args[])
{
try
{
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(”javac”);
//prepare to receive input err stream directed to This Process to drain.
InputStream stderr = proc.getErrorStream(); 得到错误流
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
String line = null;
System.out.println(”<ERROR>”);
while ((line = br.readLine()) != null)
{
System.out.println(line);
}
System.out.println(”</ERROR>”);
int exitVal = proc.waitFor();
System.out.println(”Process exitValue: ” + exitVal);
}
catch (Throwable t)
{
t.printStackTrace();
}
}
}
运行结果如下:
<ERROR>
用法:javac <选项> <源文件>
其中,可能的选项包括:
-g 生成所有调试信息
-g:none 不生成任何调试信息
-g:{lines,vars,source} 只生成某些调试信息
-nowarn 不生成任何警告
-verbose 输出有关编译器正在执行的操作的消息
-deprecation 输出使用已过时的 API 的源位置
-classpath <路径> 指定查找用户类文件的位置
-cp <路径> 指定查找用户类文件的位置
-sourcepath <路径> 指定查找输入源文件的位置
-bootclasspath <路径> 覆盖引导类文件的位置
-extdirs <目录> 覆盖安装的扩展目录的位置
-endorseddirs <目录> 覆盖签名的标准路径的位置
-d <目录> 指定存放生成的类文件的位置
-encoding <编码> 指定源文件使用的字符编码
-source <版本> 提供与指定版本的源兼容性
-target <版本> 生成特定 VM 版本的类文件
-version 版本信息
-help 输出标准选项的提要
-X 输出非标准选项的提要
-J<标志> 直接将 <标志> 传递给运行时系统
</ERROR>
Process exitValue: 2
Process finished with exit code 0
因为我在IDE里运行的,所以你会看到退出码是0,就是这个java类运行是正常。但是对于javac在例程中运行code是2.不同系统不同意义,这里代表文件没有找到。一般来说,0代表正常,非0都代表错误。
这段程序对这个例子来说足够了,但是缺乏灵活和完美!最要命的是这个程序还没有处理标准输入和输出流。
在开始完美化之前,先说说一个常见的错误。或许你已经迫不及待的编写和运行如下程序,结果发现是有问题的:
public class Test
{
public static void main(String args[])
{
try
{
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(”dir”);
InputStream stdin = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(stdin);
BufferedReader br = new BufferedReader(isr);
String line = null;
System.out.println(”<OUTPUT>”);
while ((line = br.readLine()) != null)
{
System.out.println(line);
}
System.out.println(”</OUTPUT>”);
int exitVal = proc.waitFor();
System.out.println(”Process exitValue: ” + exitVal);
}
catch (Throwable t)
{
t.printStackTrace();
}
}
}
为什么不行呢?这是因为dir这个命令需要windows 命令解释器,而不是一个单独存在的命令!也就是说该程序无法找到dir.
现在就让我们开始振奋人心的编程吧!采用一个专门的类处理外部程序需要输出的流,对于我们来说就是输入流。采用线程执行,所以可以异步的处理多个流。
/**
* gobbler
1. 雄火鸡
2. 狼吞虎咽的人
*/
class StreamGobbler extends Thread
{
InputStream is;
String type;
StreamGobbler(InputStream is, String type)
{
this.is = is;
this.type = type;
}
public void run()
{
try
{
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
{
System.out.println(type + “>” + line);
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
class GoodWindowsExec
{
public static void main(String args[])
{
if (args.length < 1)
{
System.out.println(”USAGE: java GoodWindowsExec <cmd>”);
System.exit(1);
}
try
{
String osName = System.getProperty(”os.name”);
String[] cmd = new String[3];
if (osName.equals(”Windows NT”))
{
cmd[0] = “cmd.exe”;
cmd[1] = “/C”;
cmd[2] = args[0];
}
else if (osName.equals(”Windows 95″))
{
cmd[0] = “command.com”;
cmd[1] = “/C”;
cmd[2] = args[0];
}
Runtime rt = Runtime.getRuntime();
System.out.println(”Execing ” + cmd[0] + ” ” + cmd[1]
+ ” ” + cmd[2]);
Process proc = rt.exec(cmd);
// any error message?
StreamGobbler errorGobbler = new
StreamGobbler(proc.getErrorStream(), “ERROR”);
// any output?
StreamGobbler outputGobbler = new
StreamGobbler(proc.getInputStream(), “OUTPUT”);
// kick them off
errorGobbler.start();
outputGobbler.start();
// 还是惹不起那些进程,我等。
int exitVal = proc.waitFor();
System.out.println(”ExitValue: ” + exitVal);
}
catch (Throwable t)
{
t.printStackTrace();
}
}
}
用这个方式执行:
列目录,java GoodWindowsExec “dir *.java” 。
打开word文档,java GoodWindowsExec “yourdoc.doc”。其他就不赘述了。
另外,要记住,exec不是个命令解释器,它的作用只是运行命令。千万不要认为exec() method 好像一个shell interpreter。如果你那么认为,就会犯下面的错误:
class BadWinRedirect
{
public static void main(String args[])
{
try
{
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(”java jecho ‘Hello World’ > test.txt”);
// any error message?
StreamGobbler errorGobbler = new
StreamGobbler(proc.getErrorStream(), “ERROR”);
// any output?
StreamGobbler outputGobbler = new
StreamGobbler(proc.getInputStream(), “OUTPUT”);
// kick them off
errorGobbler.start();
outputGobbler.start();
// any error???
int exitVal = proc.waitFor();
System.out.println(”ExitValue: ” + exitVal);
}
catch (Throwable t)
{
t.printStackTrace();
}
}
}
该程序本意是想执行jecho ‘Hello World‘,然后把执行结果存入test.txt。Sorry,错了。你必须用编程的方法来实现。还记得我们前面说过子进程的输出流么,把子进程的输出流===》得到,然后存入test.txt就可以实现了。
有点晕?呵呵。我们里一下思路。该例程运行程序(java jecho ‘Hello World’),产生个子进程,子进程产生输出流。子进程如前所述没有地方释放,需要父进程排泄。所以,对父进程来说,就是得到proc.getInputStream(), 就是把子进程要输出的东西得到。
这样还需要改进一下我们(吃流者)这个类。SteamBobbler.:) 如下:
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
class StreamGobbler extends Thread
{
InputStream is;
String type;
OutputStream os;
StreamGobbler(InputStream is, String type)
{
this(is, type, null);
}
StreamGobbler(InputStream is, String type, OutputStream redirect)
{
this.is = is;
this.type = type;
this.os = redirect;
}
public void run()
{
try
{
PrintWriter pw = null;
if (os != null)
{
pw = new PrintWriter(os);
}
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
{
if (pw != null)
{
pw.println(line);
}
System.out.println(type + “>” + line);
}
if (pw != null)
{
pw.flush();
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
class GoodWinRedirect
{
public static void main(String args[])
{
if (args.length < 1)
{
System.out.println(”USAGE java GoodWinRedirect <outputfile>”);
System.exit(1);
}
try
{
FileOutputStream fos = new FileOutputStream(args[0]);
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(”java jecho ‘Hello World’”);
// any error message?
StreamGobbler errorGobbler = new
StreamGobbler(proc.getErrorStream(), “ERROR”);
// any output?
StreamGobbler outputGobbler = new
StreamGobbler(proc.getInputStream(), “OUTPUT”, fos);
// kick them off
errorGobbler.start();
outputGobbler.start();
// any error???
int exitVal = proc.waitFor();
System.out.println(”ExitValue: ” + exitVal);
fos.flush();
fos.close();
}
catch (Throwable t)
{
t.printStackTrace();
}
}
}
OK,大功告成,基本上成功。
小结如下:
本文完。下期谈谈如何使用目录,环境变量等高级话题。
参考文档:
http://www.maisonbisson.com/blog/post/10900/#section-3
bsuite是一款wordpress统计插件,它的前身是bstat,简单好用的来访者统计插件。
它的功能如下:
百度笔试题目(转)
题目大致是这样的:
第一部分选择题:有几道网络相关的题目,巨简单,比如第一题是TCP、RIP、IP、FTP中哪个协议是传输层的……。有一道linux的chown使用题目。其他的全是数据结构的题目!什么链,表,码的,不知所云~~~唉,我可以没有学过数据结构的人呐!真残忍!这一部分迅速猜完!
第二部分简答题:
1、在linux中如何编译C程序,使之成为可执行文件?如何调试?
答案:1)检查程序中.h文件所在的目录,将其加入系统PATH中;
2)执行C编译:#gcc [源文件名] -o [目标文件名]
执行C++编译:#g++ [源文件名] -o [目标文件名]
3)改变目标文件为可执行文件:#chmod +x [目标文件名]
4)如需将多个可执行文件连续执行,可生成批处理文件:
#vi [批处理文件名]
可执行文件1
可执行文件2
………
最后将该批处理文件属性该位可执行。
调试:在编译时使用-g参数,就可以使用gdb进行调试。
2、写出内存分配和释放的函数,并指出区别。
答案:
C语言的标准内存分配函数:malloc,calloc,realloc,free等。
malloc与calloc的区别为1块与n块的区别:
malloc调用形式为(类型*)malloc(size):在内存的动态存储区中分配一块长度为“size”字节的连续区域,返回该区域的首地址。
calloc调用形式为(类型*)calloc(n,size):在内存的动态存储区中分配n块长度为“size”字节的连续区域,返回首地址。
realloc调用形式为(类型*)realloc(*ptr,size):将ptr内存大小增大到size。
free的调用形式为free(void*ptr):释放ptr所指向的一块内存空间。
C++中为new/delete函数。
3、写出socket函数,并指出其功能。
socket():建立socket通信描述符;
bind():将套接字和机器上的一定的端口关联;
connect():连接到远程主机;
listen():使套接字做好连接的准备,规定等待服务请求队列的长度;
accept():接受连接,一旦有客户端发出连接,accept返回客户地址信息和一个新的sock;
有了这个新的sock,双方就可以开始收发数据:
send()和recv():用于流式套接字或者数据套接字的通讯;
sendto()和recvfrom():用于无连接的数据报套接字;
close():关闭套接字;
shutdown():选择性的关闭套接字,可以只允许某一方向的通讯关闭;
getpeername():返回流式套接字时对端peer信息;
gethostname():返回程序所运行的机器的主机名字;
gethostbyname():返回本机IP;
第三部分编程题:
1、从文件中读取字符串数据,反序显示并大小写转换。
2、给定26字母表以及对应的密码表,编程实现加密及解密功能。
第四部分思考题(正是传说中的字典纠错题):
用户在输入英文单词时经常出错,现对其进行就错。给定一个正确的英文词典,考虑纠错实现。1)指出思路。2)流程、算法难易程度及可能的改进策略。
一道算法题目答案
int Replace(Stringtype &S,Stringtype T,Stringtype V);//将串S中所有子串T替换为V,并返回置换次数
{
for(n=0,i=1;i〈=Strlen(S)-Strlen(T)+1;i++) //注意i的取值范围
if(!StrCompare(SubString(S,i,Strlen(T)),T)) //找到了与T匹配的子串
{ //分别把T的前面和后面部分保存为head和tail
StrAssign(head,SubString(S,1,i-1));
StrAssign(tail,SubString(S,i+Strlen(T),Strlen(S)-i-Strlen(T)+1));
StrAssign(S,Concat(head,V));
StrAssign(S,Concat(S,tail)); //把head,V,tail连接为新串
i+=Strlen(V); //当前指针跳到插入串以后
n++;
}//if
return n;
}//Replace
分析:i+=Strlen(V);这一句是必需的,也是容易忽略的.如省掉这一句,则在某些情况下,会引起不希望的后果,虽然在大多数情况下没有影响.请思考:设S=’place’, T=’ace’, V=’face’,则省掉i+=Strlen(V);运行时会出现什么结果? (无限递归face)
百度2005年的笔试题
1.实现 void delete_char(char * str, char ch);
把str中所有的ch删掉
2.把字符串S中所有A子串换成B,这个没给函数原型
3.搜索引擎的日志要记录所有查询串,有一千万条查询,不重复的不超过三百万
要统计最热门的10条查询串. 内存<1G. 字符串长 0-255
(1) 主要解决思路 //具体用词和原题不大一样
(2) 算法及其复杂度分析
4.有字典,设计一个英文拼写纠正算法 (1) 思想 (2) 算法及复杂度 (3) 改进
5. { aaa, bb, ccc, dd }, { bbb, ff }, { gg } 等一些字符串的集合
要求把交集不为空的集合并起来,如上例会得到 { aaa, bb, ccc, dd, ff }, {gg}
(1) 思想 (2) 算法及复杂度 (3) 改进