java的io流是什么模式(Java的IO流详细总结)
java的io流是什么模式(Java的IO流详细总结)输入流:将外部设备中的数据写到内存中Java API中通过类库 java.io 来实现I/O处理数据源:data source. 提供原始数据的原始媒介。常见的:数据库、文件、其他程序、内存、网络连接、IO设备数据源就像水箱,流就像水管中流着的水流。 流是一个抽象、动态的概念,是一连串连续动态的数据集合Java Input/Output 简称Java I/O,从键盘读取数据、操作文件和目录、对文件中进行读写、都是输入输出的处理,例如:
《大数据和人工智能交流》头条号向广大初学者新增C 、Java 、Python 、Scala、javascript 等目前流行的计算机、大数据编程语言,希望大家以后关注本头条号更多的内容。作者:软件设计师天涯雨
Java的IO流(一)
一、IO流概述
1、相关概念
数据源:data source. 提供原始数据的原始媒介。常见的:数据库、文件、其他程序、内存、网络连接、IO设备
数据源就像水箱,流就像水管中流着的水流。 流是一个抽象、动态的概念,是一连串连续动态的数据集合
Java Input/Output 简称Java I/O,从键盘读取数据、操作文件和目录、对文件中进行读写、都是输入输出的处理,例如:
Java API中通过类库 java.io 来实现I/O处理
输入流:将外部设备中的数据写到内存中
输出流 :将内存中的数据写到外部设备中
2、字节流和字符流
字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的;字符流在操作时使用了缓冲区,通过缓冲区再操作文件,因为字节流读取文字字节数据后,不直接操作而是先查找指定表码表,获取对应的文字,简单的说,对文字进行操作就是:字节流 编码表
字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节, 操作字节和字节数组。所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,所以它对多国语言支持性比较好!如果是 音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点
所有文件的储存是都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。在读取文件(特别是文本文件)时,也是一个字节一个字节地读取以形成字节序列.
字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串;字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以
二、IO流的类
【1】写操作举例
例子:将一个字符串写入到一个文件中
思路:此例子操作的是字符串,那么最好使用字符流
FileWriter fw=new FileWriter("demo.txt");
//将数据写入缓冲区
fw.write("Hello World");
//fw.flush();从缓冲区写入硬盘
fw.close(); //包含了从缓冲区写入硬盘的过程,并关闭资源
注意:
1、在windows下使用"\r\n"实现换行,即fw.write("Hello\r\nWorld");
下面是Linux和windows换行通用的写法
private static final String LINE_CHANGE=System.getProperty("line.separator");
public static void main(String[] args) throws IOException
{
FileWriter fw=new FileWriter("demo.txt");
//将数据写入缓冲区
fw.write("Hello" LINE_CHANGE "World");
//fw.flush();从缓冲区写入硬盘
fw.close(); //包含了从缓冲区写入硬盘的过程,并关闭资源
}
2、通过构造函数,以再文件追加内容,以防止覆盖原来的内容
【2】读操作举例:读一个文本文件的内容
方式一:使用read()方法读单个字符
FileReader fr=new FileReader("demo.txt");
int ch=0;
//int ch1=fr.read();
//System.out.println((char)ch1);
//int ch2=fr.read();
//System.out.println((char)ch2);
//int ch3=fr.read();
//System.out.println((char)ch3);
while((ch=fr.read())!=-1)
{
System.out.println((char)ch);
}
方式二:使用read()的重载方法read(char [] ch)方法读
假设文本文件demo.txt的内容为"abcde" 那么读操作的代码如下:
FileReader fr=new FileReader("demo.txt");
char buf[]=new char[3];
int num1=fr.read(buf);//将读取到的字符存储到数组中
System.out.println("读取到的字符为:" new String(buf) "===读取的个数为:" num1);
int num2=fr.read(buf);//将读取到的字符存储到数组中
System.out.println("读取到的字符为:" new String(buf) "===读取的个数为:" num2);
int num3=fr.read(buf);//将读取到的字符存储到数组中
System.out.println("读取到的字符为:" new String(buf) "===读取的个数为:" num3);
输出的结果如下:
终上所述,代码简化如下
FileReader fr=new FileReader("demo.txt");
char buf[]=new char[1024];
int len=0;
while((len=fr.read(buf))!=-1)
{
System.out.println(new String(buf 0 len));
}
练习:文件的复制
答案,方式一
//复制其实就是一读一写的过程
//1、使用字符流读取文件
FileReader fr=new FileReader("demo.txt");
//2、创建一个目的文件
FileWriter fw=new FileWriter("demo1.txt");
//3、循环读循环写
int ch=0;
while((ch=fr.read())!=-1)
{
fw.write(ch);
}
fw.close();
fr.close();
答案,方式二
//复制其实就是一读一写的过程
//1、使用字符流读取文件
FileReader fr=new FileReader("demo.txt");
//2、创建一个目的文件
FileWriter fw=new FileWriter("demo2.txt");
//3、创建一个缓冲区容器,以提高效率
char buf[]=new char[1024];
int len=0;
while((len=fr.read(buf))!=-1)
{
fw.write(buf 0 len);
}
fw.close();
fr.close();
三、IO流缓冲区的操作
1、BufferedWriter和BufferedReader
为了提高效率,我们使用系统专门提供的缓冲区的类
例1 :缓冲区写操作
FileWriter fw=new FileWriter("demo2.txt");
//为了提高效率使用字符流缓冲区,创建一个字符写入流缓冲区对象
BufferedWriter bufw=new BufferedWriter(fw);
//使用缓冲区的写入方法将数据写入到缓冲区中
//bufw.write("hello" System.getProperty("line.separator") "world");
bufw.write("aaaaaaaaaaaaaa");
bufw.newLine();
bufw.write("bbbbbbbbbbbbbb");
//使用刷新方法
bufw.flush();
//缓冲区关闭,同时流对象也关闭
bufw.close();
例2:缓冲区读操作
按照以前读法代码如下:
FileReader fr=new FileReader("demo2.txt");
int len=0;
char buf[]=new char[1024];
while((len=fr.read(buf))!=-1)
{
System.out.println(new String(buf 0 len));
}
优化做法:
FileReader fr=new FileReader("demo2.txt");
BufferedReader bufr=new BufferedReader(fr);
String line=null;
while((line=bufr.readLine())!=null)
{
System.out.println(line);
}
例3:使用缓冲区来实现复制
方式一:
FileReader fr=new FileReader("demo2.txt");
BufferedReader bufr=new BufferedReader(fr);
FileWriter fw=new FileWriter("demo3.txt");
BufferedWriter bufw=new BufferedWriter(fw);
int ch=0;
while((ch=bufr.read())!=-1)
{
bufw.write(ch);
}
方式二:
FileReader fr=new FileReader("demo2.txt");
BufferedReader bufr=new BufferedReader(fr);
FileWriter fw=new FileWriter("demo3.txt");
BufferedWriter bufw=new BufferedWriter(fw);
String line=null;
while((line=bufr.readLine())!=null)
{
bufw.write(line);
bufw.newLine();
bufw.flush();
}
四、字节流
字节流处理图片、视频等二进制数据
1、文件输出流举例
//输出流对象
FileOutputStream fos=new FileOutputStream("demo.txt");
fos.write("ccccc".getBytes());
fos.close();
2、文件输入流举例
//输出流对象
FileInputStream fis=new FileInputStream("demo.txt");
byte buf[] =new byte[1024];
int len=0;
while((len=fis.read(buf))!=-1)
{
System.out.println(new String(buf 0 len));
}
fis.close();
使用字节流实现媒体文件的复制
方式一:
//输出流对象
FileInputStream fis=new FileInputStream("c:\\111.exe");
FileOutputStream fos=new FileOutputStream("c:\\222.exe");
byte buf[] =new byte[1024];
int len=0;
while((len=fis.read(buf))!=-1)
{
fos.write(buf 0 len);
}
fis.close();
fos.close();
方式二:
FileInputStream fis=new FileInputStream("c:\\111.exe");
BufferedInputStream bufis=new BufferedInputStream(fis);
FileOutputStream fos=new FileOutputStream("c:\\222.exe");
BufferedOutputStream bufos=new BufferedOutputStream(fos);
int ch=0;
while((ch=bufis.read())!=-1)
{
bufos.write(ch);
}
bufis.close();
bufos.close();
五、文件管理File文件对象
1、文件属性
文件分隔符:为了统一操作系统的路径【Linux为/,windeow为\\】而产生的方法
File file=new File("f:" File.separator "aaa" File.separator "a.txt");
System.out.println("f:" File.separator "aaa" File.separator "a.txt");
File file=new File("f:" File.separator "aaa" File.separator "a.txt");
String name=file.getName();
String path=file.getAbsolutePath();
long time=file.lastModified();
Date date=new Date(time);
DateFormat dateFormat=DateFormat.getDateTimeInstance(DateFormat.LONG DateFormat.LONG);
String str_time=dateFormat.format(date);
System.out.println(str_time);
File f1 = new File("d:\\test");
File f3 = new File("e:\\file.txt");
File f4 = new File("d:\\" "1.txt");
//判断文件是否存在
System.out.println(f4.exists());
//获得文件的绝对路径
System.out.println(f3.getAbsolutePath());
//获得文件名
System.out.println(f3.getName());
//获得父路径
System.out.println(f3.getParent());
//判断是否是目录
System.out.println(f1.isDirectory());
//判断是否是文件
System.out.println(f3.isFile());
//获得文件长度
System.out.println(f3.length());
2、文件的应用
【1】创建文件夹
File myFolderPath = new File("aaa");
if (!myFolderPath.exists())
{
myFolderPath.mkdir();
}
【2】创建文件
//创建文件
File f = new File("e:\\file.txt");
try{
boolean b = f.createNewFile();
}catch(Exception e){
e.printStackTrace();
}
【3】获得当前文件夹下所有文件和文件夹名称
//获得当前文件夹下所有文件和文件夹名称
File f1 = new File("f:\\aaa");
String[] s = f1.list();
for(int i = 0;i < s.length;i ){
System.out.println(s[i]);
}
【4】获得文件对象
File f1 = new File("f:\\aaa");
File[] f5 = f1.listFiles();
for(int i = 0;i < f5.length;i ){
System.out.println(f5[i]);
}
【5】创建文件夹
//创建文件夹
File f6 = new File("e:\\test\\abc");
boolean b1 = f6.mkdir();
System.out.println(b1);
b1 = f6.mkdirs();
System.out.println(b1);
【6】打印某路径下所有的文件和文件夹
public class Test
{
public static void main(String[] args)
{
//创建文件夹
File f = new File("f:\\aaa");
printAllFile(f);
}
public static void printAllFile(File f)
{
//打印当前文件名
System.out.println(f.getName());
//是否是文件夹
if(f.isDirectory())
{
//获得该文件夹下所有子文件和子文件夹
File[] f1 = f.listFiles();
//循环处理每个对象
int len = f1.length;
for(int i = 0;i < len;i )
{
//递归调用,处理每个文件对象
printAllFile(f1[i]);
}
}
}
}
【7】删除对象f下的所有文件和文件夹
public class Test {
public static void main(String[] args)
{
File f1 = new File("e:\\test");
deleteAll(f1);
}
public static void deleteAll(File f)
{
if(f.isFile())
{
f.delete();
}
else
{
File f1[] = f.listFiles();//获得当前文件夹下的所有子文件和子文件夹
int len = f1.length;//循环处理每个对象
for(int i = 0;i < len;i )
{
deleteAll(f1[i]); //递归调用,处理每个文件对象
}
f.delete();//删除当前文件夹
}
}
}
六、转换流
InputStreamReader是字节流转换为字符流的桥梁
(1)例如,从键盘输入小写,输出为大写,输入"e"退出
//1、操作输入流
InputStream in=System.in;
//2、字节流转换为字符流的桥梁
InputStreamReader irs=new InputStreamReader(in);
//3、操作字符流
BufferedReader bufr=new BufferedReader(irs);
String line="";
while((line=bufr.readLine())!=null)
{
if("e".equals(line))
{
break;
}
System.out.println(line.toUpperCase());
}
(2)使用输出流实现上述例子
//1、操作输入流
InputStream in=System.in;
//2、字节流转换为字符流的桥梁
InputStreamReader irs=new InputStreamReader(in);
//3、操作字符流
BufferedReader bufr=new BufferedReader(irs);
//4、输出流
OutputStream out=System.out;
OutputStreamWriter osw=new OutputStreamWriter(out);
BufferedWriter bufw=new BufferedWriter(osw);
String line="";
while((line=bufr.readLine())!=null)
{
if("e".equals(line))
{
break;
}
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
(3)将从键盘录入的数据写入到文件中
//1、操作输入流
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
//2、输出流
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt")));
String line="";
while((line=bufr.readLine())!=null)
{
if("e".equals(line))
{
break;
}
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
(4)将文本文件内容显示在控制台
//1、操作输入流
BufferedReader bufr=new BufferedReader(new InputStreamReader(new FileInputStream("a.txt")));
//2、输出流
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
String line="";
while((line=bufr.readLine())!=null)
{
if("e".equals(line))
{
break;
}
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
(5)将文件的内容复制到另一个文件
//1、操作输入流
BufferedReader bufr=new BufferedReader(new InputStreamReader(new FileInputStream("a.txt")));
//2、输出流
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("b.txt")));
String line="";
while((line=bufr.readLine())!=null)
{
if("e".equals(line))
{
break;
}
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
Java的IO流(二)
(一)Properties集合
1、集合特点
该集合通常用于操作带键值对的配置文件
【1】集合中的key和value都是String类型
【2】集合的数据可以写入流中,也可以从流中获取
2、Properties的应用
(1)例如,下面程序是演示如何存入和读取数据
Properties properties = new Properties();
properties.setProperty("s001" "zhangsan");
properties.setProperty("s002" "lisi");
properties.setProperty("s003" "wangwu");
properties.setProperty("s004" "zhaoliu");
properties.setProperty("s005" "sunqi");
Set<String> stringPropertyNames = properties.stringPropertyNames();
for(String name:stringPropertyNames)
{
String value=properties.getProperty(name);
System.out.println(name "=====" value);
}
(2)集合关联流
Properties properties = new Properties();
properties.setProperty("s001" "zhangsan");
properties.setProperty("s002" "lisi");
properties.setProperty("s003" "wangwu");
properties.setProperty("s004" "zhaoliu");
properties.setProperty("s005" "sunqi");
FileOutputStream fileOutputStream = new FileOutputStream("test.txt");
properties.store(fileOutputStream “this is test”);
fileOutputStream.close();
(3)修改集合信息
//1、读取这个文件
File file=new File("test.txt");
if(!file.exists()){
file.createNewFile();
}
FileReader fileReader = new FileReader("test.txt");
//2、创建Properties对象
Properties properties = new Properties();
//3、将流信息加载到集合中
properties.load(fileReader);
//4、修改集合信息
properties.setProperty("11111" "qqqq");
//5、将集合信息保存
FileWriter fileWriter = new FileWriter(file);
properties.store(fileWriter "aaaaa");
fileReader.close();
fileWriter.close();
(二)打印流
(1)、为什么要用打印流
打印流能方便的打印各种数据值的表现形式,并且不会抛IO异常
(2)、打印流的使用
PrintStream
PrintStream提供了一系列的print()和println(),可以实现将基本数据类型格式化成字符串输出。对象类型将先调用toString(),然后输出该方法返回的字符串
System.out就是PrintStream的一个实例,代表显示器
System.err 也是PrintStream的一个实例,代表显示器
PrintStream的输出功能非常强大,通常需要输出文本内容,都可以将输出流包装成PrintStream后进行输出
PrintStream的方法都不抛出IOException
PrintWriter
PrintStream的对应字符流,功能相同,方法对应
PrintWriter的方法也不抛出IOException
复制文件时可以使用PrintWriter代替BufferedWriter完成将更简单
1、字节流PrintStream
write(int b)方法:将指定的字节写入,写入协议规定,向输出流写一个字节,要写入的字节是参数b的8个低位,b的24个高位将被忽略,例如:97如果按照32机型来算,其二进制的体现形式为
00000000 00000000 00000000 01100001
PrintStream out=new PrintStream("test.txt");
out.write(97);
out.close();
由于97处于低8位,运行结果没有问题
但是,数据格式如果是下列结果:
00000000 00000000 00001110 01100001
其十进制数位3681
PrintStream out=new PrintStream("test.txt");
out.write(3681);
out.close();
由于3681中的01100001处于低8位,按照协议运行结果输出低8位01100001为97 高位将被忽略
2、字符流PrintWriter
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
PrintWriter out=new PrintWriter(System.out);
//PrintWriter out=new PrintWriter(new FileWriter(“out.txt”));
String line=null;
while((line=bufr.readLine())!=null){
if(“ok”.equals(line)){//如果按下ok退出程序
break;
}
out.print(line);
}
out.close();
bufr.close();
}
(三)序列流
1、SequenceInputStream序列流的作用
SequenceInputStream表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件的末尾,接着从第二个输入流读取,以此类推,直到到达包含的最后一个输入流的文件末尾为止
例如:
Vector vector = new Vector();
vector.add(new FileInputStream("a.txt"));
vector.add(new FileInputStream("b.txt"));
vector.add(new FileInputStream("c.txt"));
Enumeration<FileInputStream> en=vector.elements();
SequenceInputStream sis=new SequenceInputStream(en);
FileOutputStream fos=new FileOutputStream("d.txt");
byte[] buf=new byte[1024];
int len=0;
while((len=sis.read(buf))!=-1){
fos.write(buf 0 len);
}
fos.close();
sis.close();
2、文件切割
//用读取流关联源文件
FileInputStream fis=new FileInputStream(new File());
//定义一个缓冲区
byte[] buf=new byte[1024*1024];
//创建目的
FileOutputStream fos=null;
File dir=new File("c:\\partfiles");
if(!dir.exists()){
dir.mkdirs();
}
int len=0;
int count=0;
while((len=fis.read(buf))=-1){
fos=new FileOutputStream(new File(dir (count ) ".part"));
fos.write(buf 0 len);
}
3、文件的合并
ArrayList<FileInputStream> list=new ArrayList<FileInputStream>();
for(int x=1;x<=3;x )
{
list.add(new FileInputStream(new File(dir x ".part")));
}
Enumeration<FileInputStream> en=Collections.enumeration(list);
SequenceInputStream sis=new SequenceInputStream(en);
File dir=new File("c:\\partfiles");
FileOutputStream fos=new FileOutputStream(new File(dir ".bmp"));
byte[] buf=new byte[024];
int len=0;
while((len=sis.read(buf))=-1)
{
fos.write(buf 0 len);
}
fos.close();
sis.close();
文件切割和合并的专业做法:切割文件时候,必须记录切割文件的名称,以及切割出文件锁片的个数,以方便于合并
(四)对象流
1、对象流的概念:
(1)、对象序列化 (Serialization)
将Java对象转换成字节序列(IO字节流)
(2)、对象反序列化 (DeSerialization)
从字节序列中恢复Java对象
2、为什么序列化
序列化以后的对象可以保存到磁盘上,也可以在网络上传输,使得不同的计算机可以共享对象.(序列化的字节序列是平台无关的)
3、对象序列化的条件
只有实现了Serializable接口的类的对象才可以被序列化。Serializable接口中没有任何的方法,实现该接口的类不需要实现额外的方法
如果对象的属性是对象,属性对应类也必须实现Serializable接口
ObjectOutputStream 和 ObjectInputStream 分别与 FileOutputStream 和 FileInputStream 一起使用时,可以为应用程序提供对对象图形的持久存储。ObjectInputStream 用于恢复那些以前序列化的对象。其他用途包括使用套接字流在主机之间传递对象,或者用于编组和解组远程通信系统中的实参和形参
【1】对象序列化的例子
public class Test {
public static void writeObj() throws Exception{
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("e:\\aaa.txt"));
//对象被序列化,被序列化的对象必须实现Serializable接口
oos.writeObject(new Person("zhangsan" 21));
oos.close();
}
public static void main(String[] args) throws Exception {
Test.writeObj();
}
}
class Person implements Serializable{
private String name;
public Person(String name int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private int age;
}
【2】对象反序列化的例子
public class Test {
public static void writeObj() throws Exception{
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("e:\\aaa.txt"));
//对象被序列化,被序列化的对象必须实现Serializable接口
oos.writeObject(new Person("zhangsan" 21));
oos.close();
}
public static void readObj() throws Exception{
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("e:\\aaa.txt"));
Person p=(Person)ois.readObject();
System.out.println(p.getName() "=====" p.getAge());
ois.close();
}
public static void main(String[] args) throws Exception {
Test.readObj();
}
}
注意:
(1)序列化只能保存对象的非静态成员变量;不能保存任何成员方法和静态的成员变量;不保存transient成员变量;如果一个对象的成员变量是一个对象,这个对象的成员变量也会保存;串行化保存的只是变量的值,对于变量的任何修饰符,都不能保存。使用对象流把一个对象写到文件时不仅保证该对象是序列化的,而且该对象的成员对象也必须是可序列化的
(2)如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化
(3)同一个对象多次序列化的处理
3.1所有保存到磁盘中的对象都有一个序列化编号
3.2序列化一个对象中,首先检查该对象是否已经序列化过,如果没有,进行序列化;
如果已经序列化,将不再重新序列化,而是输出编号即可
3.3如果不希望某些属性(敏感)序列化,或不希望出现递归序列,为属性添加transient关键字(完成排除在序列化之外)自定义序列化(不仅可以决定哪些属性不参与序列化,还可以定义属性具体如何序列化)
3.4序列化版本不兼容,修改了实例属性后 会影响版本号,从而导致反序列化不成功
解决方案:为Java对象指定序列化版本号serialVersionUID
(五)Java的其它IO流简介
1、DataInputStream和DataOutputStream
DataInputStream和DataOutputStream提供了可以存取所有Java基础类型数据(如:int,double 等)和String的方法。它是一个处理流,只针对字节流,二进制文件
2、字节/字符数组/字符串流
(1)字节流:ByteArrayInutStream和ByteArrayOutputStream
数据源或目的地为:字节数组。只有字节流,没有字符流
(2)字符数组:CharArrayReader和CharArrayWriter
数据源或目的地为:字符数组。只有字符流,没有字节流
(3)字符串流:StringReader和StringWriter
数据源或目的地为:字符串。只有字符流,没有字节流
《大数据和人工智能交流》的宗旨
1、将大数据和人工智能的专业数学:概率数理统计、线性代数、决策论、优化论、博弈论等数学模型变得通俗易懂。
2、将大数据和人工智能的专业涉及到的数据结构和算法:分类、聚类 、回归算法、概率等算法变得通俗易懂。
3、最新的高科技动态:数据采集方面的智能传感器技术;医疗大数据智能决策分析;物联网智慧城市等等。
根据初学者需要会有C语言、Java语言、Python语言、Scala函数式等目前主流计算机语言。
根据读者的需要有和人工智能相关的计算机科学与技术、电子技术、芯片技术等基础学科通俗易懂的文章。