DatacenterBroker.java文件如下:

(其中,相关语句已经做好标注)

 /*
* Title: CloudSim Toolkit
* Description: CloudSim (Cloud Simulation) Toolkit for Modeling and Simulation of Clouds
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2009-2010, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim; import java.util.ArrayList;//Resizable-array implementation of the List interface
import java.util.HashMap;//散列表要解决的一个问题就是散列值的冲突问题,通常是两种方法:链表法和开放地址法。链表法就是将相同hash值的对象组织成一个链表放在hash值对应的槽位 (来源:http://www.yuloo.com/news/1012/527961.html)
import java.util.LinkedList;//The class implements the Deque interface, providing first-in-first-out queue operations for add, poll, along with other stack and deque operations
import java.util.List;//An ordered collection (also known as a sequence)
import java.util.Map;//An object that maps keys to values import org.cloudbus.cloudsim.core.CloudSim;//This class extends the CloudSimCore to enable network simulation in CloudSim
import org.cloudbus.cloudsim.core.CloudSimTags;//Contains various static command tags that indicate a type of action that needs to be undertaken by CloudSim entities when they receive or send events
import org.cloudbus.cloudsim.core.SimEntity;//This class represents a simulation entity
import org.cloudbus.cloudsim.core.SimEvent;//This class represents a simulation event which is passed between the entities in the simulation
import org.cloudbus.cloudsim.lists.CloudletList;//CloudletList is a collection of operations on lists of Cloudlets
import org.cloudbus.cloudsim.lists.VmList;//VmList is a collection of operations on lists of VMs /**DatacentreBroker类代表一经纪人行使用户角色,隐藏了虚拟机管理,如虚拟机创建,用户任务提交和虚拟机销毁
* DatacentreBroker represents a broker
* acting on behalf of a user. It hides VM management,
* as vm creation, sumbission of cloudlets to this VMs
* and destruction of VMs.
*
* @author Rodrigo N. Calheiros
* @author Anton Beloglazov
* @since CloudSim Toolkit 1.0
*/
public class DatacenterBroker extends SimEntity { // TODO: remove unnecessary variables移除不必要的变量 /** The vm list. 虚拟机列表*/
private List<? extends Vm> vmList; /** The vms created list. 虚拟机创建列表*/
private List<? extends Vm> vmsCreatedList; /** The cloudlet list.云任务列表 */
private List<? extends Cloudlet> cloudletList; /** The cloudlet submitted list. 云任务提交列表*/
private List<? extends Cloudlet> cloudletSubmittedList; /** The cloudlet received list. 云任务接收列表*/
private List<? extends Cloudlet> cloudletReceivedList; /** The cloudlets submitted. 提交的云任务*/
private int cloudletsSubmitted; /** The vms requested. 请求的虚拟机*/
private int vmsRequested; /** The vms acks.虚拟机确认 */
private int vmsAcks; /** The vms destroyed.虚拟机销毁 */
private int vmsDestroyed; /** The datacenter ids list. 数据中心ID列表*/
private List<Integer> datacenterIdsList; /** The datacenter requested ids list.请求数据中心ID列表 */
private List<Integer> datacenterRequestedIdsList; /** The vms to datacenters map. 虚拟机到数据中心映射*/
private Map<Integer, Integer> vmsToDatacentersMap; /** The datacenter characteristics list. 数据中心特征列表*/
private Map<Integer, DatacenterCharacteristics> datacenterCharacteristicsList; /**【创建新的数据中心代理对象】
* Created a new DatacenterBroker object.
*
* @param name name to be associated with this entity (as
* required by Sim_entity class from simjava package)
*
* @throws Exception the exception
*
* @pre name != null
* @post $none
*/
public DatacenterBroker(String name) throws Exception {
super(name); setVmList(new ArrayList<Vm>());
setVmsCreatedList(new ArrayList<Vm>());
setCloudletList(new ArrayList<Cloudlet>());
setCloudletSubmittedList(new ArrayList<Cloudlet>());
setCloudletReceivedList(new ArrayList<Cloudlet>()); cloudletsSubmitted=0;//= 与(0)是什么区别
setVmsRequested(0);
setVmsAcks(0);
setVmsDestroyed(0); setDatacenterIdsList(new LinkedList<Integer>());
setDatacenterRequestedIdsList(new ArrayList<Integer>());
setVmsToDatacentersMap(new HashMap<Integer, Integer>());
setDatacenterCharacteristicsList(new HashMap<Integer, DatacenterCharacteristics>());
} /**【方法 : 发送给代理必须创建的虚拟机列表】
* This method is used to send to the broker the list with
* virtual machines that must be created.
*
* @param list the list
*
* @pre list !=null
* @post $none
*/
public void submitVmList(List<? extends Vm> list) {
getVmList().addAll(list);
} /**【方法 : 发送云任务列表给代理】
* This method is used to send to the broker the list of
* cloudlets.
*
* @param list the list
*
* @pre list !=null
* @post $none
*/
public void submitCloudletList(List<? extends Cloudlet> list){
getCloudletList().addAll(list);
} /**(绑定云任务到指定虚拟机)
* Specifies that a given cloudlet must run in a specific virtual machine.
*
* @param cloudletId ID of the cloudlet being bount to a vm
* @param vmId the vm id
*
* @pre cloudletId > 0
* @pre id > 0
* @post $none
*/
public void bindCloudletToVm(int cloudletId, int vmId){
CloudletList.getById(getCloudletList(), cloudletId).setVmId(vmId);
} /**处理可用于代理的事件
* Processes events available for this Broker.
*
* @param ev a SimEvent object
*
* @pre ev != null
* @post $none
*/
@Override//http://www.javaeye.com/wiki/topic/694939 参考注释
public void processEvent(SimEvent ev) {//implements org.cloudbus.cloudsim.core.SimEntity.processEvent
//Log.printLine(CloudSim.clock()+"[Broker]: event received:"+ev.getTag());
switch (ev.getTag()){
// Resource characteristics request资源特征请求
case CloudSimTags.RESOURCE_CHARACTERISTICS_REQUEST:
processResourceCharacteristicsRequest(ev);
break;
// Resource characteristics answer资源特征应答
case CloudSimTags.RESOURCE_CHARACTERISTICS:
processResourceCharacteristics(ev);
break;
// VM Creation answer 虚拟机创建应答
case CloudSimTags.VM_CREATE_ACK:
processVmCreate(ev);
break;
//A finished cloudlet returned 返回一个完成的云任务
case CloudSimTags.CLOUDLET_RETURN:
processCloudletReturn(ev);
break;
// if the simulation finishes 仿真完成
case CloudSimTags.END_OF_SIMULATION:
shutdownEntity();
break;
// other unknown tags are processed by this method 处理unknown tags
default:
processOtherEvent(ev);
break;
}
} /**
* Process the return of a request for the characteristics of a PowerDatacenter(功率意识数据中心).
*
* @param ev a SimEvent object
*
* @pre ev != $null
* @post $none
*/
protected void processResourceCharacteristics(SimEvent ev) {
DatacenterCharacteristics characteristics = (DatacenterCharacteristics) ev.getData();
getDatacenterCharacteristicsList().put(characteristics.getId(), characteristics); if (getDatacenterCharacteristicsList().size() == getDatacenterIdsList().size()) {
setDatacenterRequestedIdsList(new ArrayList<Integer>());
createVmsInDatacenter(getDatacenterIdsList().get(0));
}
} /**处理PowerDatacenter特征的请求
* Process a request for the characteristics of a PowerDatacenter.
*
* @param ev a SimEvent object
*
* @pre ev != $null
* @post $none
*/
protected void processResourceCharacteristicsRequest(SimEvent ev) {
setDatacenterIdsList(CloudSim.getCloudResourceList());
setDatacenterCharacteristicsList(new HashMap<Integer, DatacenterCharacteristics>()); Log.printLine(CloudSim.clock()+": "+getName()+ ": Cloud Resource List received with "+getDatacenterIdsList().size()+" resource(s)"); for (Integer datacenterId : getDatacenterIdsList()) {
sendNow(datacenterId, CloudSimTags.RESOURCE_CHARACTERISTICS, getId());
}
} /**【请求虚拟机响应应答】
* Process the ack received due to a request for VM creation.
*
* @param ev a SimEvent object
*
* @pre ev != null
* @post $none
*/
protected void processVmCreate(SimEvent ev) {
int[] data = (int[]) ev.getData();
int datacenterId = data[0];
int vmId = data[1];
int result = data[2]; if (result == CloudSimTags.TRUE) {
getVmsToDatacentersMap().put(vmId, datacenterId);
getVmsCreatedList().add(VmList.getById(getVmList(), vmId));
Log.printLine(CloudSim.clock()+": "+getName()+ ": VM #"+vmId+" has been created in Datacenter #" + datacenterId + ", Host #" + VmList.getById(getVmsCreatedList(), vmId).getHost().getId());
} else {
Log.printLine(CloudSim.clock()+": "+getName()+ ": Creation of VM #"+vmId+" failed in Datacenter #" + datacenterId);
} incrementVmsAcks(); if (getVmsCreatedList().size() == getVmList().size() - getVmsDestroyed()) { // all the requested VMs have been created 所有请求虚拟机已创建
submitCloudlets();
} else {
if (getVmsRequested() == getVmsAcks()) { // all the acks received, but some VMs were not created所有响应接受。但一些虚拟机没有创建
// find id of the next datacenter that has not been tried找出下一个数据中心ID
for (int nextDatacenterId : getDatacenterIdsList()) {
if (!getDatacenterRequestedIdsList().contains(nextDatacenterId)) {
createVmsInDatacenter(nextDatacenterId);
return;
}
} //all datacenters already queried 咨询了所有的数据中心
if (getVmsCreatedList().size() > 0) { //if some vm were created 一些虚拟机已经创建
submitCloudlets();
} else { //no vms created. abort停止
Log.printLine(CloudSim.clock() + ": " + getName() + ": none of the required VMs could be created. Aborting");
finishExecution();
}
}
}
} /**【处理云任务返回事件】
* Process a cloudlet return event.
*
* @param ev a SimEvent object
*
* @pre ev != $null
* @post $none
*/
protected void processCloudletReturn(SimEvent ev) {
Cloudlet cloudlet = (Cloudlet) ev.getData();
getCloudletReceivedList().add(cloudlet);
Log.printLine(CloudSim.clock()+": "+getName()+ ": Cloudlet "+cloudlet.getCloudletId()+" received");
cloudletsSubmitted--;
if (getCloudletList().size()==0&&cloudletsSubmitted==0) { //all cloudlets executed 所有云任务已执行完
Log.printLine(CloudSim.clock()+": "+getName()+ ": All Cloudlets executed. Finishing...");
clearDatacenters();
finishExecution();
} else { //some cloudlets haven't finished yet 一些任务没完成
if (getCloudletList().size()>0 && cloudletsSubmitted==0) {
//all the cloudlets sent finished. It means that some bount
//cloudlet is waiting its VM be created云任务发送完毕
clearDatacenters();
createVmsInDatacenter(0);
} }
} /**【重写 创建一个新的不同类型的代理】
* Overrides this method when making a new and different type of Broker.
* This method is called by {@link #body()} for incoming unknown tags.
*
* @param ev a SimEvent object
*
* @pre ev != null
* @post $none
*/
protected void processOtherEvent(SimEvent ev){
if (ev == null){
Log.printLine(getName() + ".processOtherEvent(): " + "Error - an event is null.");
return;
} Log.printLine(getName() + ".processOtherEvent(): " + "Error - event unknown by this DatacenterBroker.");
} /**在数据中心里创建虚拟机
* Create the virtual machines in a datacenter.
*
* @param datacenterId Id of the chosen PowerDatacenter
*
* @pre $none
* @post $none
*/
protected void createVmsInDatacenter(int datacenterId) {
// send as much vms as possible for this datacenter before trying the next one
int requestedVms = 0;
String datacenterName = CloudSim.getEntityName(datacenterId);
for (Vm vm : getVmList()) {
if (!getVmsToDatacentersMap().containsKey(vm.getId())) {
Log.printLine(CloudSim.clock() + ": " + getName() + ": Trying to Create VM #" + vm.getId() + " in " + datacenterName);
sendNow(datacenterId, CloudSimTags.VM_CREATE_ACK, vm);
requestedVms++;
}
} getDatacenterRequestedIdsList().add(datacenterId); setVmsRequested(requestedVms);
setVmsAcks(0);
} /**提交云任务到虚拟机
* Submit cloudlets to the created VMs.
*
* @pre $none
* @post $none
*/
protected void submitCloudlets() {
int vmIndex = 0;
for (Cloudlet cloudlet : getCloudletList()) {
Vm vm;
if (cloudlet.getVmId() == -1) { //if user didn't bind this cloudlet and it has not been executed yet用户没有绑定云任务
vm = getVmsCreatedList().get(vmIndex);
} else { //submit to the specific vm提交给专门的虚拟机
vm = VmList.getById(getVmList(), cloudlet.getVmId());
if (vm == null) { // vm was not created 虚拟机没有创建
Log.printLine(CloudSim.clock()+": "+getName()+ ": Postponing execution of cloudlet "+cloudlet.getCloudletId()+": bount VM not available");
continue;
}
} Log.printLine(CloudSim.clock()+": "+getName()+ ": Sending cloudlet "+cloudlet.getCloudletId()+" to VM #"+vm.getId());
cloudlet.setVmId(vm.getId());
sendNow(getVmsToDatacentersMap().get(vm.getId()), CloudSimTags.CLOUDLET_SUBMIT, cloudlet);
cloudletsSubmitted++;
vmIndex = (vmIndex + 1) % getVmsCreatedList().size();
getCloudletSubmittedList().add(cloudlet);
} //从等待列表中除去提交的任务 remove submitted cloudlets from waiting list
for (Cloudlet cloudlet : getCloudletSubmittedList()) {
getCloudletList().remove(cloudlet);
}
} /**销毁虚拟机
* Destroy the virtual machines running in datacenters.
*
* @pre $none
* @post $none
*/
protected void clearDatacenters() {
for (Vm vm : getVmsCreatedList()) {
Log.printLine(CloudSim.clock() + ": " + getName() + ": Destroying VM #" + vm.getId());
sendNow(getVmsToDatacentersMap().get(vm.getId()), CloudSimTags.VM_DESTROY, vm);
} getVmsCreatedList().clear();
} /**仿真结束
* Send an internal event communicating the end of the simulation.
*
* @pre $none
* @post $none
*/
private void finishExecution() {
sendNow(getId(), CloudSimTags.END_OF_SIMULATION);
} /* (non-Javadoc)
* @see cloudsim.core.SimEntity#shutdownEntity()
*/
@Override
public void shutdownEntity() {
Log.printLine(getName() + " is shutting down...");
} /* (non-Javadoc)
* @see cloudsim.core.SimEntity#startEntity()
*/
@Override
public void startEntity() {
Log.printLine(getName() + " is starting...");
schedule(getId(), 0, CloudSimTags.RESOURCE_CHARACTERISTICS_REQUEST);
} /**虚拟机列表
* Gets the vm list.
*
* @param <T> the generic type
* @return the vm list
*/
@SuppressWarnings("unchecked")
public <T extends Vm> List<T> getVmList() {
return (List<T>) vmList;
} /**设置虚拟机列表
* Sets the vm list.
*
* @param <T> the generic type
* @param vmList the new vm list
*/
protected <T extends Vm> void setVmList(List<T> vmList) {
this.vmList = vmList;
} /**云任务列表
* Gets the cloudlet list.
*
* @param <T> the generic type
* @return the cloudlet list
*/
@SuppressWarnings("unchecked")
public <T extends Cloudlet> List<T> getCloudletList() {
return (List<T>) cloudletList;
} /**设置云任务列表
* Sets the cloudlet list.
*
* @param <T> the generic type
* @param cloudletList the new cloudlet list
*/
protected <T extends Cloudlet> void setCloudletList(List<T> cloudletList) {
this.cloudletList = cloudletList;
} /**云任务提交列表
* Gets the cloudlet submitted list.
*
* @param <T> the generic type
* @return the cloudlet submitted list
*/
@SuppressWarnings("unchecked")
public <T extends Cloudlet> List<T> getCloudletSubmittedList() {
return (List<T>) cloudletSubmittedList;
} /**设置云任务提交列表
* Sets the cloudlet submitted list.
*
* @param <T> the generic type
* @param cloudletSubmittedList the new cloudlet submitted list
*/
protected <T extends Cloudlet> void setCloudletSubmittedList(List<T> cloudletSubmittedList) {
this.cloudletSubmittedList = cloudletSubmittedList;
} /**云任务接收列表
* Gets the cloudlet received list.
*
* @param <T> the generic type
* @return the cloudlet received list
*/
@SuppressWarnings("unchecked")
public <T extends Cloudlet> List<T> getCloudletReceivedList() {
return (List<T>) cloudletReceivedList;
} /**设置云任务接收列表
* Sets the cloudlet received list.
*
* @param <T> the generic type
* @param cloudletReceivedList the new cloudlet received list
*/
protected <T extends Cloudlet> void setCloudletReceivedList(List<T> cloudletReceivedList) {
this.cloudletReceivedList = cloudletReceivedList;
} /**虚拟机列表 ???
* Gets the vm list.
*
* @param <T> the generic type
* @return the vm list
*/
@SuppressWarnings("unchecked")
public <T extends Vm> List<T> getVmsCreatedList() {
return (List<T>) vmsCreatedList;
} /**
* Sets the vm list.
*
* @param <T> the generic type
* @param vmsCreatedList the vms created list
*/
protected <T extends Vm> void setVmsCreatedList(List<T> vmsCreatedList) {
this.vmsCreatedList = vmsCreatedList;
} /**虚拟机请求
* Gets the vms requested.
*
* @return the vms requested
*/
protected int getVmsRequested() {
return vmsRequested;
} /**
* Sets the vms requested.
*
* @param vmsRequested the new vms requested
*/
protected void setVmsRequested(int vmsRequested) {
this.vmsRequested = vmsRequested;
} /**虚拟机响应
* Gets the vms acks.
*
* @return the vms acks
*/
protected int getVmsAcks() {
return vmsAcks;
} /**
* Sets the vms acks.
*
* @param vmsAcks the new vms acks
*/
protected void setVmsAcks(int vmsAcks) {
this.vmsAcks = vmsAcks;
} /**增加虚拟机响应
* Increment vms acks.
*/
protected void incrementVmsAcks() {
this.vmsAcks++;
} /**销毁虚拟机
* Gets the vms destroyed.
*
* @return the vms destroyed
*/
protected int getVmsDestroyed() {
return vmsDestroyed;
} /**
* Sets the vms destroyed.
*
* @param vmsDestroyed the new vms destroyed
*/
protected void setVmsDestroyed(int vmsDestroyed) {
this.vmsDestroyed = vmsDestroyed;
} /**数据执行ID
* Gets the datacenter ids list.
*
* @return the datacenter ids list
*/
protected List<Integer> getDatacenterIdsList() {
return datacenterIdsList;
} /**
* Sets the datacenter ids list.
*
* @param datacenterIdsList the new datacenter ids list
*/
protected void setDatacenterIdsList(List<Integer> datacenterIdsList) {
this.datacenterIdsList = datacenterIdsList;
} /**虚拟机到数据中心映射
* Gets the vms to datacenters map.
*
* @return the vms to datacenters map
*/
protected Map<Integer, Integer> getVmsToDatacentersMap() {
return vmsToDatacentersMap;
} /**
* Sets the vms to datacenters map.
*
* @param vmsToDatacentersMap the vms to datacenters map
*/
protected void setVmsToDatacentersMap(Map<Integer, Integer> vmsToDatacentersMap) {
this.vmsToDatacentersMap = vmsToDatacentersMap;
} /**数据中心特征列表
* Gets the datacenter characteristics list.
*
* @return the datacenter characteristics list
*/
protected Map<Integer, DatacenterCharacteristics> getDatacenterCharacteristicsList() {
return datacenterCharacteristicsList;
} /**
* Sets the datacenter characteristics list.
*
* @param datacenterCharacteristicsList the datacenter characteristics list
*/
protected void setDatacenterCharacteristicsList(Map<Integer, DatacenterCharacteristics> datacenterCharacteristicsList) {
this.datacenterCharacteristicsList = datacenterCharacteristicsList;
} /**
* Gets the datacenter requested ids list.
*
* @return the datacenter requested ids list
*/
protected List<Integer> getDatacenterRequestedIdsList() {
return datacenterRequestedIdsList;
} /**
* Sets the datacenter requested ids list.
*
* @param datacenterRequestedIdsList the new datacenter requested ids list
*/
protected void setDatacenterRequestedIdsList(List<Integer> datacenterRequestedIdsList) {
this.datacenterRequestedIdsList = datacenterRequestedIdsList;
} }

CloudSim源代码学习——服务代理商(DatacenterBroker)的更多相关文章

  1. CloudSim源代码学习——任务单元(Cloudlet)

    /* * Title: CloudSim Toolkit * Description: CloudSim (Cloud Simulation) Toolkit for Modeling and Sim ...

  2. CloudSim源代码学习——云数据中心(Datacenter)

    package org.cloudbus.cloudsim; import java.text.DecimalFormat;//十进制 import java.util.ArrayList; impo ...

  3. CloudSim源代码学习——虚拟机(VM)

    package org.cloudbus.cloudsim; import java.util.ArrayList;//This class provides methods to manipulat ...

  4. igmpproxy源代码学习——igmpProxyInit()

    igmpproxy源代码学习--igmpProxyInit()函数详解,igmpproxy初始化 在运行igmpproxy的主程序igmpproxyRun()之前需要对igmpproxy进行一些配置, ...

  5. struts2源代码学习之初始化(一)

    看struts2源代码已有一段时日,从今天開始,就做一个总结吧. 首先,先看看怎么调试struts2源代码吧,主要是下面步骤: 使用Myeclipse创建一个webproject 导入struts2须 ...

  6. 停车场管理软件附带源代码 J2EE服务端+android客户端

    该源码是停车场管理软件附带源代码 J2EE服务端+android客户端,也是一套停车场管理车辆进出的管理软,喜欢的朋友可以看看吧. 应用的后台管理主要功能介绍:1  机构管理 ,机构有从属管理< ...

  7. [Java] LinkedList / Queue - 源代码学习笔记

    简单地画了下 LinkedList 的继承关系,如下图.只是画了关注的部分,并不是完整的关系图.本博文涉及的是 Queue, Deque, LinkedList 的源代码阅读笔记.关于 List 接口 ...

  8. 开源中国安卓client源代码学习(一) 渐变启动界面

    开源中国安卓client源代码学习(一) 渐变启动界面 准备学习安卓开发, 看到网上有人推荐开源中国安卓client的源代码, 说里面包括了大部分技术, 于是准备好好研究研究. 特开通此系列博客来记录 ...

  9. 读Flask源代码学习Python--config原理

    读Flask源代码学习Python--config原理 个人学习笔记,水平有限.如果理解错误的地方,请大家指出来,谢谢!第一次写文章,发现好累--!. 起因   莫名其妙在第一份工作中使用了从来没有接 ...

随机推荐

  1. Swift5 语言指南(十二) 属性

    属性将值与特定类,结构或枚举相关联.存储的属性将常量和变量值存储为实例的一部分,而计算属性则计算(而不是存储)值.计算属性由类,结构和枚举提供.存储的属性仅由类和结构提供. 存储和计算属性通常与特定类 ...

  2. css 如何“画”一个抽奖转盘

    主要描述的是如何运用 css 绘制一个抽奖转盘,并运用原生 js 实现转盘抽奖效果. 先来张效果图: 布局 一般来说,转盘一般有四个部分组成:外层闪烁的灯.内层旋转的圆盘.圆盘上的中奖结果.指针. 所 ...

  3. Liferay7 BPM门户开发之12:acitiviti和liferay用户权限体系集成

    写到第12章才出现Liferay的内容,希望可以厚积薄发. 我们的目标是不使用不维护Activiti的用户组织架构,只维护Liferay的体系,这样的好处是非常明显的,即不用做组织架构的同步工作. 原 ...

  4. Webpack代理proxy配置,解决本地跨域调试问题,同时允许绑定host域名调试

    Webpack代理proxy配置,解决本地跨域调试问题,同时允许绑定host域名调试 会撸码的小马 关注 2018.05.29 17:30* 字数 212 阅读 1488评论 0喜欢 2 接到上一章, ...

  5. 2019年19道java经典面试题(附答案)

    1.不可变对象 指对象一旦被创建状态不能再改变.任何修改都会创建一个新的对象,如 String.Integer及其它包装类. 2.能否创建一个包含可变对象的不可变对象? 可以.不要共享可变对象的引用就 ...

  6. 原生js实现vue组件功能

    在如今VUE盛行的情况下,我们一直在惊叹于VUE的组件的功能,却不知道,原生js早就已经支持了这个功能. 最近在公开课学到的,js还有很多很多需要探索学习. 下面是一个简单的例子 <!DOCTY ...

  7. python 打包exe

    下载及安装:pip install pyinstaller 执行命令: pyinstaller -F xxx.py pyinstaller --onefile meng.py 可以运行的exe文件位于 ...

  8. Fork/Join框架

    java 5开始引入了Executor和ExecutorService接口以及实现这两个接口的类之后,使得java在并发支持上得到了进一步的提升.执行器框架(Executor Framework)将任 ...

  9. Android快速实现二维码扫描--Zxing

    Android中二维码扫描的最常用库是zxing和zbar,zxing项目地址为https://github.com/zxing/zxing,目前还有多个人在维护.zbar主要用C来写的,对速度有要求 ...

  10. 深度学习论文翻译解析(四):Faster R-CNN: Down the rabbit hole of modern object detection

    论文标题:Faster R-CNN: Down the rabbit hole of modern object detection 论文作者:Zhi Tian , Weilin Huang, Ton ...