Hadoop案例(一)之日志清洗
日志清洗案例
一. 简单解析版
1)需求
去除日志中字段长度小于等于11的日志。
2)输入数据
194.237.142.21 - - [/Sep/::: +] "GET /wp-content/uploads/2013/07/rstudio-git3.png HTTP/1.1" "-" "Mozilla/4.0 (compatible;)"
183.49.46.228 - - [/Sep/::: +] "-" "-" "-"
163.177.71.12 - - [/Sep/::: +] "HEAD / HTTP/1.1" "-" "DNSPod-Monitor/1.0"
163.177.71.12 - - [/Sep/::: +] "HEAD / HTTP/1.1" "-" "DNSPod-Monitor/1.0"
101.226.68.137 - - [/Sep/::: +] "HEAD / HTTP/1.1" "-" "DNSPod-Monitor/1.0"
101.226.68.137 - - [/Sep/::: +] "HEAD / HTTP/1.1" "-" "DNSPod-Monitor/1.0"
60.208.6.156 - - [/Sep/::: +] "GET /wp-content/uploads/2013/07/rcassandra.png HTTP/1.0" "http://cos.name/category/software/packages/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36"
222.68.172.190 - - [/Sep/::: +] "GET /images/my.jpg HTTP/1.1" "http://www.angularjs.cn/A00n" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36"
222.68.172.190 - - [/Sep/::: +] "-" "-" "-"
183.195.232.138 - - [/Sep/::: +] "HEAD / HTTP/1.1" "-" "DNSPod-Monitor/1.0"
183.195.232.138 - - [/Sep/::: +] "HEAD / HTTP/1.1" "-" "DNSPod-Monitor/1.0"
66.249.66.84 - - [/Sep/::: +] "GET /page/6/ HTTP/1.1" "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
221.130.41.168 - - [/Sep/::: +] "GET /feed/ HTTP/1.1" "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36"
157.55.35.40 - - [/Sep/::: +] "GET /robots.txt HTTP/1.1" "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
50.116.27.194 - - [/Sep/::: +] "POST /wp-cron.php?doing_wp_cron=1379487095.2510800361633300781250 HTTP/1.0" "-" "WordPress/3.6; http://blog.fens.me"
58.215.204.118 - - [/Sep/::: +] "GET /nodejs-socketio-chat/ HTTP/1.1" "http://www.google.com/url?sa=t&rct=j&q=nodejs%20%E5%BC%82%E6%AD%A5%E5%B9%BF%E6%92%AD&source=web&cd=1&cad=rja&ved=0CCgQFjAA&url=%68%74%74%70%3a%2f%2f%62%6c%6f%67%2e%66%65%6e%73%2e%6d%65%2f%6e%6f%64%65%6a%73%2d%73%6f%63%6b%65%74%69%6f%2d%63%68%61%74%2f&ei=rko5UrylAefOiAe7_IGQBw&usg=AFQjCNG6YWoZsJ_bSj8kTnMHcH51hYQkAA&bvm=bv.52288139,d.aGc" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
58.215.204.118 - - [/Sep/::: +] "GET /wp-includes/js/jquery/jquery-migrate.min.js?ver=1.2.1 HTTP/1.1" "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
58.215.204.118 - - [/Sep/::: +] "GET /wp-includes/js/jquery/jquery.js?ver=1.10.2 HTTP/1.1" "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
58.215.204.118 - - [/Sep/::: +] "GET /wp-includes/js/comment-reply.min.js?ver=3.6 HTTP/1.1" "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
58.215.204.118 - - [/Sep/::: +] "GET /wp-content/uploads/2013/08/chat.png HTTP/1.1" "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
58.215.204.118 - - [/Sep/::: +] "GET /wp-content/uploads/2013/08/chat2.png HTTP/1.1" "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
58.215.204.118 - - [/Sep/::: +] "GET /wp-content/uploads/2013/08/socketio.png HTTP/1.1" "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
58.248.178.212 - - [/Sep/::: +] "GET /nodejs-grunt-intro/ HTTP/1.1" "http://blog.fens.me/series-nodejs/" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; MDDR; InfoPath.2; .NET4.0C)"
58.248.178.212 - - [/Sep/::: +] "GET /wp-includes/js/jquery/jquery-migrate.min.js?ver=1.2.1 HTTP/1.1" "http://blog.fens.me/nodejs-grunt-intro/" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; MDDR; InfoPath.2; .NET4.0C)"
3)实现代码
(1)编写LogMapper
package com.xyg.mapreduce.weblog;
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper; public class LogMapper extends Mapper<LongWritable, Text, Text, NullWritable>{ Text k = new Text(); @Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { // 1 获取1行数据
String line = value.toString();
// 2 解析日志
boolean result = parseLog(line,context);
// 3 日志不合法退出
if (!result) {
return;
}
// 4 设置key
k.set(line);
// 5 写出数据
context.write(k, NullWritable.get());
}
// 2 解析日志
private boolean parseLog(String line, Context context) {
// 1 截取
String[] fields = line.split(" "); // 2 日志长度大于11的为合法
if (fields.length > ) {
// 系统计数器
context.getCounter("map", "true").increment();
return true;
}else {
context.getCounter("map", "false").increment();
return false;
}
}
}
(2)编写LogDriver
package com.xyg.mapreduce.weblog; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class LogDriver { public static void main(String[] args) throws Exception {
args = new String[] { "e:/inputlog", "e:/output1" };
// 1 获取job信息
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
// 2 加载jar包
job.setJarByClass(LogDriver.class);
// 3 关联map
job.setMapperClass(LogMapper.class);
// 4 设置最终输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(NullWritable.class);
// 5 设置输入和输出路径
FileInputFormat.setInputPaths(job, new Path(args[]));
FileOutputFormat.setOutputPath(job, new Path(args[]));
// 6 提交
job.waitForCompletion(true);
}
}
二. 复杂解析版
1)需求
对web访问日志中的各字段识别切分
去除日志中不合法的记录
根据统计需求,生成各类访问请求过滤数据
2)输入数据
194.237.142.21 - - [/Sep/::: +] "GET /wp-content/uploads/2013/07/rstudio-git3.png HTTP/1.1" "-" "Mozilla/4.0 (compatible;)"
183.49.46.228 - - [/Sep/::: +] "-" "-" "-"
163.177.71.12 - - [/Sep/::: +] "HEAD / HTTP/1.1" "-" "DNSPod-Monitor/1.0"
163.177.71.12 - - [/Sep/::: +] "HEAD / HTTP/1.1" "-" "DNSPod-Monitor/1.0"
101.226.68.137 - - [/Sep/::: +] "HEAD / HTTP/1.1" "-" "DNSPod-Monitor/1.0"
101.226.68.137 - - [/Sep/::: +] "HEAD / HTTP/1.1" "-" "DNSPod-Monitor/1.0"
60.208.6.156 - - [/Sep/::: +] "GET /wp-content/uploads/2013/07/rcassandra.png HTTP/1.0" "http://cos.name/category/software/packages/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36"
222.68.172.190 - - [/Sep/::: +] "GET /images/my.jpg HTTP/1.1" "http://www.angularjs.cn/A00n" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36"
222.68.172.190 - - [/Sep/::: +] "-" "-" "-"
183.195.232.138 - - [/Sep/::: +] "HEAD / HTTP/1.1" "-" "DNSPod-Monitor/1.0"
183.195.232.138 - - [/Sep/::: +] "HEAD / HTTP/1.1" "-" "DNSPod-Monitor/1.0"
66.249.66.84 - - [/Sep/::: +] "GET /page/6/ HTTP/1.1" "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
221.130.41.168 - - [/Sep/::: +] "GET /feed/ HTTP/1.1" "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36"
157.55.35.40 - - [/Sep/::: +] "GET /robots.txt HTTP/1.1" "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
50.116.27.194 - - [/Sep/::: +] "POST /wp-cron.php?doing_wp_cron=1379487095.2510800361633300781250 HTTP/1.0" "-" "WordPress/3.6; http://blog.fens.me"
58.215.204.118 - - [/Sep/::: +] "GET /nodejs-socketio-chat/ HTTP/1.1" "http://www.google.com/url?sa=t&rct=j&q=nodejs%20%E5%BC%82%E6%AD%A5%E5%B9%BF%E6%92%AD&source=web&cd=1&cad=rja&ved=0CCgQFjAA&url=%68%74%74%70%3a%2f%2f%62%6c%6f%67%2e%66%65%6e%73%2e%6d%65%2f%6e%6f%64%65%6a%73%2d%73%6f%63%6b%65%74%69%6f%2d%63%68%61%74%2f&ei=rko5UrylAefOiAe7_IGQBw&usg=AFQjCNG6YWoZsJ_bSj8kTnMHcH51hYQkAA&bvm=bv.52288139,d.aGc" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
58.215.204.118 - - [/Sep/::: +] "GET /wp-includes/js/jquery/jquery-migrate.min.js?ver=1.2.1 HTTP/1.1" "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
58.215.204.118 - - [/Sep/::: +] "GET /wp-includes/js/jquery/jquery.js?ver=1.10.2 HTTP/1.1" "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
58.215.204.118 - - [/Sep/::: +] "GET /wp-includes/js/comment-reply.min.js?ver=3.6 HTTP/1.1" "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
58.215.204.118 - - [/Sep/::: +] "GET /wp-content/uploads/2013/08/chat.png HTTP/1.1" "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
58.215.204.118 - - [/Sep/::: +] "GET /wp-content/uploads/2013/08/chat2.png HTTP/1.1" "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
58.215.204.118 - - [/Sep/::: +] "GET /wp-content/uploads/2013/08/socketio.png HTTP/1.1" "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
58.248.178.212 - - [/Sep/::: +] "GET /nodejs-grunt-intro/ HTTP/1.1" "http://blog.fens.me/series-nodejs/" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; MDDR; InfoPath.2; .NET4.0C)"
58.248.178.212 - - [/Sep/::: +] "GET /wp-includes/js/jquery/jquery-migrate.min.js?ver=1.2.1 HTTP/1.1" "http://blog.fens.me/nodejs-grunt-intro/" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; MDDR; InfoPath.2; .NET4.0C)"
3)实现代码
(1)定义一个bean,用来记录日志数据中的各数据字段
package com.xyg.mapreduce.log;
public class LogBean {
private String remote_addr;// 记录客户端的ip地址
private String remote_user;// 记录客户端用户名称,忽略属性"-"
private String time_local;// 记录访问时间与时区
private String request;// 记录请求的url与http协议
private String status;// 记录请求状态;成功是200
private String body_bytes_sent;// 记录发送给客户端文件主体内容大小
private String http_referer;// 用来记录从那个页面链接访问过来的
private String http_user_agent;// 记录客户浏览器的相关信息
private boolean valid = true;// 判断数据是否合法
public String getRemote_addr() {
return remote_addr;
}
public void setRemote_addr(String remote_addr) {
this.remote_addr = remote_addr;
}
public String getRemote_user() {
return remote_user;
}
public void setRemote_user(String remote_user) {
this.remote_user = remote_user;
}
public String getTime_local() {
return time_local;
}
public void setTime_local(String time_local) {
this.time_local = time_local;
}
public String getRequest() {
return request;
}
public void setRequest(String request) {
this.request = request;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getBody_bytes_sent() {
return body_bytes_sent;
}
public void setBody_bytes_sent(String body_bytes_sent) {
this.body_bytes_sent = body_bytes_sent;
}
public String getHttp_referer() {
return http_referer;
}
public void setHttp_referer(String http_referer) {
this.http_referer = http_referer;
}
public String getHttp_user_agent() {
return http_user_agent;
}
public void setHttp_user_agent(String http_user_agent) {
this.http_user_agent = http_user_agent;
}
public boolean isValid() {
return valid;
}
public void setValid(boolean valid) {
this.valid = valid;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(this.valid);
sb.append("\001").append(this.remote_addr);
sb.append("\001").append(this.remote_user);
sb.append("\001").append(this.time_local);
sb.append("\001").append(this.request);
sb.append("\001").append(this.status);
sb.append("\001").append(this.body_bytes_sent);
sb.append("\001").append(this.http_referer);
sb.append("\001").append(this.http_user_agent);
return sb.toString();
}
}
(2)编写LogMapper程序
package com.xyg.mapreduce.log;
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper; public class LogMapper extends Mapper<LongWritable, Text, Text, NullWritable>{
Text k = new Text(); @Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
// 1 获取1行
String line = value.toString();
// 2 解析日志是否合法
LogBean bean = pressLog(line);
if (!bean.isValid()) {
return;
}
k.set(bean.toString());
// 3 输出
context.write(k, NullWritable.get());
} // 解析日志
private LogBean pressLog(String line) {
LogBean logBean = new LogBean();
// 1 截取
String[] fields = line.split(" ");
if (fields.length > ) {
// 2封装数据
logBean.setRemote_addr(fields[]);
logBean.setRemote_user(fields[]);
logBean.setTime_local(fields[].substring());
logBean.setRequest(fields[]);
logBean.setStatus(fields[]);
logBean.setBody_bytes_sent(fields[]);
logBean.setHttp_referer(fields[]); if (fields.length > ) {
logBean.setHttp_user_agent(fields[] + " "+ fields[]);
}else {
logBean.setHttp_user_agent(fields[]);
}
// 大于400,HTTP错误
if (Integer.parseInt(logBean.getStatus()) >= ) {
logBean.setValid(false);
}
}else {
logBean.setValid(false);
}
return logBean;
}
}
(3)编写LogDriver程序
package com.xyg.mapreduce.log;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class LogDriver {
public static void main(String[] args) throws Exception {
// 1 获取job信息
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
// 2 加载jar包
job.setJarByClass(LogDriver.class);
// 3 关联map
job.setMapperClass(LogMapper.class);
// 4 设置最终输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(NullWritable.class);
// 5 设置输入和输出路径
FileInputFormat.setInputPaths(job, new Path(args[]));
FileOutputFormat.setOutputPath(job, new Path(args[]));
// 6 提交
job.waitForCompletion(true);
}
}
Hadoop案例(一)之日志清洗的更多相关文章
- discuz论坛apache日志hadoop大数据分析项目:清洗数据核心功能解说及代码实现
discuz论坛apache日志hadoop大数据分析项目:清洗数据核心功能解说及代码实现http://www.aboutyun.com/thread-8637-1-1.html(出处: about云 ...
- 用 shell 脚本做日志清洗
问题的提出 公司有一个用户行为分析系统,可以记录用户在使用公司产品过程中的一系列操作轨迹,便于分析产品使用情况以便优化产品 UI 界面布局.这套系统有点类似于 Google Analyse(GA),所 ...
- Hadoop案例(五)过滤日志及自定义日志输出路径(自定义OutputFormat)
过滤日志及自定义日志输出路径(自定义OutputFormat) 1.需求分析 过滤输入的log日志中是否包含xyg (1)包含xyg的网站输出到e:/xyg.log (2)不包含xyg的网站输出到e: ...
- Hive学习之四 《Hive分区表场景案例应用案例,企业日志加载》 详解
文件的加载,只需要三步就够了,废话不多说,来直接的吧. 一.建表 话不多说,直接开始. 建表,对于日志文件来说,最后有分区,在此案例中,对年月日和小时进行了分区. 建表tracktest_log,分隔 ...
- Hadoop学习之Hadoop案例分析
一.日志数据分析1.背景1.1 ***论坛日志,数据分为两部分组成,原来是一个大文件,是56GB:以后每天生成一个文件,大约是150-200MB之间: 每行记录有5部分组成:1.访问ip:2.访问时间 ...
- Hadoop案例(十)WordCount
WordCount案例 需求1:统计一堆文件中单词出现的个数(WordCount案例) 0)需求:在一堆给定的文本文件中统计输出每一个单词出现的总次数 1)数据准备:Hello.txt hello w ...
- 二、基于hadoop的nginx访问日志分析---计算日pv
代码: # pv_day.py#!/usr/bin/env python # coding=utf-8 from mrjob.job import MRJob from nginx_accesslog ...
- 一、基于hadoop的nginx访问日志分析---解析日志篇
前一阵子,搭建了ELK日志分析平台,用着挺爽的,再也不用给开发拉各种日志,节省了很多时间. 这篇博文是介绍用python代码实现日志分析的,用MRJob实现hadoop上的mapreduce,可以直接 ...
- Hadoop:实战Web日志分析
示例场景 日志说明 有两台Web服务器,日志文件存放在/usr/local/nginx/logs/目录,日志默认为nginx定义格式.如: 123.13.17.13 - - [25/Aug/2016: ...
随机推荐
- 最近遇到的DISCUZ一些问题解决方法
“抱歉,您的请求来路不正确或表单验证串不符,无法提交” 打开“source\class\helper\helper_form.php”, 然后把“$_GET[‘formhash’] == formha ...
- 基于OpenResty和Node.js的微服务架构实践
什么是微服务? 传统的单体服务架构是单独服务包,共享代码与数据,开发成本较高,可维护性.伸缩性较差,技术转型.跨语言配合相对困难.而微服务架构强调一个服务负责一项业务,服务可以单独部署,独立进行技术选 ...
- ZABBIX 3.0 配置监控MYSQL性能【OK】
Zabbix3.0自带了MySQL插件来监控mysql数据库的模板,只需要配置好agent客户端,然后在web端给主机增加模板就行了. 参考:http://www.cnblogs.com/keving ...
- 查看git拉取地址
在项目地址下面输入:git remote -v 即可查看到地址啦.
- 「Python」pandas入门教程
pandas适合于许多不同类型的数据,包括: 具有异构类型列的表格数据,例如SQL表格或Excel数据 有序和无序(不一定是固定频率)时间序列数据. 具有行列标签的任意矩阵数据(均匀类型或不同类型) ...
- Codeforces 148 D Bag of mice
D. Bag of mice http://codeforces.com/problemset/problem/148/D time limit per test 2 seconds memory l ...
- HDU6130 签到题 打表
LINK 题意:给出一个描述自身的数列,求出第n项 思路:看了很久题目才看懂..每个值其实是描述一个分组中的个数,把两个数列对照一下就可以了,那么一个指针扫,同时向尾部加数,构造个数组就行了.其实很水 ...
- 每个Web开发者都需要具备的9个软技能
对于一份工作,你可能专注于修炼自己的内功,会在不自觉中忽视软技能.硬技能决定你是否能得到工作,而软技能能够表明你是否适合这份工作和适应工作环境等.所有的公司都有属于自己的文化,并努力将这些文化传承下去 ...
- 2、java语言基础
1.关键字 被Java语言赋予特定含义的单词被称为关键字关键字都是小写的在Java开发工具中,针对关键字有特殊颜色的标记 2.标识符 Java标识符命名规则 ·标识符是由,数字,字母,下划线和美元符号 ...
- python作业类Fabric主机管理程序开发(第九周)
作业需求: 1. 运行程序列出主机组或者主机列表 2. 选择指定主机或主机组 3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载) 4. 充分使用多线程或多进程 5. 不同主机的用户名密码 ...