094实战 关于js SDK的程序,java SDK的程序
一:JS SDK
1.修改配置workspace
2.导入
3.Demo.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>测试页面1</title>
<!-- 第一种集成方式 -->
<script type="text/javascript" src="./js/analytics.js"></script>
</head>
<body>
测试页面1<br/>
跳转到:
<a href="demo.html">demo</a>
<a href="demo2.html">demo2</a>
<a href="demo3.html">demo3</a>
<a href="demo4.html">demo4</a>
</body>
</html>
4.效果
5.产生新的日志
tail -f access.log
二:重点
1.关于js的产生
参考程序analytics.js的JS SDK
(function() {
var CookieUtil = {
// get the cookie of the key is name
get : function(name) {
var cookieName = encodeURIComponent(name) + "=", cookieStart = document.cookie
.indexOf(cookieName), cookieValue = null;
if (cookieStart > -1) {
var cookieEnd = document.cookie.indexOf(";", cookieStart);
if (cookieEnd == -1) {
cookieEnd = document.cookie.length;
}
cookieValue = decodeURIComponent(document.cookie.substring(
cookieStart + cookieName.length, cookieEnd));
}
return cookieValue;
},
// set the name/value pair to browser cookie
set : function(name, value, expires, path, domain, secure) {
var cookieText = encodeURIComponent(name) + "="
+ encodeURIComponent(value); if (expires) {
// set the expires time
var expiresTime = new Date();
expiresTime.setTime(expires);
cookieText += ";expires=" + expiresTime.toGMTString();
} if (path) {
cookieText += ";path=" + path;
} if (domain) {
cookieText += ";domain=" + domain;
} if (secure) {
cookieText += ";secure";
} document.cookie = cookieText;
},
setExt : function(name, value) {
this.set(name, value, new Date().getTime() + 315360000000, "/");
}
}; // 主体,其实就是tracker js
var tracker = {
// config
clientConfig : {
// TODO 这里的url需要传入具体的地址
serverUrl : "http://linux-hadoop3.ibeifeng.com/BEIfeng.gif",
sessionTimeout : 360, // 360s -> 6min 指定会话的过期时间,指的是操作停留最多的时间
maxWaitTime : 3600, // 3600s -> 60min -> 1h 指定的是单页面的最多停留时间,当前这个参数无效
ver : "1"
}, cookieExpiresTime : 315360000000, // cookie过期时间,10年 columns : {
// 发送到服务器的列名称
eventName : "en",
version : "ver",
platform : "pl",
sdk : "sdk",
uuid : "u_ud",
memberId : "u_mid",
sessionId : "u_sd",
clientTime : "c_time",
language : "l",
userAgent : "b_iev",
resolution : "b_rst",
currentUrl : "p_url",
referrerUrl : "p_ref",
title : "tt",
orderId : "oid",
orderName : "on",
currencyAmount : "cua",
currencyType : "cut",
paymentType : "pt",
category : "ca",
action : "ac",
kv : "kv_",
duration : "du"
}, keys : {
pageView : "e_pv",
chargeRequestEvent : "e_crt",
launch : "e_l",
eventDurationEvent : "e_e",
sid : "bftrack_sid",
uuid : "bftrack_uuid",
mid : "bftrack_mid",
preVisitTime : "bftrack_previsit", }, /**
* 获取会话id
*/
getSid : function() {
return CookieUtil.get(this.keys.sid);
}, /**
* 保存会话id到cookie
*/
setSid : function(sid) {
if (sid) {
CookieUtil.setExt(this.keys.sid, sid);
}
}, /**
* 获取uuid,从cookie中
*/
getUuid : function() {
return CookieUtil.get(this.keys.uuid);
}, /**
* 保存uuid到cookie
*/
setUuid : function(uuid) {
if (uuid) {
CookieUtil.setExt(this.keys.uuid, uuid);
}
}, /**
* 获取memberID
*/
getMemberId : function() {
return CookieUtil.get(this.keys.mid);
}, /**
* 设置mid
*/
setMemberId : function(mid) {
if (mid) {
CookieUtil.setExt(this.keys.mid, mid);
}
}, // 入口方法
startSession : function() {
// 加载js就触发的方法
if (this.getSid()) {
// 会话id存在,表示uuid也存在
if (this.isSessionTimeout()) {
// 会话过期,产生新的会话
this.createNewSession();
} else {
// 会话没有过期,更新最近访问时间
this.updatePreVisitTime(new Date().getTime());
}
} else {
// 会话id不存在,表示uuid也不存在
this.createNewSession();
}
this.onPageView();
}, onLaunch : function() {
// 触发launch事件
var launch = {};
launch[this.columns.eventName] = this.keys.launch; // 设置事件名称
this.setCommonColumns(launch); // 设置公用columns
this.sendDataToServer(this.parseParam(launch)); // 最终发送编码后的数据
}, onPageView : function() {
// 触发page view事件
if (this.preCallApi()) {
var time = new Date().getTime();
var pageviewEvent = {};
pageviewEvent[this.columns.eventName] = this.keys.pageView;
pageviewEvent[this.columns.currentUrl] = window.location.href; // 设置当前url
pageviewEvent[this.columns.referrerUrl] = document.referrer; // 设置前一个页面的url
pageviewEvent[this.columns.title] = document.title; // 设置title
this.setCommonColumns(pageviewEvent); // 设置公用columns
this.sendDataToServer(this.parseParam(pageviewEvent)); // 最终发送编码后的数据
this.updatePreVisitTime(time); // 更新最近访问时间
}
}, onChargeRequest : function(orderId, name, currencyAmount, currencyType,
paymentType) {
// 触发订单产生事件
if (this.preCallApi()) {
if (!orderId || !currencyType || !paymentType) {
this.log("订单id、货币类型以及支付方式不能为空");
return;
} if (typeof (currencyAmount) == "number") {
// 金额必须是数字
var time = new Date().getTime();
var chargeRequestEvent = {};
chargeRequestEvent[this.columns.eventName] = this.keys.chargeRequestEvent;
chargeRequestEvent[this.columns.orderId] = orderId;
chargeRequestEvent[this.columns.orderName] = name;
chargeRequestEvent[this.columns.currencyAmount] = currencyAmount;
chargeRequestEvent[this.columns.currencyType] = currencyType;
chargeRequestEvent[this.columns.paymentType] = paymentType;
this.setCommonColumns(chargeRequestEvent); // 设置公用columns
this.sendDataToServer(this.parseParam(chargeRequestEvent)); // 最终发送编码后的数据ss
this.updatePreVisitTime(time);
} else {
this.log("订单金额必须是数字");
return;
}
}
}, onEventDuration : function(category, action, map, duration) {
// 触发event事件
if (this.preCallApi()) {
if (category && action) {
var time = new Date().getTime();
var event = {};
event[this.columns.eventName] = this.keys.eventDurationEvent;
event[this.columns.category] = category;
event[this.columns.action] = action;
if (map) {
// map如果不为空,进行内容的添加
for ( var k in map) {
// 循环key
if (k && map[k]) {
// 当key和value不为空的时候,进行添加操作
event[this.columns.kv + k] = map[k]; // key添加前缀"kv_"
}
}
}
if (duration) {
event[this.columns.duration] = duration; // 当duration不为0的时候进行添加
}
this.setCommonColumns(event); // 设置公用columns
this.sendDataToServer(this.parseParam(event)); // 最终发送编码后的数据ss
this.updatePreVisitTime(time);
} else {
this.log("category和action不能为空");
}
}
}, /**
* 执行对外方法前必须执行的方法
*/
preCallApi : function() {
if (this.isSessionTimeout()) {
// 如果为true,表示需要新建
this.startSession();
} else {
this.updatePreVisitTime(new Date().getTime());
}
return true;
}, sendDataToServer : function(data) {
// 发送数据data到服务器,其中data是一个字符串
// TODO:发送以前发送失败的数据
var that = this;
var i2 = new Image(1, 1);
i2.onerror = function() {
// 这里可以进行重试操作
// 当请求失败的情况下,执行这块的代码,可以将数据保存到local stroage中,下次再重新发送数据
};
// 给定图片的请求url
i2.src = this.clientConfig.serverUrl + "?" + data;
}, /**
* 往data中添加发送到日志收集服务器的公用部分
*/
setCommonColumns : function(data) {
data[this.columns.version] = this.clientConfig.ver;
data[this.columns.platform] = "website";
data[this.columns.sdk] = "js";
data[this.columns.uuid] = this.getUuid(); // 设置用户id
data[this.columns.memberId] = this.getMemberId(); // 设置会员id
data[this.columns.sessionId] = this.getSid(); // 设置sid
data[this.columns.clientTime] = new Date().getTime(); // 设置客户端时间
data[this.columns.language] = window.navigator.language; // 设置浏览器语言
data[this.columns.userAgent] = window.navigator.userAgent; // 设置浏览器类型
data[this.columns.resolution] = screen.width + "*" + screen.height; // 设置浏览器分辨率
}, /**
* 创建新的会员,并判断是否是第一次访问页面,如果是,进行launch事件的发送。
*/
createNewSession : function() {
var time = new Date().getTime(); // 获取当前操作时间
// 1. 进行会话更新操作
var sid = this.generateId(); // 产生一个session id
this.setSid(sid);
this.updatePreVisitTime(time); // 更新最近访问时间
// 2. 进行uuid查看操作
if (!this.getUuid()) {
// uuid不存在,先创建uuid,然后保存到cookie,最后触发launch事件
var uuid = this.generateId(); // 产品uuid
this.setUuid(uuid);
this.onLaunch(); // 触发launch事件
}
}, /**
* 参数编码返回字符串
*/
parseParam : function(data) {
var params = "";
for ( var e in data) {
if (e && data[e]) {
// 对key和value进行编码操作
params += encodeURIComponent(e) + "="
+ encodeURIComponent(data[e]) + "&";
}
}
if (params) {
return params.substring(0, params.length - 1);
} else {
return params;
}
}, /**
* 产生uuid<br/>
* UUID的产生逻辑,可以参考Java中UUID的生产代码
*/
generateId : function() {
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
var tmpid = [];
var r;
tmpid[8] = tmpid[13] = tmpid[18] = tmpid[23] = '-';
tmpid[14] = '4'; for (i = 0; i < 36; i++) {
if (!tmpid[i]) {
r = 0 | Math.random() * 16;
tmpid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
}
}
return tmpid.join('');
}, /**
* 判断这个会话是否过期,查看当前时间和最近访问时间间隔时间是否小于this.clientConfig.sessionTimeout<br/>
* 如果是小于,返回false;否则返回true。
*/
isSessionTimeout : function() {
var time = new Date().getTime();
var preTime = CookieUtil.get(this.keys.preVisitTime);
if (preTime) {
// 最近访问时间存在,那么进行区间判断
return time - preTime > this.clientConfig.sessionTimeout * 1000;
}
return true;
}, /**
* 更新最近访问时间
*/
updatePreVisitTime : function(time) {
CookieUtil.setExt(this.keys.preVisitTime, time);
}, /**
* 打印日志
*/
log : function(msg) {
console.log(msg);
}, }; // 对外暴露的方法名称
window.__AE__ = {
startSession : function() {
tracker.startSession();
},
onPageView : function() {
tracker.onPageView();
},
onChargeRequest : function(orderId, name, currencyAmount, currencyType,
paymentType) {
tracker.onChargeRequest(orderId, name, currencyAmount,
currencyType, paymentType);
},
onEventDuration : function(category, action, map, duration) {
tracker.onEventDuration(category, action, map, duration);
},
setMemberId : function(mid) {
tracker.setMemberId(mid);
}
}; // 自动加载方法
var autoLoad = function() {
// 进行参数设置
var _aelog_ = _aelog_ || window._aelog_ || [];
var memberId = null;
for (i = 0; i < _aelog_.length; i++) {
_aelog_[i][0] === "memberId" && (memberId = _aelog_[i][1]);
}
// 根据是给定memberid,设置memberid的值
memberId && __AE__.setMemberId(memberId);
// 启动session
__AE__.startSession();
}; // 调用
autoLoad();
})();
2.同时在access.log收集日志
三:JAVA SDK
1.原理图
2.程序的重点
将日志数据发送到队列
取数据,将数据发送到nginx服务器
3.程序AnalyticsEngineSDK
package com.ibeifeng.sdk.java.logmake; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger; /**
* 分析引擎sdk java服务器端数据收集
*
* @author ibeifeng
* @version 1.0
*
*/
public class AnalyticsEngineSDK {
// 日志打印对象
private static final Logger log = Logger.getGlobal();
// 请求url的主体部分
public static final String accessUrl = "http://linux-hadoop3.ibeifeng.com/BEIfeng.gif";
private static final String platformName = "java_server";
private static final String sdkName = "jdk";
private static final String version = "1"; /**
* 触发订单支付成功事件,发送事件数据到服务器
*
* @param orderId
* 订单支付id
* @param memberId
* 订单支付会员id
* @return 如果发送数据成功(加入到发送队列中),那么返回true;否则返回false(参数异常&添加到发送队列失败).
*/
public static boolean onChargeSuccess(String orderId, String memberId) {
try {
if (isEmpty(orderId) || isEmpty(memberId)) {
// 订单id或者memberid为空
log.log(Level.WARNING, "订单id和会员id不能为空");
return false;
}
// 代码执行到这儿,表示订单id和会员id都不为空。
Map<String, String> data = new HashMap<String, String>();
data.put("u_mid", memberId);
data.put("oid", orderId);
data.put("c_time", String.valueOf(System.currentTimeMillis()));
data.put("ver", version);
data.put("en", "e_cs");
data.put("pl", platformName);
data.put("sdk", sdkName);
// 创建url
String url = buildUrl(data);
// 发送url&将url加入到队列
SendDataMonitor.addSendUrl(url);
return true;
} catch (Throwable e) {
log.log(Level.WARNING, "发送数据异常", e);
}
return false;
} /**
* 触发订单退款事件,发送退款数据到服务器
*
* @param orderId
* 退款订单id
* @param memberId
* 退款会员id
* @return 如果发送数据成功,返回true。否则返回false。
*/
public static boolean onChargeRefund(String orderId, String memberId) {
try {
if (isEmpty(orderId) || isEmpty(memberId)) {
// 订单id或者memberid为空
log.log(Level.WARNING, "订单id和会员id不能为空");
return false;
}
// 代码执行到这儿,表示订单id和会员id都不为空。
Map<String, String> data = new HashMap<String, String>();
data.put("u_mid", memberId);
data.put("oid", orderId);
data.put("c_time", String.valueOf(System.currentTimeMillis()));
data.put("ver", version);
data.put("en", "e_cr");
data.put("pl", platformName);
data.put("sdk", sdkName);
// 构建url
String url = buildUrl(data);
// 发送url&将url添加到队列中
SendDataMonitor.addSendUrl(url);
return true;
} catch (Throwable e) {
log.log(Level.WARNING, "发送数据异常", e);
}
return false;
} /**
* 根据传入的参数构建url
*
* @param data
* @return
* @throws UnsupportedEncodingException
*/
private static String buildUrl(Map<String, String> data) throws UnsupportedEncodingException {
StringBuilder sb = new StringBuilder();
sb.append(accessUrl).append("?");
for (Map.Entry<String, String> entry : data.entrySet()) {
if (isNotEmpty(entry.getKey()) && isNotEmpty(entry.getValue())) {
// key和value不为空
sb.append(entry.getKey().trim()).append("=").append(URLEncoder.encode(entry.getValue().trim(), "utf-8"))
.append("&");
// 解码
// URLDecoder.decode("需要解码的内容", "utf-8");
}
}
return sb.substring(0, sb.length() - 1);// 去掉最后&
} /**
* 判断字符串是否为空,如果为空,返回true。否则返回false。
*
* @param value
* @return
*/
private static boolean isEmpty(String value) {
return value == null || value.trim().isEmpty();
} /**
* 判断字符串是否非空,如果不是空,返回true。如果是空,返回false。
*
* @param value
* @return
*/
private static boolean isNotEmpty(String value) {
return !isEmpty(value);
}
}
4.程序SendDataMonitor
package com.ibeifeng.sdk.java.logmake; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger; /**
* 发送url数据的监控者,用于启动一个单独的线程来发送数据
*
* @author ibeifeng
*
*/
public class SendDataMonitor {
// 日志记录对象
private static final Logger log = Logger.getGlobal();
// 队列,用户存储发送url, 并发控制的Int.maxSize大小的阻塞队列
private BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
// 用于单列的一个类对象
private static SendDataMonitor monitor = null; private SendDataMonitor() {
// 私有构造方法,进行单列模式的创建
} /**
* 获取单例的monitor对象实例
*
* @return
*/
public static SendDataMonitor getSendDataMonitor() {
if (monitor == null) {
synchronized (SendDataMonitor.class) {
if (monitor == null) {
monitor = new SendDataMonitor(); Thread thread = new Thread(new Runnable() { @Override
public void run() {
// 线程中调用具体的处理方法
SendDataMonitor.monitor.run();
}
});
// 测试的时候,不设置为守护模式
// thread.setDaemon(true);
thread.start();
}
}
}
return monitor;
} /**
* 添加一个url到队列中去
*
* @param url
* @throws InterruptedException
*/
public static void addSendUrl(String url) throws InterruptedException {
getSendDataMonitor().queue.put(url);
} /**
* 具体执行发送url的方法
*
*/
private void run() {
while (true) {
try {
// take 方法是阻塞方法,队列上有数据则取出,队列上没有数据则等待
String url = this.queue.take();
// 正式的发送url
HttpRequestUtil.sendData(url);
} catch (Throwable e) {
log.log(Level.WARNING, "发送url异常", e);
}
}
} /**
* 内部类,用户发送数据的http工具类
*
* @author ibeifeng
*
*/
public static class HttpRequestUtil {
/**
* 具体发送url的方法
*
* @param url
* @throws IOException
*/
public static void sendData(String url) throws IOException {
HttpURLConnection con = null;
BufferedReader in = null; try {
URL obj = new URL(url); // 创建url对象
con = (HttpURLConnection) obj.openConnection(); // 打开url连接
// 设置连接参数
con.setConnectTimeout(5000); // 连接过期时间
con.setReadTimeout(5000); // 读取数据过期时间
con.setRequestMethod("GET"); // 设置请求类型为get System.out.println("发送url:" + url);
// 发送连接请求
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
// TODO: 这里考虑是否可以
} finally {
try {
if (in != null) {
in.close();
}
} catch (Throwable e) {
// nothing
}
try {
con.disconnect();
} catch (Throwable e) {
// nothing
}
}
}
}
}
5.测试
6.结果
7.程序Test
package com.ibeifeng.sdk.java.logmake.test; import java.util.HashSet;
import java.util.Random;
import java.util.Set; import com.ibeifeng.sdk.java.logmake.AnalyticsEngineSDK; public class Test {
private static Random random = new Random(System.currentTimeMillis());
private static Set<Order> orders = new HashSet<>(); public static void main(String[] args) throws InterruptedException {
Order order = null;
while (true) {
order = getSuccessOrder();
// 发送订单付款行为数据
AnalyticsEngineSDK.onChargeSuccess(order.orderId, order.memberId);
Thread.sleep(random.nextInt(500));
if (random.nextInt(100) > 75) {
// 25%的订单发生退款行为
order = getRefundOrder();
if (order != null) {
// 发送订单退款行为数据
AnalyticsEngineSDK.onChargeRefund(order.orderId, order.memberId);
Thread.sleep(random.nextInt(500));
}
}
}
} private static Order getSuccessOrder() {
while (true) {
int orderId = random.nextInt(Math.max(200000, orders.size() * 2));
Order order = new Order();
order.orderId = "orderid" + orderId;
if (!orders.contains(order)) {
// 该order是一个新的order对象
order.memberId = "ibeifeng" + random.nextInt(1000);
orders.add(order);
return order;
}
}
} private static Order getRefundOrder() {
int count = 0;
Order[] os = orders.toArray(new Order[0]);
while (true) {
count++;
int index = random.nextInt(os.length); // 获取下标位置
Order order = os[index]; // 获取对应下标位置的数据
if (!order.refund) {
order.refund = true; // 设置为已经退款操作
return order;
} else if (count >= os.length) {
// 设置最多重试次数
return null;
}
}
} static class Order {
public String orderId;
public String memberId;
public boolean refund = false; @Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((orderId == null) ? 0 : orderId.hashCode());
return result;
} @Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Order other = (Order) obj;
if (orderId == null) {
if (other.orderId != null)
return false;
} else if (!orderId.equals(other.orderId))
return false;
return true;
}
}
}
8.测试
094实战 关于js SDK的程序,java SDK的程序的更多相关文章
- 阿里云SDK手册之java SDK
进行阿里云sdk开发的前提是已经购买阿里云的相关服务才能调用阿里的相关接口进行开发.最近公司在做云管控的项目,于是进行下摘录总结. 一. 环境准备 阿里云针对不同的开发语言提供不同的sdk,由于项目用 ...
- 关于js SDK的程序,java SDK的程序
一:JS SDK 1.修改配置workspace 2.导入 3.Demo.html <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Trans ...
- Spring MVC 程序首页的设置 - 一号门-程序员的工作,程序员的生活(java,python,delphi实战)
body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...
- 「小程序JAVA实战」springboot的后台搭建(31)
转自:https://idig8.com/2018/08/29/xiaochengxujavashizhanspringbootdehoutaidajian31/ 根据下面的图,我们来建立下对应的sp ...
- 「小程序JAVA实战」微信开发者工具helloworld(三)
转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-03/ 第一个小程序demo的运行,首选需要去使用开发工具 开发工具下载安装 https://mp. ...
- 「小程序JAVA实战」微信小程序简介(一)
转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-01/ 一直想学习小程序,苦于比较忙,加班比较多没时间,其实这都是理由,很多时候习惯了搬砖,习惯了固 ...
- 「小程序JAVA实战」微信小程序的简要注册流程(二)
转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-02/ 了解了小程序的历史和它未来的前景,我们开始注册小程序 注册小程序 可以参考官网介绍:http ...
- 【阿里云产品公测】消息队列服务MQS java SDK 机器人应用初体验
[阿里云产品公测]消息队列服务MQS java SDK 机器人应用初体验 作者:阿里云用户啊里新人 初体验 之 测评环境 由于MQS支持外网访问,因此我在本地做了一些简单测试(可能有些业余),之后 ...
- Java SDK夯住(Hang)问题排查
夯住(Hang)是指程序仍在运行,卡在某个方法调用上,没有返回也没有异常抛出:卡住时间从几秒到几小时不等. Java程序发生Hang时,应该首先使用 jstack 把java进程的堆栈信息保存下来 , ...
随机推荐
- luogu P1053 篝火晚会
传送门 首先如果题目的目标状态不是一个环就不合法 然后先把这个环搞出来,然后每个位置上的数对这个数对应的位置连边,可以发现有若干个环,而只要对这些环执行操作就好了,答案上界显然是\(n\).然后,如果 ...
- 创建Git独立分支
在使用git进行版本控制的某些场景中我们可能需要在一个项目中建立完全独立的分支,此分支将作为一个独立的版本历史根节点,不与之前任何分支拥有相同的版本祖先. 比如当我们要在一个项目中使用一个分支进行项目 ...
- Struts通配符映射
- 中间人攻击之ettercap嗅探
中间人攻击: 中间人攻击(Man-in-the-MiddleAttack,简称“MITM攻击”)是一种“间接”的入侵攻击,这种攻击模式是通过各种技术手段将受入侵者控制的一台计算机虚拟放置在网络连接中的 ...
- pytorch官网上两个例程
caffe用起来太笨重了,最近转到pytorch,用起来实在不要太方便,上手也非常快,这里贴一下pytorch官网上的两个小例程,掌握一下它的用法: 例程一:利用nn 这个module构建网络,实现 ...
- OpenWrt启动过程分析+添加自启动脚本【转】
一.OpenWrt启动过程分析 转自: http://www.eehello.com/?post=107 总结一下OpenWrt的启动流程:1.CFE->2.linux->3./etc/p ...
- BIM 相关资料
BIM 相关资料:http://pan.baidu.com/share/link?shareid=919219072&uk=966240844
- 阿里云服务器搭建FTP
操作系统:Windows Server 2008 R2企业版. 首先,创建一个用户组:ftpUsers,创建一个用户:ftpAdmin.并将ftpAdmin隶属于ftpUsers组 其次,需要安装ft ...
- NTFS文件系统简介
原文地址:http://www.cnblogs.com/watertao/archive/2011/11/28/2266595.html 1.简介 NTFS(New Technology File S ...
- ORA-01017: invalid username/password; logon denied 解决方案
在SQLPLUS窗口下进行用户登录,出现ORA-01017:invalid username/password:logon denied .如下图: 在网上找了很久,发现一个实用的解决方案,操作如下: ...