struts2源代码分析

2024-11-17 版权声明 我要投稿

struts2源代码分析(精选8篇)

struts2源代码分析 篇1

读者如果曾经学习过Struts1.x或者有过Struts1.x的开发经验,那么千万不要想当然地以为这一章可以跳过。实际上Struts1.x与Struts2并无我们想象的血缘关系。虽然Struts2的开发小组极力保留Struts1.x的习惯,但因为Struts2的核心设计完全改变,从思想到设计到工作流程,都有了很大的不同。

Struts2是Struts社区和WebWork社区的共同成果,我们甚至可以说,Struts2是WebWork的升级版,他采用的正是WebWork的核心,所以,Struts2并不是一个不成熟的产品,相反,构建在WebWork基础之上的Struts2是一个运行稳定、性能优异、设计成熟的WEB框架。

本章主要对Struts的源代码进行分析,因为Struts2与WebWork的关系如此密不可分,因此,读者需要下载xwork的源代码,访问http://文件,则通过过滤器链继续往下传送,直到到达请求的资源为止。

如果getMapping()方法返回有效的ActionMapping对象,则被认为正在请求某个Action,将调用Dispatcher.serviceAction(request, response, servletContext, mapping)方法,该方法是处理Action的关键所在。上述过程的源代码如清单15所示。

代码清单15:FilterDispatcher.doFilter()方法

publicvoid doFilter(ServletRequest req, ServletResponse res, FilterChain chain)throws IOException, ServletException {

HttpServletRequest request =(HttpServletRequest)req;

HttpServletResponse response =(HttpServletResponse)res;

ServletContext servletContext = getServletContext();

String timerKey = “FilterDispatcher_doFilter: ”;

try {

UtilTimerStack.push(timerKey);

request = prepareDispatcherAndWrapRequest(request, response);//重新包装request

ActionMapping mapping;

try {

mapping = actionMapper.getMapping(request, dispatcher.getConfigurationManager());//得到存储Action信息的ActionMapping对象

} catch(Exception ex){

……(省略部分代码)

return;

}

if(mapping == null){//如果mapping为null,则认为不是请求Action资源

String resourcePath = RequestUtils.getServletPath(request);

if(“".equals(resourcePath)&& null!= request.getPathInfo()){

resourcePath = request.getPathInfo();

}

{

ngth());

//如果请求的资源以/struts开头,则当作静态资源处理

if(serveStatic && resourcePath.startsWith(”/struts“))

String name = resourcePath.substring(”/struts“.le

findStaticResource(name, request, response);} else {

//否则,过滤器链继续往下传递

chain.doFilter(request, response);}

// The framework did its job here

return;

}

//如果请求的资源是Action,则调用serviceAction方法。

dispatcher.serviceAction(request, response, servletContext, mapping);

} finally {

try {

ActionContextCleanUp.cleanUp(req);

}

} finally {

UtilTimerStack.pop(timerKey);

} }

这段代码的活动图如图18所示:

(图18)

在Dispatcher.serviceAction()方法中,先加载Struts2的配置文件,如果没有人为配置,则默认加载struts-default.xml、struts-plugin.xml和struts.xml,并且将配置信息保存在形如com.opensymphony.xwork2.config.entities.XxxxConfig的类中。

类com.opensymphony.xwork2.config.providers.XmlConfigurationProvider负责配置文件的读取和解析,addAction()方法负责读取标签,并将数据保存在ActionConfig中;addResultTypes()方法负责将标签转化为ResultTypeConfig对象;loadInterceptors()方法负责将标签转化为InterceptorConfig对象;loadInterceptorStack()方法负责将标签转化为InterceptorStackConfig对象;loadInterceptorStacks()方法负责将标签转化成InterceptorStackConfig对象。而上面的方法最终会被addPackage()方法调用,将所读取到的数据汇集到PackageConfig对象中,细节请参考代码清单16。

代码清单16:XmlConfigurationProvider.addPackage()方法

protected PackageConfig addPackage(Element packageElement)throws ConfigurationException {

PackageConfig newPackage = buildPackageContext(packageElement);

age

if(newPackage.isNeedsRefresh()){

return newPackage;} if(LOG.isDebugEnabled()){

LOG.debug(”Loaded “ + newPackage);} // add result types(and default result)to this package addResultTypes(newPackage, packageElement);// load the interceptors and interceptor stacks for this packloadInterceptors(newPackage, packageElement);// load the default interceptor reference for this package loadDefaultInterceptorRef(newPackage, packageElement);// load the default class ref for this package loadDefaultClassRef(newPackage, packageElement);// load the global result list for this package loadGlobalResults(newPackage, packageElement);// load the global exception handler list for this package

loadGlobalExceptionMappings(newPackage, packageElement);

// get actions

NodeList actionList = packageElement.getElementsByTagName(”action“);

for(int i = 0;i < actionList.getLength();i++){

Element actionElement =(Element)actionList.item(i);

addAction(actionElement, newPackage);

}

// load the default action reference for this package

loadDefaultActionRef(newPackage, packageElement);

configuration.addPackageConfig(newPackage.getName(), newPackage);

return newPackage;

}

活动图如图19所示:

(图19)

配置信息加载完成后,创建一个Action的代理对象——ActionProxy引用,实际上对Action的调用正是通过ActionProxy实现的,而ActionProxy又由ActionProxyFactory创建,ActionProxyFactory是创建ActionProxy的工厂。

注:ActionProxy和ActionProxyFactory都是接口,他们的默认实现类分别是DefaultActionProxy和DefaultActionProxyFactory,位于com.opensymphony.xwork2包下。

在这里,我们绝对有必要介绍一下com.opensymphony.xwork2.DefaultActionInvocation类,该类是对ActionInvocation接口的默认实现,负责Action和截拦器的执行。

在DefaultActionInvocation类中,定义了invoke()方法,该方法实现了截拦器的递归调用和执行Action的execute()方法。其中,递归调用截拦器的代码如清单17所示:

代码清单17:调用截拦器,DefaultActionInvocation.invoke()方法的部分代码

if(interceptors.hasNext()){

//从截拦器集合中取出当前的截拦器

final InterceptorMapping interceptor =(InterceptorMapping)interceptors.next();

UtilTimerStack.profile(”interceptor: “+interceptor.getName(),new UtilTimerStack.ProfilingBlock(){

public String doProfiling()throws Exception {

//执行截拦器(Interceptor)接口中定义的intercept方法

resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);

returnnull;

}

});

}

从代码中似乎看不到截拦器的递归调用,其实是否递归完全取决于程序员对程序的控制,先来看一下Interceptor接口的定义:

代码清单18:Interceptor.java publicinterface Interceptor extends Serializable {

void destroy();

void init();

String intercept(ActionInvocation invocation)throws Exception;}

所有的截拦器必须实现intercept方法,而该方法的参数恰恰又是ActionInvocation,所以,如果在intercept方法中调用invocation.invoke(),代码清单17会再次执行,从Action的Intercepor列表中找到下一个截拦器,依此递归。下面是一个自定义截拦器示例:

代码清单19:CustomIntercepter.java publicclass CustomIntercepter extends AbstractInterceptor {

@Override

public String intercept(ActionInvocation actionInvocation)throws Exception

} { actionInvocation.invoke();return”李赞红“;}

截拦器的调用活动图如图20所示:

(图20)

如果截拦器全部执行完毕,则调用invokeActionOnly()方法执行Action,invokeActionOnly()方法基本没做什么工作,只调用了invokeAction()方法。

为了执行Action,必须先创建该对象,该工作在DefaultActionInvocation的构造方法中调用init()方法早早完成。调用过程是:DefaultActionInvocation()->init()->createAction()。创建Action的代码如下:

代码清单20:DefaultActionInvocation.createAction()方法

protectedvoid createAction(Map contextMap){

try {

action = objectFactory.buildAction(proxy.getActionName(), proxy.getNamespace(), proxy.getConfig(), contextMap);

} catch(InstantiationException e){

……异常代码省略

}

}

Action创建好后,轮到invokeAction()大显身手了,该方法比较长,但关键语句实在很少,用心点看不会很难。

代码清单20:DefaultActionInvocation.invokeAction()方法

protected String invokeAction(Object action, ActionConfig actionConfig)throws Exception {

//获取Action中定义的execute()方法名称,实际上该方法是可以随便定义的

String methodName = proxy.getMethod();

String timerKey = ”invokeAction: “+proxy.getActionName();

try {

UtilTimerStack.push(timerKey);

Method method;

try {

//将方法名转化成Method对象

method = getAction().getClass().getMethod(methodName, new Class[0]);

} catch(NoSuchMethodException e){

// hmm--OK, try doXxx instead

try {

//如果Method出错,则尝试在方法名前加do,再转成Method对象

String altMethodName = ”do“ + methodName.substring(0, 1).toUpperCase()+ methodName.substring(1);

method = getAction().getClass().getMethod(altMethodName, new Class[0]);

} catch(NoSuchMethodException e1){

// throw the original one

throw e;

}

}

//执行方法

[0]);

}

Object methodResult = method.invoke(action, new Object

//处理跳转

if(methodResult instanceof Result){

this.result =(Result)methodResult;

returnnull;

} else {

return(String)methodResult;

} } catch(NoSuchMethodException e){

……省略异常代码 } finally {

UtilTimerStack.pop(timerKey);}

刚才使用了一段插述,我们继续回到ActionProxy类。

我们说Action的调用是通过ActionProxy实现的,其实就是调用了ActionProxy.execute()方法,而该方法又调用了ActionInvocation.invoke()方法。归根到底,最后调用的是DefaultActionInvocation.invokeAction()方法。

以下是调用关系图:

其中:

Ø

ActionProxy:管理Action的生命周期,它是设置和执行Action的起始点。

Ø

ActionInvocation:在ActionProxy层之下,它表示了Action的执行状态。它持有Action实例和所有的Interceptor

以下是serviceAction()方法的定义:

代码清单21:Dispatcher.serviceAction()方法

publicvoid serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,ActionMapping mapping)throws ServletException {

Map extraContext = createContextMap(request, response, mapping, context);

// If there was a previous value stack, then create a new copy and pass it in to be used by the new Action

ValueStack stack =(ValueStack)request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);

if(stack!= null){

extraContext.put(ActionContext.VALUE_STACK, ValueStackFactory.getFactory().createValueStack(stack));

}

String timerKey = ”Handling request from Dispatcher“;

try {

UtilTimerStack.push(timerKey);

String namespace = mapping.getNamespace();

String name = mapping.getName();

String method = mapping.getMethod();

Configuration config = configurationManager.getConfiguration();

ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace, name, extraContext, true, false);

proxy.setMethod(method);

request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());

// if the ActionMapping says to go straight to a result, do it!

if(mapping.getResult()!= null){

Result result = mapping.getResult();

result.execute(proxy.getInvocation());

} else {

proxy.execute();

}

// If there was a previous value stack then set it back onto the request

if(stack!= null){

request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);

}

} catch(ConfigurationException e){

LOG.error(”Could not find action or result", e);

sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);

} catch(Exception e){

thrownew ServletException(e);

} finally {

UtilTimerStack.pop(timerKey);

}

}

最后,通过Result完成页面的跳转。

3.4 本小节总结

总体来讲,Struts2的工作机制比Struts1.x要复杂很多,但我们不得不佩服Struts和WebWork开发小组的功底,代码如此优雅,甚至能够感受看到两个开发小组心神相通的默契。两个字:佩服。

以下是Struts2运行时调用方法的顺序图:

(图21)

四、总结

阅读源代码是一件非常辛苦的事,对读者本身的要求也很高,一方面要有扎实的功底,另一方面要有超强的耐力和恒心。本章目的就是希望能帮助读者理清一条思路,在必要的地方作出简单的解释,达到事半功倍的效果。

当然,笔者不可能为读者解释所有类,这也不是我的初衷。Struts2+xwork一共有700余类,除了为读者做到现在的这些,已无法再做更多的事情。读者可以到Struts官方网站下载帮助文档,慢慢阅读和理解,相信会受益颇丰。

本章并不适合java语言初学者或者对java博大精深的思想理解不深的读者阅读,这其中涉及到太多的术语和类的使用,特别不要去钻牛角尖,容易使自信心受损。基本搞清楚Struts2的使用之后,再回过头来阅读本章,对一些知识点和思想也许会有更深的体会。

struts2源代码分析 篇2

随着Web领域的不断发展,MVC (Mode-View-Controller)成为一种公认的优秀设计模式,该模式分为模型层、视图层、控制层,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。Struts2是建立在Struts和WebWork基础上,并且集成了Struts和WebWork的优点,它是使用了MVC设计模式的框架,能够具有更好的可扩展性、强大的功能,同时它也是目前最流行的MVC框架之一[1]。FreeMarker和Velocity是应用在Struts2中非常流行的模板语言。主要研究FreeMarker和Velocity模板语言在Struts2中的应用,工作原理,分析比较两种模板语言的特点,方便开发人员在开发过程中,选择最合适的模板语言开发项目工程,提高工作效率,从而节省了开发所需要的时间。

2 FreeMarker模板语言

FreeMarker是一个用Java编写的模板引擎,能够将数据与页面模板分离,根据指定的模板输出多种规格的文本,如HTML、XML、RTF等。FreeMarker实际上是被设计用来生成HTML页面,尤其是通过实现了基于MVC (Mode-View-Controller)模式的Java Servlet应用程序。使用MVC模式的动态页面的设计思想,可以将前端设计师从程序员中分离出来。网页设计人员专注于改写视图页面的显示内容,而不受到程序开发人员编写底层代码的干扰,这是因为将业务逻辑和视图页面设计被分离出来了。这种设计思想可以让同一个人在同一个项目当中拥有程序员和页面设计师的角色,由于逻辑和视图分离使代码变得简洁,更加方便程序员去维护。

FreeMarker的工作原理是模板+数据模型=输出[2],以此将数据模型中的数据合并到模板并将其输出,如图1所示。虽然FreeMarker也具有一些编程能力,但是它不是一种很全面的编程语言。当程序需要显示数据库的数据信息时,FreeMarker是通过模板生成文本页面把数据库中的数据信息显示出来。

FreeMarker不是Web开发的应用程序框架。它是一个适用于Web应用程序框架中的组件,但是FreeMarker引擎本身并不知道HTTP协议或Java Servlet的存在。它仅仅来生成文本内容。即使是这样,它也非常适用于非Web应用程序的开发环境。值得注意的是,我们使用FreeMarker作为视图层的组件,是为了给例如Struts这样的Model 2应用框架提供现成的解决方案。FreeMarker本身是免费的,它基于BSD规则的许可协议。它也是OSI认证的开源软件[2]。

FreeMarker是Struts2默认的模板技术,较Velocity模板引擎,FreeMarker支持JSP标签,内嵌XML、DOM解析功更强大,使用起来更加方便快捷。此外,Free Marker的指令具有对数据的分值控制、循环输出等功能,对处理Hash和Sequence对象时具有更好的灵活性。Free Marker生成的纯文本的静态文件,有利于减轻服务器的负担[3]。如果用户使用FreeMarker生成纯文本的HTML、XML等文档,服务器需要更少的硬件资源,服务器能够对用户的请求做出快速的响应,不同于JSP页面,当JSP页面发布于服务器上时,用户请求需要不断地与服务器进行交互,从而使服务器占用了大量的资源。与JSP相比较,使用FreeMarker能够提高服务器的响应速度,缩短反应时间,降低对硬件资源的占用率。

3 Velocity模板语言

Velocity模板语言简称VTL,是一个基于Java的模版引擎[4]。在同一个应用程序中,Web设计师可以使用Velocity模板语言预先设计好模板Java开发人员编写程序代码设置上下文,将页面中的数据放入到上下文中,通过使用Velocity引擎将数据和上下文结合起来,实现动态页面的效果。Java代码和视图设计的有效分离[5],可以使Java开发人员专注于Java代码的底层编写,页面设计师专注于页面设计的效果,不需要考虑更多的代码编程,有利于后期应用程序的管理与维护。Velocity可用来从模板产生Web页面,SQL,PostScript以及其他输出,简化了Web开发。它也可用于一个独立的程序以产生源代码和报告,或者作为其他系统的一个集成组件。Velocity还支持模板的国际化编码转换。Velocity也是Apache软件组织提供的一项开源项目,可以免费下载。

Struts2对Velocity提供了很好的支持,只需要经过简单的配置,就可以在程序中使用Velocity,不需要Velocity的API。

4 比较分析

FreeMarker和Velocity都是目前非常流行的两种模板语言,两种语言的语法也很相似,适用对象也基本相同,它们最大的相似点都是通过分离页面视图和程序逻辑,从而实现MVC架构。

FreeMarker比Velocity多了一个格式化的功能,而且FreeMarker还支持JSP标签,内嵌XML DOM解析,功能上要比Velocity强[1]。使用Velocity,需要寻找各种工作环境或者特定工具来一次次地解决典型的模板创作任务,最后会浪费很多时间。工作环境经常意味着把Java对象在Velocity模板中直接使用,这违反了简单、无编程HTML设计的理念。如果将表示任务移到控制器代码中的话,这也违反了MVC框架设计理念。使用FreeMarker,可以以out-of-the-box的方式实现Velocity所能做的。

当访问一个未定义的变量,可以通过配置FreeMarker来停止render模板显示错误信息,或者跳过错误部分,FreeMarker会记录问题(日志),在写错指令名时,FreeMarker也会抛出异常。而Velocity会输出源代码。

Velocity语法上相对FreeMarker要简单一些,不需要什么特定的标签,它只使用简单的$varName来输出变量,灵活度要较FreeMarker高一些。Velocity不支持其他标签库(即在Velocity中不能引用其他标签,如不能使用Struts的标签)。Struts2,提供了自己的标签库,更好的支持FreeMarker。

5 结语

FreeMarker和Velocity都是优秀的模板语言,分离了页面逻辑和业务逻辑,通过与Struts2的组合使用可以进行高效的工作。Struts2框架采用FreeMarker作为其默认的模板技术,同时对Velocity的支持性也是非常良好,是选择FreeMarker还是选择Velocity,程序开发人员可以根据实际项目中的需求,去选择对自己更加方便、快捷、高效的模板语言。

摘要:Struts2是一个基于MVC架构的框架,有许多视图表示形式。为了使Java Web的页面视图更好地与业务逻辑分离开来,引入了基于Java的FreeMarker和Velocity模板语言,这两种模板语言凭借着自身的优势在众多模板语言中广泛应用,使用FreeMarker和Velocity模板引擎技术,不仅提高了程序员的开发效率,还使得应用程序在较长的时间内具有良好的维护性。

关键词:FreeMarker语言,Velocity语言,模板引擎,Struts 2框架,Java Web应用

参考文献

[1]范立峰,林果园.Java Web程序设计教程[M].北京:人民邮电出版社,2010.

[2]南磊,译.FreeMarker手册.

[3]耿晓君,等.Struts2下基于FreeMarker的XML数据输出与ExtJS的解析实现[J].江苏广播电视大学学报,2009,(05):59-62.

[4]陈涛,白栩翔.Velocity模板引擎技术在Java Web中的应用[J].农业网络信息,2011,(05):38—40.

struts2源代码分析 篇3

关键词组织机构代码;现状;对策;分析

中图分类号TB文献标识码A文章编号1673-9671-(2011)021-0225-01

代码事业在我国已有二十年的历史,在全国代码工作人员的努力下取得了令人瞩目的成绩,但是代码事业要想更加深入的发展,满足日益快速的发展大中小企业的需求,就面临着严峻且强有力的考验。

1组织机构代码工作的现状和面临的挑战

1)法人基础信息库的确立给组织机构代码工作人员带来的挑战。国家信息化的发展要求法人库的确立,此项工作量大、面广、技术要求高,进度较为缓慢,其中的主要问题就是代码在法人库中的定位、流程、系统建设和协调等问题,如果这些问题解决不了,就无法保证法人库建设的正常进行,要代码介入到国家电子政务中去只能是纸上谈兵,只有极大力度把各项繁杂、细致的基础性工作做好,才有可能使得代码事业在较短的时间内有新的进展和突破。

2)提高代码的赋码率来满足应用部门的需求。目前,组织机构代码因历史和法律法规执行上的原因受到一定的局限,这是由于国家经济战略的调整,各种经济活动不断的涌现,从而也致使了代码赋码不全的问题出现,制约着代码工作的进一步发展。要拓宽赋码范围,提高赋码率,不仅是代码工作及时为各应用部门提供准确有效的基础信息,也为国家宏观经济调控起到重要作用。我们必须高度重视且努力认真的落实。

3)是立法问题。代码事业在发展中一直不断面临种种挑战,法人单位基础信息库工程建设仍然举步维艰、进展迟缓,最关键、最核心的原因就是组织机构代码至今尚未立法。由于没有法律的保障,部门间利益矛盾难以协调也就成了必然。事实上,随着法人单位基础信息库确立,相关部委和专家对代码有了越来越多的了解,对其重要性也有更深刻的认识,并对代码还没能立法也感到困惑。为此代码中心一直在坚定信心地全方位努力,将这一很有希望的事情抓紧抓好。

2代码工作必须努力奋斗的几个方面

1)加快法人单位基础的信息库建设的进程。代码工作的生命线在于能否在国家的信息化建设中担当重要角色,如果代码工作被国家的信息化工作边缘化,那么后果将不堪设想。不进则退,我们没有更多的考虑和徘徊余地。因此,我们将承受更繁重的工作,更艰巨的任务,在紧迫的时间里,必须重点做好以下几项工作:①加强于国信办、编办、工商、税务、民政和统计等部门的协调,在代码工作基础不受影响的前提下,求大同存小异,把法人库建设的进程推向实质性阶段;②利用专家组等各方力量,进一步做好方案的论证及完善工作,使其既能满足国家电子政务的需求,又能满足代码事业的长久发展;③做好法人库方案实施计划中的各项准备工作,在做好需求分析的基础上,抓好基础建设、技术装备的配置、软件的开发与系统管理;④做好各级代码管理机构法人库建设的指导与落实,在搞好调研的基础上,研究出实现法人单位基础信息库动态化实时管理的关键要素,形成更加完善的法人单位基础分信息库的动态采集维护管理系统;⑤代码中心要尽快完成代码管理信息系统的升级工作,完成计算机房的扩建与改造;⑥加强对代码工作人员的培训工作,要有计划地针对高级管理人员和一般工作人员进行不同层次、不同内容地培训,切实为法人库的建设、应用和维护打下良好的基础。

2)加强代码立法工作。组织机构代码立法仍是今年一项重要工作,而且是一件只能抓紧不能放松的工作。目前,已有近90%的代码管理机构都有地方法规可依,这为国家代码立法奠定了一个好的基础,因为这是一件大有希望的事,所以必须努力去做,早一天出台,我们的工作就早一天步入法制化正轨,法人库的建设就会早日做成,代码就能早日在国家电子政务和信息化建设中站稳脚跟。

3)提高代码库数据质量。应用是代码的生命,而推动代码应用的关键是数据质量。我们讲提高数据质量,不仅是几个应用部门的需求,更重要的是国家在电子政务建设中对基础信息的需求,是全面提高政府依法行政能力,加快建设廉洁、勤政、务实、高效的政府、促进国民经济可持续快速健康发展和社会进步的需求。代码在法人库中的定位向我们提出了挑战,而挑战的核心问题就是数据质量是否能经得起考验,这就给我们敲响了警钟:法人库建成后,代码数据与多个部门的数据可能共置于一个平台,使其更具透明度与可比性,这种资源整合的结果终究会以优质而胜出,以劣质而淘汰,可见代码的数据质量是代码事业生死存亡的关键。因此,对代码数据的准确性、规范性和完整性,我们必须给予高度重视,切不可掉以轻心。

4)进一步加大推广应用的力度。组织机构代码工作能够得以不断发展,推广应用是生命。法人库建设进程给代码的推广应用工作提出了更艰巨的任务。今年,代码中心一方面要努力抓好法人库建设中与各参与部门的协调工作,另一方面,要继续深化代码在银行、外汇、社会保障、公安车辆管理和质检部门的应用,尤其是要通过与银行和外汇部门的数据核对,核查清理问题数据和沉淀数据。各地方代码管理机构要充分重视此项工作,积极配合国家代码中心做好清查工作,以提高代码数据库信息的整体质量,为各应用部门提供满意的服务。

5)完善个体户赋码。完善个体赋码,是代码在国家经济实现金融监管、税源监控应用中的一个重要需求,也是代码拓展自身事业,适应更广泛的应用一个重要环节。今年3月11日总局下发了《关于向个体工商户颁发组织机构代码证书有关问题的通知》,通知对在向个体户赋码中的法律依据、颁证原则和有关注意事项都做了规定,望各地要认真贯彻执行,既保证赋码的合法性,又要保证应用部门的数据真实性与完整性。个体工商户赋码牵涉的问题较多,政策性又很强,做好了对代码的应用将产生巨大的影响与推动。因此必须注重二个方面:一是严格政策,在自愿的基础上对符合条件的一定要赋,否则不赋;二是实施代码区段单独管理,杜绝码段混用和重错码现象发生。

6)加大培训力度。国家信息化的不断发展,给代码工作不断提出了新要求,同时,也促使代码工作不断产生新的变化,包括政策性、技术性、管理性等等。变化是客观存在,只有适应变化才能进步,怎样适应?最根本的还是靠人,没有一批能够适应变化的人,代码工作就没办法做好,几年来不管代码中心还是各地代码管理机构在培训上都做了很多工作,但仍不能满足代码工作的发展要求,代码工作有些问题的产生,就是因为人员素质没能达到要求而产生的,所以,人员加强培养工作一定要抓紧、抓好、抓出成效。

3结语

国家信息化的不断发展,给代码工作不断提出了新要求,同时,也促使代码工作不断产生新的变化,包括政策性、技术性、管理性等等。变化是客观存在,只有适应变化才能进步,培养一批能够适应变化的人,各地代码管理工作才能获得良好的成效。

参考文献

[1]刘晓平.提高代码质量.拓宽应用领域[J].学理论,2010,09.

Struts2习题 篇4

标识、可以、如果没写,说明该包为默认空间 2.Action 的实现通集成常用那种方法? 一种是直接实现自己的Action 另一种是实现Action的接口 继承ActionSupport 3.不属于Struts2的动作类的常量返回值的是(C)

A.success

B.input

C.never

D.login 4.以下不属于Struts2动作执行的结果类型是(A)a.action b.redirect c.redirectAction d.dispatcher 5.在struts.xml中。假如在一个package中没有配置namespace,那么在其中配置一个Action名字叫做login,它的result是这样配置的/login.jsp,已知在此配置文件中还有另一个name为user的package其中也有一个Action名字为login,它的result是这样

配置的/loginUser.jsp那么在以下什么情况下将能访问到login.jsp

A A.在根路径后输入/login B.在根路径后输入/user/login C.在根路径后输入/login/user D.在根路径后输入/abc/login 6.正规开发中,在使用struts2时定义Action使用哪种方式。B A.直接定义Action类。B.从ActionSupport继承。C.从Action继承。D.实现Action接口。

7.不同的线程在调用Action时创建几个Action实例。C A.1个 B.2个

C.每个线程创建1个。D.可以自定义配置。

8.struts提供了Action接口定义了5个标准字符串常量,不包括的有(C)A SUCCESS

B NONE C REG D LOGIN

9.列举出action执行结果类型,并说明用途。

默认结果类型是dispatcher chain:Action链式处理的结果类型,也就是将结果转发到这个action中。

dispatcher:用于整合JSP的结果类型

redirect:实际上dispatcher和redirect的区别就是在于转发和重定向的区别。

redirect-action:重定向action 10.struts2中result-type的chain和redirectAction的区别 chain,它是一个琏式的,是从一个Action转发另外一个Aciton redirectAction,是从新请求一个Action 11.action的class里面写的是什么? Action相应类的详细路径

12.action的extends里面调用的是什么?

从另外一个包继承、相当于拥有即承包的所有配置

13.如果不写action的后面mothod,默认的调用的方法是什么,如果写的话,写的时候有什么需要注意的?

不写会默认调用最上面的方法

14.输出值的strtus标签是什么?

s:property

15.循环的struts标签是什么?

s:iterator

15.判断的strtuts标签是什么?

s:if

16.显示文本的strtuts标签是什么?

17.请简述前台提交后是如何到达后台action的。

通过form表单action找到struts配置文件相应action的类 再去找相应action类里的方法

Struts2习题2

一、填空题

1.Struts2框架由___________和___________框架发展而来。(Struts&WebWork)2.Struts2以___________为核心,采用___________的机制来处理用户的请求。(WebWork,拦截器)

3.Struts2中的控制器类是一个普通的___________。Class或填过滤器类

二、选择题

1.不属于Action接口中定义的字符串常量的是___________。B A.SUCCESS B.FAILURE

C.ERROR D.INPUT 2.在控制器类中一般需要添加相应属性的___________和___________。AC A.setter方法 B.as方法 C.getter方法 D.is方法 3.控制器需要在___________配置文件中进行配置。B A.web.xml B.struts.xml C.struts2.xml D.webwork.xml 4.不属于Struts 2表单标签库的是___________。D A. B. C. D.

struts2源代码分析 篇7

关键词:java源代码,缺陷分析,系统设计

前言

缺陷分析工作是提升java系统运行效率的关键方法,在一般的源代码运行系统中,只有具备系统管理能力的客户才能够通过登录的方式实现对缺陷分析系统的控制,一般情况下,正常的用户在实施缺陷分析系统的运行过程中,不能够了解源代码问题的分析方式,因此,设计并完善java系统的分析方案,对提升Java系统的运行质量十分重要。

1 Java系统缺陷分析过程的主要管理手段

1.1 不同种类系统缺陷方式的管理手段

Java系统的缺陷模式分为很多种类,正常通过登录方式实现系统管理的客户只能够对正规渠道的缺陷模式实施分析,在不能正常实现系统分析的状态下,客户需要及时对已经存在的Java系统缺陷实施删除处理,并且及时对已经出现缺陷状态的Java系统实施主要信息的收集,以便能够对信息当中造成系统瘫痪的主要原因实施修正处理[1]。在处理不同方式的系统缺陷当中,可以使用新型系统处理的方式对已经存在问题的系统实施增添式处理,以便系统的使用者能够在进行缺陷系统的运行改造中实施管理模板的调整,并根据正常的添加程序对已经设计完成的系统调试方案实施处理,使存在缺陷问题的系统能够尽快恢复正常。要从分运用不同形式的JAVA语言形式对出现的缺陷模式实施控制处理,使需要进行添加处理的Java程序能够更加便捷的进行新系统的录入,提升缺陷问题方案的执行效率。

1.2 Java系统缺陷问题的含义分析

在实施系统问题的处理过程中,需要对现有系统的信息方式进行考察,实施源代码分析的系统必须为标准的Java形式的系统,并且保证运行的基础性编码为代码状态,以便不同形式的系统能够根据不同使用模式进行文件的填充,如果操作能够及时的找出不同种类的java文件,则需要根据统一形式的处理信息实现不同缺陷问题的处理。要根据已经设计完成的系统删除处理,对存在源代码问题的部分系统实施删除处理,当系统已经发现存在缺陷问题的状态下,需要对存在突出问题的局部系统实施标注处理,并对存在问题的系统名称实施控制处理,要在运行删除系统之前,做好系统缺陷模式的备份工作,并严格按照既定方案的要求对存在缺陷的系统实施逐一处理,以便系统的运行效率不会因源代码的问题受到影响。

1.3 实施Java系统缺陷模式的模板分析

要在系统当中存在个别案例的状态下对已经出现的窗口实施控制,并在不断出现的窗口中寻求源代码缺陷问题的分析方案,对缺陷问题的相关信息实施调查,以便新窗口能够对源代码的缺陷问题进行系统性补救,当操作人员已经能够全面的对源代码运行过程中的编辑器实施控制,则需要对造成系统问题的信息实施管控处理,以便不同种类的管理问题能够按照既定的方式实施编辑系统的转化,在对已经出现问题的缺陷系统实施管理的过程中,需要对不同运行方式的系统状态实施传输处理,以便存在系统缺陷的问题装置能够通过整合的方式实现运行模式的自动调整[2]。操作人员需要对系统运行过程中的缺陷问题进行统计,整理形成系统的缺陷模式整理方案,以便不同种类的文件可以实现缺陷问题的全方位控制,提升系统操作的合理性和科学性,要合理的对已经出现缺陷问题的方案实施更高水平的调整,以便不同种类的Java系统问题能够通过对源代码问题的处理得到根本层面的解决。

2 从源代码分析方面制定Java系统分析方案

2.1 系统源代码整体结构的分析和实践

在对源代码实施分析的过程中,操作人员要注意科学的选择系统的分析方案,如果Java系统在运行过程中可以同SVN系统实现对接,则需要对系统已经出现的缺陷和需要实施共享的代码进行处理,以便系统能够通过对用户名和运行密码的处理实现对地址的共享。要在分析Java系统运行问题的过程中,对正在使用的源代码实施质量问题的监控,并且根据源代码运行过程中的主要方向实施源代码地址文件的选择,以便不同状态的运行文件能够在统一的运行方式中得到认同,要根据正确的流程进行源代码的改造,如图一所示,通过标准的源代码修改流程,对不同系统的源代码具体数据实施全面的调整,以便得到正确的结果。要通过系统分析的方式对已经产生的系统问题进行整合,如果缺陷问题存在于不同系统分支的开端,则需要对不同文件的编码和段落实施系统的处理,当系统能够对存在缺陷问题的源代码质量进行等级区分的时候,操作人员需要对不同主要程度的代码实施颜色的标注,并且保证每一位用户能够通过对系统当中的基础性要素进行自由的调整,提升系统运行过程中的字迹质量,如果系统的运行人员不需要对字迹的处理方式进行控制,操作人员需要对系统运行过程中的信息实施顺序的调整,以便系统的使用者能够通过对系统编码的控制实现问题的避免。系统的操作人员要注意及时调整系统运行当中的方案,通过对不同种类的信息问题进行排序,降低系统在运行流程中的质量问题,以便系统能够在辨别源代码的过程中对存在错误信息的段落实施规避处理[3]。系统在运行过程中还要注意对不同位置的Java信息系统进行关键信息的采集,根据系统弹出的对话框对系统的运行区间进行判断,并提前做好详细信息的解决对策,以便系统的缺陷信息能够通过对话框的显示信息进行调整,升级系统缺陷模式的处理能力。

2.2 源代码缺陷问题的管理方式

要在处理系统缺陷问题的过程中,对导致缺陷模式的主要原因进行详细的分析,如果实时分析的系统能够更加快捷的对记录当中存在的缺陷问题实施控制,则需要对不同窗口状态下的系统缺陷问题进行解决,以便系统运行当中的质量问题能够对运行错误进行全面的调整,要对系统实施分析的不同报告进行错误原因的判断,根据缺陷问题的产生原因以及模式运行过程中的详细信息,对报告当中的问题进行原因的判断,以便不同种类的错误信息能够在提升系统错误分析能力的基础上保证系统的运行,使Java系统不会是缺陷模式的处理过程中出现暂时性的崩溃。要在处理系统的过程中进行系统分析报告的设计和统计,以便系统出现缺陷问题的根本原因能够在分析当中得以控制。要使系统的操作人员能够通过对系统报告的分析实现系统错误的更正,如果系统的错误能够在列表均等的状态下实现不同种类问题的集中处理,就能够通过对源代码的分析和相关文件的删除实现系统编程过程中问题的避免,以便系统能够从提高细节控制力方面避免系统的缺陷。

3 缺陷分析系统的具体实现方式

3.1 Java系统缺陷问题的精准测试

在实施java运行的过程中,操作人员需要对管理人员的运行过程中的问题进行规避,如果系统的管理人员能够对系统存在缺陷的方位实施大幅度删除处理,则要对需要实施删除处理的部分系统规划方案进行集中管理,以便系统能够提前实施精确的方位测算,要根据一般情况下用户使用测试模块的习惯对进行测试的方位实施了解,根据不同种类测试手段对需要进行测试的系统实施运行流程的控制,要在实施系统停滞状态的处理之前,对系统运行过程中的信息处理方式实施准确的控制,并根据不同形式的信息测算平台对信息测试手段进行调整,在实施缺陷问题测算的过程中,系统的操作人员需要对系统的基础方位进行全程跟进,并且通过对系统生成报告的分析制定相关问题的调整方案,使系统能够从基础形式方面对测试手段实施调整。

3.2 全方位控制Java系统的运行信息

要保证系统在进行测算的过程中对已经出现的问题进行信息的控制,以便信息能够从精确测算的方案上对名称等关键性要素进行信息取证。在进行系统基础性文件的摘录过程中,要根据不同方式的类型文件对Java系统实施缺陷状态的测试,以便操作人员能够及时对系统存在的源代码问题进行删除处理,从多个方面保证Java系统的运行质量。如果操作人员在运行操作系统的过程中发现系统存在同规划处理方案不同的问题,则需要对精确的系统测算报告进行处理,使系统能够利用基础报告提升系统的测试质量。要保证操作人员能够在进行系统信息输入的过程中进行系统报告质量的检测,通过对不同测试标准的考核实现系统的输入方式上的调整,当系统能够对进行输入处理的系统文件进行良好归纳的状态下,系统操作人员要及时停止不同方位的系统测试进程,并根据已经产生的系统缺陷报告对系统的调试流程进行科学的设计,使操作人员能够根据新型系统测试标准对系统已经出现的信息进行控制。在进行系统操作的过程中,需要加强对Java文件的关注,如果Java文件能够提升系统的精确度,则需要对系统已经删除处理的部分进行收集整理,避免不同标准的系统删除方案影响系统的运行质量。运行团队要根据系统源代码的具体属性对输入信息进行分析和分类,并且采取集中方式对不同情况的系统缺陷实施检测报告的总结,以便系统的操作者能够根据源代码的具体情况进行删除系统的设计,提升系统运行过程中的测算质量,要按照系统对话框的信息对系统源代码的具体情况结合文件名称进行分析,以便分析工作能够拥有更加完善的资料基础,当系统的文件存在名称相同的问题时,操作人员要对文件名称进行标识处理,并提前进行系统文件备份检测方案的制定,以便系统能够正确的运行标准基础测算流程,按照文件的主体信息实现Java系统的操作,从根本上避免由于文件名称标识所导致的系统问题。

3.3 根据模型实施缺陷分析系统的调整

首先,操作人员需要根据Java系统运行过程中的具体问题进行问题解决方案模型的建立,以便系统能够从调整登录形式方面避免系统缺陷问题的产生,如果系统在运行过程中出现运行方案调整方面的问题,要充分使用系统运行模式的删除系统对不同运行质量的层面实施调节,使系统能够在应对缺陷问题的过程中具备充足的系统管理基础。系统的缺陷问题的治理过程中需要注意对已经出现质量问题的系统传输形式进行调整,使系统能够根据相同的下载模式实施缺陷问题主题规避方案的查询,并通过对系统缺陷规则的处理实现系统在使用过程中的处理,以便系统能够在处理Java源代码的过程中实现输入信息的管控。要保证系统的运行过程中不出现缺陷问题,需要实施系统使用方的处理力度,要保证每一位处理人员充分参考系统的编程漏洞,进行系统缺陷问题的分析,并通过调整源代码的运行方式促进系统新型测试标准的建立,以便系统能够尽快做出缺陷方面的显示,根据系统的删除标准实施系统的调节,使系统能够根据参数的调整情况实现系统运行方案的明确。

结论

对Java源代码方面的缺陷问题进行深入的分析,并根据实际情况制定出这一缺陷问题的正确的解决方案,对提升Java系统的运行质量,总结经验,避免缺陷问题的再次产生,具有十分重要的意义。Java系统开发质量的提升很大程度上有益于系统设计与开发领域未来的发展。

参考文献

[1]战德臣,王忠杰,徐晓飞.面向企业资源计划全生命周期的建模方法及工具[J].计算机集成制造系统,2014,09:1345-1351+1373.

[2]陈翔,陈继红.回归测试中的测试用例优先排序技术述评[J].软件学报,2013,08:1695-1712.

破译源代码 篇8

当你听到“数据分析师”这个词的时候,脑海中第一时间出现的画面会是什么?会是乔纳·希尔在电影《点球成金》中所演的那个分析师彼得·布兰德的形象吗?

你知道研究数字的人都是书呆子型的,那种人整天坐在电脑面前,吃着外卖快餐,并且没有时间更没有意愿来打点自己的仪容。那种人也许会剪个头发,但是不会花费超过10块钱去剪掉它们。那种人从来不会穿一条合身的裤子,也不会穿上一件得体的衬衫。好吧,你说的那种人只是《点球成金》中的彼得·布兰德,那可不是真正的汤米·贝尔塞提斯。

掘金队1.95米的数据分析师可以用ZZtop的一句歌词来形容:他是一个穿着讲究的男人。从他的精干整洁的头发,到他的卷着袖口量身定制的礼服衬衫,闪闪发光的银色手表,黑色的腰带,木炭色的熨烫裤子,甚至是带有设计图案的靴子,都会让你感觉到——他会把自己的想法放到每一件事情当中,尤其是他的工作。

“运用分析你可以做很多事情。”贝尔塞提斯说,“那纯粹取决于分析资源、分析时间和所分析的人物。这就是我的工作:指出我们要做的主要任务。”

有汤米做指导的时候,大家很容易进入到他的思想当中。但是不要进去太久了,当他允许大家用洞察力去探索他的世界时,他的任何秘密也许就会泄露出来。

“当有的人阅读我的思想的时候,我并不想泄露我们的战术或者一些类似的相关事情,”贝尔塞提斯说,“但是同时,我们希望我们的球迷能了解我的想法。我们有一个积极的管理层,这是我非常高兴的事情。我们知道数据分析只是成功的一块拼图。我们所做的决定就像是一棵大树,而数据分析只是一个小分支。我们需要用很多的视角去观察比赛,球探的视角、退役球员的视角、蒂姆·康奈利(2013年掘金队新上任的篮球运营部副总裁)的视角——要知道,他来NBA并不久,所以我们会有很多不同的视角,而我能给的就是数字的视角。”

“当我接到蒂姆给我打的电话时,我说‘给我一天的考虑时间。’”贝尔塞提斯说,“但是很快的我就知道自己想要来这里(掘金队)。”汤米是土生土长的立陶宛人,他从7岁开始打篮球。“我不认为在立陶宛有比篮球更重要的事情。”汤米说。“有一部电影叫做《另一支梦之队》,我们的助理总经理阿特拉斯·卡尼瑟瓦斯在那部片子里出演。立陶宛的篮球已经相当强大了,我们真的不需要美国的梦之队在电影里出演。”篮球在上世纪30年代扎根于立陶宛,当然也扎根于汤米的心中。

尽管贝尔塞提斯在掘金队只有一个工作,但他总是在组织中扮演不同的角色,让自己保持忙碌状态。

“我所做的最重要的事情就是把赛前和赛后的报告交给教练。”贝尔塞提斯说,“这就是一些在惯有的基础上,用数据来指导球队的东西,而且他们做的非常好。”

赛前和赛后报告

“我给教练做的赛前报告,是从本质上描绘出我们要交手的球队的大体情况,而不是给出最基本的数据。”汤米说,“事实上我根本不会提交最基本的数据,因为那些东西在网上就能查到。我的报告是关于对手愿意在哪里投篮,他们五个人中哪个位置不太擅长防守,他们是否喜欢投底角三分球,在中距离处他们是否善于防守等等。所有的这些东西都是非常有用的,所以我会把它们总结一下。”

“之后我会指出一些关键球员。看球员的比赛录像是非常有用的,有些时候能从数据中看到一些很明显的事情,但是大家可能并不注意到它。”贝尔塞提斯说,“所以,我会根据分析做出一份报告。我们怎么去防德里克·罗斯?怎么去防凯文·杜兰特?有时候你会对他们束手无策,但是至少能从某种程度上知道他们不太擅长什么。差之毫厘,谬以千里,如果我们能在这激烈的竞争中得到额外的一点点优势的话,那么我们就会有更大的几率去赢得比赛。这就是我要做的事情。”

“我去过马修利奥尼斯篮球学院,是前NBA著名立陶宛球员萨鲁纳斯·马修利奥尼斯在美国开办的。”贝尔塞提斯说,“10年前我在他的学院学习,在那里和一些国家青年队队员打球。”是的,汤米在18岁的时候离开了立陶宛,来到美国追求自己的篮球梦想。他在马修利奥尼斯篮球学院打得非常出色。随着他的高中篮球生涯结束,他意识到自己需要做出一个决定。“我总是要确定一下,自己应该有一个备用的计划,如果我以后不打篮球干什么?我知道这是个非常好的机会,所以我就选择了做数据分析。”

汤米会把赛前报告交给布莱恩·肖,之后肖会根据这些报告上的信息来安排比赛战术。“汤米每天都会给我提供一份报告,他会告诉我在球场上哪个位置我们的进攻最有效,对手在哪个位置上最有效,在“热区”我们应该得到多少分,对手的两分球、底角三分球的出手几率是多少……”掘金主教练布莱恩·肖说道;“这样就做到了知己知彼,也就相当于我们可以预测到比赛的走向,有了这些似乎一个外行人也可以安排战术了。”

“汤米有他的工作,统计数据并且分析数据。而我也有工作要做,投篮并且帮助球队取得胜利。”掘金队的进攻后卫兰迪·弗耶说,“数据绝对不会说谎,但是我并不会注意那个,因为打比赛是要用心去打的。”

也许弗耶不会注意数据,但是事实上,他和他的队友们都从贝尔塞提斯提供的数据中获益。这就是“比赛计划”。

“我每天都是跟着直觉打比赛,也按照教练给大家安排的比赛计划去打球。”掘金前锋威尔森·钱德勒说道:“教练们会给大家安排一个相当棒的比赛计划,他们指出每个队员身上的优势和劣势,而且这会让自己更好地去审视自己。好的球员在球场上能把每件事都做得很好,所以你得试着让他们做一些不太擅长的事情,但是对于他们来说,还是能进球。因此你要想方法让他们用最难的方式进球。就像杜兰特,他是一个很强的对手,总能进好多高难度进球。有的时候你已经防到位了,但他还是可以得分,所以你得一次又一次地尝试去防住他。”

钱德勒在讨论“尝试着把球员限制在他理论上较弱的位置上”的时候,说到了关键的东西。有时候,即使是最好的信息也不会帮助你指出应该在球场上做什么。

“你会告诉我们,如果你能把詹姆斯和韦德限制在油漆区外的话,你就有很大的机会去打败热火……好吧,那是信息里提供的东西,假如你在场上真的那么做的话,后果可想而知。”肖说,“能把理论信息结合到在球场上你要防守的实际球员身上,就像现在社会的婚姻问题一样。”

当比赛结束后,看着比赛结果回想刚刚发生的事情,教练组是否真的运用到这些所提供的信息,才是关键。

“关于把理论的数据结合在实际球员身上,这个事情我确实做了不少,”贝尔塞提斯说,“不过有些球员真的让人很苦恼。例如杜兰特,如果我们按照理论数据去限制他的话,在事实上那根本就不起到作用……我只能说,数据分析只是一种版本的事实,它也许并不会100%正确,但是我敢肯定,它不会100%错误。”

“赛后报告是用来总结赛前报告和我们的比赛的。”贝尔赛提斯说道:“球队的有些目标可以通过教练组安排战术来完成,我们需要确定从进攻和防守两端都达成目标。”

开明的教练给了他机会

贝尔塞提斯毕业于哈佛大学,有经济学和物理学双学位。“在哈佛,每个人都很坚强,因为那里的压力很大,尤其是进入那些更成熟的行业,如银行业和咨询业。”贝尔塞提斯说。“从哈佛毕业的人从来没有把目标行业定为体育行业的,至少我不这么认为。”不过,他却很想去体育界工作。因此在大三的暑假,贝尔塞提斯去了纽约参加了一份在NBA实习的工作。但是毕业后贝尔塞提斯接受了一份咨询行业的工作,而不是他想从事的NBA相关的事情。不过在工作中他学会了不少统计和分析的技巧和经验。可是,他希望能够从事篮球行业的梦想,始终在他心里像火一样地燃烧着。

“我喜欢数据。”布莱恩·肖说道:“对我来讲,学会如何去理解你所得到的信息才是关键。在那之前,包括我在内,许多传统学校的教练们不把它当回事,是因为他们没有在电脑时代长大。我相信,数据分析已经是篮球比赛的一部分,而且永远都是。”

“从传统篮球角度来讲。”肖说:“在防守的时候我们不用出油漆区,我们会让对手随便投底角三分球,我们在防守的时候不能去犯规……不过数据分析会告诉我们,这些事情都是错误的。”

有人认为,NBA教练不会去听从一个27岁的数据分析师来改变自己的战术,指出自己球队的优缺点的。

“我觉得让他们相信我,这并不难。因为我打过篮球。”贝尔塞提斯说,“这不像我来自一个完全陌生的统计学校,给他们扔一大堆数字烟幕弹。我知道篮球比赛是怎么打的,而且我并不会完全干涉他们的战术,因为他们是教练,他们做出大的规划,不过同时,我只做一点点小的改动,因为我比他们更了解数据。所以,如果你愿意,这就像是一个完美的配合。”

“教练组已经很出色了,我不会过多的强调他们有多开明。”贝尔塞提斯说,“我希望他们能用到我总结的东西,我也被告知他们的确在用,这是非常棒的。不过与此同时,我知道数据并不代表着一切。有的时候,我给出的数据是这样的,但是他们却安排了完全不同的战术,所以我从来不会很任性。因为我知道,在我的报告中总会有某些东西能帮助到他们……这就是我的工作,能给球队带来额外的几率去赢得比赛。”

在一个82场常规赛的赛季中,总结赛前和赛后报告会占据贝尔塞提斯的大部分时间。不过当休赛期的时候,他会把时间用到球队办公室项目中。

在两年的咨询工作后,汤米觉得自己的经验已近足够了,他决定继续追寻自己的梦想:篮球。所以,他做出了一些必要的牺牲,放弃了轻松的工作,来到伦敦为NBA工作——向国际市场卖NBA转播权。刚刚工作两周之后,大概在2012年八月,他出差到莫斯科,这次偶然的机会改变了他的职业生涯规划。“我在那认识了蒂姆·康奈利。”贝尔塞提斯说,“我们谈了很多关于篮球的东西,他说:‘为什么你在做销售工作?为什么你不从事一份和篮球更相关的工作呢?’我说:‘呃,我有经济学背景,我觉得这就是适合我的工作。’他说道:‘你应该考虑一下离篮球更近一些。’之后我们一直保持联系,当他为掘金工作后,他给我打电话,看看我是否想要加入他们。”

给掘金队的总结

“我们尝试去追踪球员们的成长。”贝尔塞提斯说,“我们想要知道他们去年打得怎么样,今年打得又是什么样,差距在哪,进步在哪。这就是纯粹的数据分析透视法。教练们每天都和球员一同奋战在战壕里,他们知道球员是怎么想的,他们一心为着球员。而我做什么呢?我要盯着数据。例如,是否有某人不像去年投篮那么准了,为什么会出现这种情况?他们是在自己不擅长的区域出手太多了吗?我就是要看着这些东西,有的时候数据是非常真实的。我会和教练分享这些数据,之后教练会根据数据做出自己的计划。”

正如汤米之前提过的那样,教练们的决定就像是一个大树,而他的工作只是树上的一个分支。他能为球队做出更有用的决定提供支持。他在工作中也需要观察联盟中的其他球员,看看哪些球员更适合掘金队的体系,以至于在未来能和掘金队签约。

“数据分析可以被用在很多方面,因为它是一个广泛的工作。”贝尔塞提斯说,“我做了一系列的项目——例如统计和分析球队能打进季后赛的百分比。有些东西已经在网上可以找到了,但是我们要有自己的观点。我们会把自己的预测和最终的实际情况作出比较,我们也会注意观察联盟中的其他球员,而且我们也关注选秀。只要在NBA中可以去分析的东西我们都会去做。当然,也会去分析其他队伍的球员。要不断地去尝试让我们的队伍变得更强大,之所以运用分析就是为了这个。”

“在数据分析中,有一些对球队的分析:我们的速度是否足够快,我们的进攻节奏是否合理,”贝尔塞提斯说,“现在我们已经打出相当快节奏的比赛了,我们是要继续这么高速打球吗?还是我们需要改一改?在过去的10年里是否有一支高速打球的球队赢下了比赛取得了成功?他们的速度有我们快吗?”

丹佛掘金队年轻的数据分析师还兴奋的告诉我们:“在我九岁开始,阿特拉斯·卡尼索瓦斯(前立陶宛著名篮球运动员)成了我的偶像。我总是穿12号球衣,因为他就是12号。我们也打相同的位置,有些人真的会拿我和他进行比较。我的教练总说:‘像他一样打球。’我会说:‘我会努力做到的。’然后,在我大一的时候,我见到了他,那太美妙了!我们一直保持联系,而且还变得很亲密。这是一个很有趣的故事,我在阿特拉斯来掘金之前得到了这份工作。蒂姆给我提供了这份工作,我接受了。两天之后,蒂姆又给我打电话:‘我们有了一个新的助力总经理,是阿特拉斯。’太不可思议了!能和自己的偶像一起工作太酷了!那种感觉是无法用语言来形容的。在训练的时候,我们总是进行投篮比赛,不幸的是,我从来都没赢过他。我希望有一天我能打败他,哪怕一次也行。他总是那个我一直要去学习的人。”

SportVU技术——运动追踪摄像机

随着SportVU技术——运动追踪摄像机的出现,越来越多的数据可以被贝尔塞提斯所利用了。球队就能知道哪些球员善于接球投篮,当被双人包夹时进攻球员会怎么做,球员把球控在手中的时间有多少,等等。棘手的问题是,如何利用这些数据来帮助你的球队。

“在篮球场上,每一个动作都会受到另外九个人的影响,而不是教练的决定。”NBA著名评论员克里斯·布拉德说。掘金队怎样才能确定哪个球员会更适合他们的体系?你敢说那些“从数据上看很适合”的球员,来到掘金后一定会打得很好吗?

“拥有这项技术的确是非常好的事情。”贝尔塞提斯说,“这项技术的优势越来越明显了。不过,数据专家和球迷们很容易被各种数据弄混头脑。你需要在繁多的数据中找到你想要的,然后从中做出总结。这当然比没有数据要好。同时,我们从这项技术中得到的数据太多了,不能只用到某些单独的数据,这是非常复杂的。所以现在的所有人都在这项技术中不断探索,希望能找到更好的方法来帮助大家,我们也不例外,始终在不停地摸索。现在我们已经有一些成就了。”

毫无疑问,每个球队都想能更好地运用这些数据,这种竞争肯定存在。但是现在还没有一个组织可以把每支球队里的数据专家召集在一起来互相讨论,不过贝尔塞提斯认为如果可以有这样的一个组织,那会很有意思。

“确实没有一个组织,但是我觉得应该有一个才好。我认识一些人在为别的球队做数据分析。要知道,每个人都想找到最好的方法来帮助球队,所以就会有很多机密的事情,因此我们并不能把自己的方法和大家分享。不过我们互相都很友善,很明显我们在某种方面讲是同事,但同时我们也在相互竞争,同行是冤家啊。”

上一篇:华东师范大学行政规章制定程序规定下一篇:《金刚经》简介