首页 文章 精选 留言 我的

精选列表

搜索[Vite构建],共10000篇文章
优秀的个人博客,低调大师

详解Dialog(二)——有关列表的构建

一、普通列表 普通列表的样式是这样的: 要实现这样的列表样式,是通过下面的方法来实现的: [java] view plain copy builder.setItems(CharSequence[]items,DialogInterface.OnClickListenerlistener) builder.setItems(intitemsId,DialogInterface.OnClickListenerlistener) 这两种方法实现的效果都是一样的, [java] view plain copy setItems(CharSequence[]items,DialogInterface.OnClickListenerlistener) 这个items传进去的是一个字符串数组; [java] view plain copy setItems(intitemsId,DialogInterface.OnClickListenerlistener) 这个传进去的一个itemsId,是在XML中定义好的一个字符串数组资源的ID; 下面,我们一个个看看他们的具体用法: 1、字符串数组 下面是上图是实现上图效果的代码: [java] view plain copy String[]mItems={"item0","item1","itme2","item3","itme4","item5","item6"}; AlertDialog.Builderbuilder=newAlertDialog.Builder(MyActivity.this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("使用列表字符串"); builder.setItems(mItems,newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialog,intwhich){ Toast.makeText(MyActivity.this,"clicked:"+which,Toast.LENGTH_LONG).show(); } }); builder.create(); builder.show(); 可以看到首先构造一个mItems数组,然后在buidler.setItems直接传进去就好了。至于DialogInterface.OnClickListener(){}函数就是对点击事件的监听,which表示当前点击的是哪个ITEM的索引。 2、字符串资源ID 首先在xml文件夹下建一个字符串资源XML,命名为:array.xml,位置如图: 然后定义一段字符串数组: [java] view plain copy <?xmlversion="1.0"encoding="utf-8"?> <resources> <string-arrayname="dialog_items"> <item>王菲</item> <item>王力宏</item> <item>帅哥</item> <item>美女</item> </string-array> </resources> 下面就是利用SetItem来生成列表了: [java] view plain copy AlertDialog.Builderbuilder=newAlertDialog.Builder(MyActivity.this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("使用ResourceID"); builder.setItems(R.array.dialog_items,newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialog,intwhich){ Toast.makeText(MyActivity.this,"clicked:"+which,Toast.LENGTH_LONG).show(); } }); builder.create(); builder.show(); 在这里的SetItems时直接将我们字符串数组的name直接设置进去,出来的效果就是这样的: 二、单选列表 单选列表的样式是这样的: 要实现单选列表,主要是通过下面四个其中之一来实现的: 方法一: [java] view plain copy setSingleChoiceItems(CharSequence[]items,intcheckedItem,DialogInterface.OnClickListenerlistener) 与上面一样,传进去一个字符串数组,和初始化时选中的ITEM,构造一个单选列表 方法二: [java] view plain copy setSingleChoiceItems(intitemsId,intcheckedItem,DialogInterface.OnClickListenerlistener) 同样,与上面的例子相同,这里传进去的是一个字符串数组的资源ID,字符串数组的构造方法与上面相同,就不再赘述 方法三: [java] view plain copy setSingleChoiceItems(ListAdapteradapter,intcheckedItem,DialogInterface.OnClickListenerlistener) 这 个方法是最难理解的方法,因为这里的ListAdapter并不能是普通的Adapter,不信你传一个Adapter,保证出来只是你自己的ITEM视 图,旁边的单选按钮却出不来,其实这里的Adapter只是重写单选按钮旁的文字的样式,并不支持所有的Adapter,这个我会在本文最后讲述。方法四: [java] view plain copy setSingleChoiceItems(Cursorcursor,intcheckedItem,StringlabelColumn,DialogInterface.OnClickListenerlistener) 这里通过传进去一个Cursor来构造对应的字符串数组,可以是数据库Cursor,也可以其它系统自带的数据Cursor,但基本上用不到,就不再讲了 好了,关于方法三,因为下面会接着讲SetAdapter的知识,所以这部分我留在最后再讲,这里先讲下方法一和方法二: 方法一和方法二,与上例没什么区别,下面我就以方法一以例来讲讲上面的效果图是怎么实现的吧: 代码如下: [java] view plain copy String[]mItems={"攻","受","全能型","不告诉你"}; AlertDialog.Builderbuilder=newAlertDialog.Builder(MyActivity.this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("你懂的"); builder.setSingleChoiceItems(mItems,0,newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialog,intwhich){ //TODOAuto-generatedmethodstub Toast.makeText(MyActivity.this,"clicked:"+which,Toast.LENGTH_LONG).show(); } }); builder.create(); builder.show(); 很简单,构造一个mItems的String字符串,然后直接传进去setSingleChoiceItems中,默认选中第一个,即索引是0的项。 三、多选列表 先看看效果图: 自带的多选构造函数有如下几个: 方法一: [java] view plain copy setMultiChoiceItems(CharSequence[]items,boolean[]checkedItems,DialogInterface.OnMultiChoiceClickListenerlistener) 一样,传进去一个ITEMS数组和对应的项目的选中与否状态的数组; 方法二: [java] view plain copy setMultiChoiceItems(intitemsId,boolean[]checkedItems,DialogInterface.OnMultiChoiceClickListenerlistener) 这里传进去的是一个字符串数组,与第一部分相同 方法三: [java] view plain copy setMultiChoiceItems(Cursorcursor,StringisCheckedColumn,StringlabelColumn,DialogInterface.OnMultiChoiceClickListenerlistener) 同样,这里传进去的是一个CURSOR,可以是数据库的指针,也可以是系统自带数据的指针,基本不怎么用,就不讲了 下面以方法一为例看看多选列表的构造过程: [java] view plain copy String[]mItems={"经常犯二","傻叉一枚","逗逼","小清纯","沉稳大叔","有时可爱"}; AlertDialog.Builderbuilder=newAlertDialog.Builder(MyActivity.this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("性格类型"); builder.setMultiChoiceItems(mItems, newboolean[]{false,false,false,false,false,false,false}, newDialogInterface.OnMultiChoiceClickListener(){ @Override publicvoidonClick(DialogInterfacedialog,intwhich,booleanisChecked){ Toast.makeText(MyActivity.this,"clicked:"+which,Toast.LENGTH_LONG).show(); } } ); builder.show(); 这里构造了两个数组,一个是字符串数组,另一个每项对应是否选中的boolean数组 [java] view plain copy String[]mItems={"经常犯二","傻叉一枚","逗逼","小清纯","沉稳大叔","有时可爱"}; 对应的选中项的布尔值数组: [java] view plain copy newboolean[]{false,false,false,false,false,false,false} 四、自定义列表项 这节我带大家自定义列表项的实现,故名思义,就是每个ITEM都是我们自己来定义,使用我们自己的Adapter,先看看效果: 要实现自定义列表主要是造下面这个函数来实现的: [java] view plain copy setAdapter(ListAdapteradapter,DialogInterface.OnClickListenerlistener) 直接将我们构造好的Adapter设置进去。 下面就带大家实现下图示中的视图: 1、构造Adapter 有关派生自BaseAdapter来构造ListViewAdapter的过程就不再细讲了,大家可以参考我以前的两篇文章: 1、《List控件使用---SimpleAdapter使用详解(一)》 2、《BaseAdapter——convertView回收机制与动态控件响应》 第 一篇现在看来着实太烂了,一直想重写又没时间来做,大家可以再搜搜网上的其它相关文章来学一下有关BaseAdapter的相关内容吧。第二篇有关 convertView的回收机制写的还是挺不错的,大家可以仔细看看,相信会对ListView的机制有一个更清晰的理解。废话不多说了,下面言转正 转,看看我们这里的ListAdapter的构造过程: 首先是单个Item的布局:(list_item.xml) 很简单,采用水平布局,左边一个图像,右边一个对应的TEXT,这里只是基本实现功能,大家完全可以在理解这篇文章的基础上派生出更复杂的视图 [java] view plain copy <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="match_parent"> <ImageView android:id="@+id/item_imageview" android:layout_width="80dip" android:layout_height="80dip" android:scaleType="fitCenter"/> <TextView android:id="@+id/item_text" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical|left" android:textSize="20sp"/> </LinearLayout> 对应的视图类: [java] view plain copy privateclassViewHolder{ publicTextViewmTvTitle; publicImageViewmImageView; } 其中有两个变量,一个存储对应的TextView,另一个存储对应的ImageView; 现在我们还需要一个类来存储视图类中TextView的标题字符串,和对应ImageView的图片资源的ID值,这就是我们的数据类: [java] view plain copy publicstaticclassDataHolder{ publicStringtitle; publicintImageID; publicDataHolder(Stringtitle,intimageID){ this.title=title; this.ImageID=imageID; } } 我们先阶段性的看看我们的ListViewAdapter: 首先是派生自BaseAdapter,然后是构造函数,我们传进去一个DataHolder的列表,用来存储每个Item应该显示的内容 [java] view plain copy publicclassListItemAdapterextendsBaseAdapter{ privateList<DataHolder>mDataList=newArrayList<DataHolder>(); privateLayoutInflatermInflater; publicListItemAdapter(Contextcontext,ArrayList<DataHolder>datalist){ if(datalist!=null&&datalist.size()>0){ mDataList.addAll(datalist); } mInflater=LayoutInflater.from(context); } ……………… } 然后是最关键的getView部分: [java] view plain copy publicViewgetView(intposition,ViewconvertView,ViewGroupviewGroup){ ViewHolderholder=null; if(convertView==null){ holder=newViewHolder(); convertView=mInflater.inflate(R.layout.list_item,null); holder.mTvTitle=(TextView)convertView.findViewById(R.id.item_text); holder.mImageView=(ImageView)convertView.findViewById(R.id.item_imageview); convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } holder.mImageView.setImageResource(mDataList.get(position).ImageID); holder.mTvTitle.setText(mDataList.get(position).title); returnconvertView; } 首先是通过covertView的tag来获取重复利用的convertView,这什么要这么写,看《BaseAdapter——convertView回收机制与动态控件响应》 然后是利用传进来的数据,初始化列表Item: [java] view plain copy holder.mImageView.setImageResource(mDataList.get(position).ImageID); holder.mTvTitle.setText(mDataList.get(position).title); 最后返回convertView,让系统去做绘图 到这里ListViewAdapter的构造过程就基本完成了,下面是完整的代码: [java] view plain copy /** *Createdbyharvic *date2015-1-11 **/ publicclassListItemAdapterextendsBaseAdapter{ privateList<DataHolder>mDataList=newArrayList<DataHolder>(); privateLayoutInflatermInflater; publicListItemAdapter(Contextcontext,ArrayList<DataHolder>datalist){ if(datalist!=null&&datalist.size()>0){ mDataList.addAll(datalist); } mInflater=LayoutInflater.from(context); } @Override publicintgetCount(){ returnmDataList.size(); } @Override publicObjectgetItem(intposition){ returnmDataList.get(position); } @Override publiclonggetItemId(intposition){ returnposition; } @Override publicViewgetView(intposition,ViewconvertView,ViewGroupviewGroup){ ViewHolderholder=null; if(convertView==null){ holder=newViewHolder(); convertView=mInflater.inflate(R.layout.list_item,null); holder.mTvTitle=(TextView)convertView.findViewById(R.id.item_text); holder.mImageView=(ImageView)convertView.findViewById(R.id.item_imageview); convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } holder.mImageView.setImageResource(mDataList.get(position).ImageID); holder.mTvTitle.setText(mDataList.get(position).title); returnconvertView; } privateclassViewHolder{ publicTextViewmTvTitle; publicImageViewmImageView; } publicstaticclassDataHolder{ publicStringtitle; publicintImageID; publicDataHolder(Stringtitle,intimageID){ this.title=title; this.ImageID=imageID; } } } 2、构造列表 在MainActivity中,首先是初始化我们的ListViewAdapter,要初始化Adapter,就要首先传进去一个DataHolder的数组,所有要先构造一个DataHolder的数组 [java] view plain copy privateArrayList<ListItemAdapter.DataHolder>initDataHolder(){ ArrayList<ListItemAdapter.DataHolder>datalist=newArrayList<ListItemAdapter.DataHolder>(); ListItemAdapter.DataHolderdata_1=newListItemAdapter.DataHolder("可爱萌宠1",R.drawable.animal1); ListItemAdapter.DataHolderdata_2=newListItemAdapter.DataHolder("可爱萌宠2",R.drawable.animal2); ListItemAdapter.DataHolderdata_3=newListItemAdapter.DataHolder("可爱萌宠3",R.drawable.animal3); ListItemAdapter.DataHolderdata_4=newListItemAdapter.DataHolder("可爱萌宠4",R.drawable.animal4); datalist.add(data_1); datalist.add(data_2); datalist.add(data_3); datalist.add(data_4); returndatalist; } 在构造完成数据列表之后,下面就是构造我们的自定义的列表了,我把整个对话框显示过程整合成了一个函数createCustomList,代码如下: [java] view plain copy privatevoidcreateCustomList(){ ArrayList<ListItemAdapter.DataHolder>dataHolders=initDataHolder(); ListItemAdapteradapter=newListItemAdapter(MyActivity.this,dataHolders); AlertDialog.Builderbuilder=newAlertDialog.Builder(MyActivity.this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("可爱萌宠"); builder.setAdapter(adapter,newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialogInterface,intwhich){ Toast.makeText(MyActivity.this,"clicked:"+which,Toast.LENGTH_LONG).show(); } }); builder.create(); builder.show(); } OK啦,到这,整个自列表项的内容就讲完了,下面再回过来给大家说说上面我们提到的有关单选列表自定义Adapter的问题。 五、有关单选列表自定义Adapter 这里主要讲的函数是第二部分单选列表中的方法三: [java] view plain copy setSingleChoiceItems(ListAdapteradapter,intcheckedItem,DialogInterface.OnClickListenerlistener) 在第四部分,我们构造了一个ListAdapter,这里需要的也是同样的一个ListAdapter,那我们直接将第四部分中的Adapter传进去,会是什么效果呢? 也就是利用下面的代码: 我们直接在createCustomList()上面改一下,即把builder.setAdapter()直接换成setSingleChoiceItems() ,传进去Adpter,看看在我们定义的视图后面会不会出现一个单选按钮呢? [java] view plain copy privatevoidcreateCustomList(){ ArrayList<ListItemAdapter.DataHolder>dataHolders=initDataHolder(); ListItemAdapteradapter=newListItemAdapter(MyActivity.this,dataHolders); AlertDialog.Builderbuilder=newAlertDialog.Builder(MyActivity.this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("可爱萌宠"); builder.setSingleChoiceItems(adapter,0,newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialogInterface,intwhich){ Toast.makeText(MyActivity.this,"clicked:"+which,Toast.LENGTH_LONG).show(); } }); builder.create(); builder.show(); } 运行一下,效果是这样的: 看见了没,毛也没有,坑爹玩意,那这个函数到底是用来做什么的呢,在源码中有这样一个文件: 地址在:$android_sdk_home/platforms/Android-x.x/data/res/layout/simple_list_item_single_choice.xml 文件内容是这样的: [html] view plain copy <CheckedTextViewxmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/single_list_item" android:layout_width="match_parent" android:layout_height="?android:attr/listPreferredItemHeightSmall" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:gravity="center_vertical" android:checkMark="?android:attr/listChoiceIndicatorSingle" android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" /> 利用这个玩意是可以实现效果的,我们来试一下。 1、新建Adapter 新建一个布局文件,来保存ListVIew的每项的Item,代码如下: [html] view plain copy <CheckedTextViewxmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/single_list_item" android:layout_width="match_parent" android:layout_height="?android:attr/listPreferredItemHeightSmall" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:gravity="center_vertical" android:checkMark="?android:attr/listChoiceIndicatorSingle" android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" /> 在Adapter中,同样,用来保存ITEM视图的ViewHolder类,如下: [java] view plain copy privateclassViewHolder{ publicTextViewmName; } 因 为在布局中只有一个TextView,所以在ViewHolder中也只需要一个TextView与其对应,至于类似上面的承载对应数据的 DataHolder,因为我们只需要一个String字符串数组就足够了,所以就没必要再新建一个类来承载这些数据了,所以我们要构造Adapter 时,传进来一个字符串数组就好了: 所以简单的构造函数为: 在构造时,传进来我们每项要显示的标题的字符串数组String[] items,并将其直接添加到我们的List<String> mList中。 [java] view plain copy publicclassSingleChoiceAdapterextendsBaseAdapter{ privateLayoutInflatermInflater; privateList<String>mList=newArrayList<String>(); publicSingleChoiceAdapter(Contextcontext,String[]items){ mInflater=LayoutInflater.from(context); if(items==null||items.length<=0){ return; } for(Stringitem:items){ mList.add(item); } } ………… } 然后是最关键的getView()部分: [java] view plain copy publicViewgetView(intposition,ViewconvertView,ViewGroupviewGroup){ ViewHolderholder=null; if(convertView==null){ holder=newViewHolder(); convertView=mInflater.inflate(R.layout.single_choice_item,null); holder.mName=(TextView)convertView.findViewById(R.id.single_list_item); convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } holder.mName.setText(mList.get(position)); returnconvertView; } 这段代码难度不大,就是每次绘图时,将TextView的内容设置为我们指定的字符串: [java] view plain copy holder.mName.setText(mList.get(position)); 下面是SingleChoiceAdapter完整的代码: [java] view plain copy /** *Createdbyharvic *date2015-1-11 */ publicclassSingleChoiceAdapterextendsBaseAdapter{ privateLayoutInflatermInflater; privateList<String>mList=newArrayList<String>(); publicSingleChoiceAdapter(Contextcontext,String[]items){ mInflater=LayoutInflater.from(context); if(items==null||items.length<=0){ return; } for(Stringitem:items){ mList.add(item); } } @Override publicintgetCount(){ returnmList.size(); } @Override publicObjectgetItem(intposition){ returnmList.get(position); } @Override publiclonggetItemId(intposition){ returnposition; } @Override publicViewgetView(intposition,ViewconvertView,ViewGroupviewGroup){ ViewHolderholder=null; if(convertView==null){ holder=newViewHolder(); convertView=mInflater.inflate(R.layout.single_choice_item,null); holder.mName=(TextView)convertView.findViewById(R.id.single_list_item); convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } holder.mName.setText(mList.get(position)); returnconvertView; } privateclassViewHolder{ publicTextViewmName; } } 然后就是使用的阶段了 2、构造单选列表 这里首先构造SingleChoiceAdapter的实例,然后将其传入setSingleChoiceItems中,代码如下: [java] view plain copy String[]mItems={"攻","受","全能型","不告诉你"}; SingleChoiceAdapteradapter=newSingleChoiceAdapter(MyActivity.this,mItems); AlertDialog.Builderbuilder=newAlertDialog.Builder(MyActivity.this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("可爱萌宠"); builder.setSingleChoiceItems(adapter,0,newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialogInterface,intwhich){ Toast.makeText(MyActivity.this,"clicked:"+which,Toast.LENGTH_LONG).show(); } }); builder.create(); builder.show(); 运行出来的效果如图: 看到没,这里效果是出来了,可见,在单选按钮中,定义Adapter并不是随便定义的,只能定义CheckedTextView的视图,其它是不支持的!!!! 好了,到这里本篇就结束了,下篇给大家讲讲有关自定义对话框的内容。 本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/5434828.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

如何构建AI驱动型智能服务?

人工智能(简称AI)驱动型智能服务将把当下各类前沿技术(例如区块链)、物联网以及客户体验因素结合起来——而其未来的发展方向则必然以信任协调为基础。 机器学习、深度学习、自然语言处理以及认知计算的结合将彻底改变人类与机器之间的交互方式。AI驱动型智能服务将学会感知人类身处的周遭环境、根据其以往行动推断个人喜好,并巧妙地通过日常生活对人类加以引导。事实上,对于此类目标的追求将成为当下十年乃至未来最为重要的转变,并使得AI驱动型智能服务被引入各个行业以及各类业务流程当中。 对于企业而言,AI驱动型智能服务则将深刻影响未来的工作流、物联网服务、客户体验以及同步分类帐(即区块链技术)。业务的成功将以AI处理结果为前提(详见图一)。一旦结果建立完成,企业即可规划AI驱动型智能服务,并利用其以规模化方式实现编排、自动化与民主化个性体验交付。 七类AI成果 AI的颠覆性能力源自其速度、精确性以及强化人类判断的能力。我们可以通过以下七类成果了解AI项目所能够实现的具体价值: 1.感知并描述当前正在发生的事态。第一类成果能够同以往的手动编程方案一样描述周遭背景。 2.向你通知你所需了解的情况。通知内容可通过警报、工作流、提醒器以及其它信号加以呈现,并经由手动输入及学习等方式交付额外信息。 3.提供行动建议。根据以往行动提供建议,同时利用权重属性、决策管理以及机器学习随时间推移进行建议修订。 4.自动执行重复工作。随着机器学习不断发展成熟,自动化的实用性也将更上一层楼。 5.提供预测以启发合理预期。要进行预测,我们首先需要建立起深度学习与神经网络,并利用其对行为进行预测与测试。 6.预防负面结果。利用认知推理机制发现潜在威胁。 7.态势感知提供当前重要信息。态势感知将进一步模拟人类在制定决策方面的能力。 AI驱动型智能服务的实现,必须以信任为基础 由于AI驱动型智能服务必须将决策制定责任指派给各原子驱动智能服务,因此任何AI驱动型智能服务的实现基础皆为信任。下面,我们将探讨AI驱动型智能服务信任协调体系中的五大关键组成部分。 1.配合AI,利用数据化足迹与数据产出建立匿名与显式资料。每一个人、设备或者网络都会提供部分信息。这种数字化足迹或产出可能源自面部分析、网络IP地址甚至是步态采集。利用AI与认知推理,系统将能够分析其中的模式并将其与身份关联起来。这意味着AI服务将可在不同情景之下识别并认出对应个人。 2.渲染式体验使交互更为自然。情景、内容、协作与频道共同成为AI驱动型服务交付渲染式独特体验的基础。这类服务将利用地理位置、时间段、天气、心跳率甚至是个人感受等因素作为情景属性,同时结合服务自身所掌握的对象身份与偏好,旨在改进相关性交交付更适合的内容。感知与响应机制将通过对话与文本框的形式实现参与者同机器间的协作。频道则包括各类具体交互点,例如移动、社交、信息亭以及个人等等。其目标在于根据身份提供自然的用户体验。 3.大规模个性化数字服务交付。以规模化方式实现预测分析、催化条件以及选择。预测分析允许客户获得提前预判的能力。催化条件则负责响应的交付或者触发。每位个人或设备都将拥有自己的情景体验,具体取决于身份、历史偏好以及当前需求。从自行选择到情景驱动型选择,再到多选择变量测试,AI系统将令选择拥有更为理想的满意度水平。 4.价值交换成就信任协调。采取行动之后,价值交换即可以交易方式进行。货币、非货币与共识是三种常见的价值交换形式。虽然货币交换也许最为人们所熟知,但非货币价值交换(包括认同、访问与影响)通常也能够带来令人瞩目的价值形式。另外,简单的一致性协商或者协议也能够在患者治疗方案或者土地所有权归属等层面实现价值交换。 5.步调与反馈值得关注,AI支持型机器学习亦然。在机器学习与其它AI工具的支持之下,智能服务开始考虑交付的步调问题:一次性、临时、重复、基于订阅以及阈值驱动型机制皆在其中。利用机器学习技术,系统将了解到智能服务的具体交付方式,并将其运用于未来的交互当中。 总结陈词:AI带来的强化效果 担心机器人统治世界确实有些多虑。事实上,成功的AI驱动型智能服务将强化人类智能——正如机器强化人类的物理体能一样。AI驱动型智能服务在定义同步分类帐技术(即区块链)、物联网、客户体验以及未来工作方式的商业模式当中扮演着关键性角色。由此实现的错误率降低、决策速度提升、需求信号识别、结果预测以及“灾难”预防等能力也必将得到越来越多人们的认可。 原文发布时间为:2017年9月7日 本文作者:杨昀煦 本文来自云栖社区合作伙伴至顶网,了解相关信息可以关注至顶网

优秀的个人博客,低调大师

熊猫直播Rancho发布系统构建之路

作者介绍 符杰超,熊猫直播基础架构部高级运维开发工程师。主要负责熊猫直播运维自动化架构平台建设和开发 前言 随着熊猫直播的业务发展越来越快,业务需求的迭代和版本更新需求越来越多,对开发和运维面临以下4个痛点: 项目需求上线越来越多 发布周期比较长,人工操作比较繁琐 发布项目效率和风险的问题,比如平滑发布,切换负载均衡 发布过程没有详细的审计功能 由此,团队内部决定在现有的发布过程上实现开发统一的发布系统平台,实现熊猫直播的运维发布流程化、标准化、自动化为一体的统一发布要求。 下面围绕整个Rancho发布系统做总结梳理,总共分为9个方面: 实现的最终目的 用户登陆(发布系统的第一道安全墙) 用户权限(发布系统的第二道安全墙) 项目权限(发布系统的第三道安全墙) 代码发布前台 代码发布后台 发布过程/结果 建立标准的wiki文档 小结 Rancho 发布系统流程概述架构图 Rancho 发布系统流程图 Rancho发布系统 实现的最终目的 随着熊猫直播业务的迅猛发展、项目、产品的需求规模和版本迭代频次是无法预估的。传统的运维支持方式已渐渐无法满足这种工程应用现状。但是如果把发布权利交付到开发人员手里控制,运维安全是比较大的隐患。当2者都无法平衡的时候,利用高效的标准化,自动化体系将2个无法逾越的问题优化结合起来,我们结合了上述问题,实现了内部的发布系统,对于发布系统,实现了2个核心目标,如下: 发布项目统一接入在新项目接入平台的第一次起,运维只需要把项目添加上,给对应的开发开放相对应的发布权限,项目接入+权限都是正常状态下,运维需要做的事情就完成了 一键自动发布开发可以根据自己所拥有的项目发布权限,进行任何时间段的发布,同时发布系统会对用户,发布项目,发布操作,结果做到全方位的记录 目的: 让研发自助运维 用户登陆(发布系统的第一道安全墙) 对于发布系统的登陆,我们结合了内部开发的一套SSO系统+Rancho系统并加了一层白名单策略,有以下3个方面考虑: 安全性平台登陆安全性,SSO采用统一认证+MD5算法+Hash算法+静态系统唯一标识 连接统一的Session/Cookie允许连接,保持会话,过期,删除由SSO管理 双权验证假如用户在SSO可以正常登陆,但是在Rancho发布平台没有登陆权限,就是禁止登陆。原因很简单,因为全公司每个人都拥有自己的统一登陆账户,防止有人试探登陆/误操作登陆 用户权限(发布系统的第二道安全墙) 用户权限,我们分为2类角色: 管理员具有发布系统超级权限,可以对所有项目/用户进行操作 普通用户只能看到运维授权的项目,发布、发布详情、查看发布历史、查询,但是不可编辑、更新项目 项目权限(发布系统的第三道安全墙) 项目权限设计,我们当时也花很多时间去讨论,最终拟定方案,项目不首先对应用户,而是在用户和项目中间建立一个桥梁,我们命名为项目组 原因当多个用户同时去拥有一个项目权限的时候,这个时候要全部用户都要增加到这个项目体系中去 如果这样做的问题增加繁琐,当项目删除改用户权限/或者用户不再拥有该项目权限,还要精确的删除,否则删除错了,后果很严重,逻辑同时还要对用户和项目,做双层处理操作 解决方案用户--项目组--项目 方案优点 项目组方便了运维管理,如果没有项目组,一个项目对应的权限用户比较多的话、需要管理员分别的去增加/更新编辑比较繁琐 系统根据项目组有效控制不同用户之间对应项目的权限隔离发 项目组图例 代码发布前台 前台用于开发人员进行发布所操作的页面,其中功能包含: 发布页面 发布tag种类选择 发布环境/机器列表选择 当用户进来某个项目的时候,Rancho 发布系统会同时异步获取该项目所有的环境/主机列表,对用户而言无需任何操作处理。 发布页面 支持机器单选、多选、全选、临时主机添加等: 发布tag种类 发布tag种类选择如下: 开发tag(可测试) 线上tag(灰度/线上) 其他tag(代表开发/线上 tag 未显示你要发布的 tag,发布人员可以根据 tag号输入,如果 git 库里存在,可以正常发布,如果不存在,用户也可以接收到对应的错误结果) 线上/开发tag,Rancho 发布系统会自动实时更新git库前10个最新的tag,供用户选择 tag版本选择页面 tag比对图 用户选择的tag和主干,和最后一次发布tag比对如下: 发布环境/机器列表选择 对于发布环境我们有自己的一套命名扩展规则,有3种类型: 类型一根据项目功能服务来命名 类型二根据发布环境来命名 类型三 前2者整合 某个项目命名情况: 项目功能服务拆分,包含:crontab、sdk、console、front等 项目发布环境拆分,包含:online、beta、gray等 独立情况/整合情况,如下说明: beta环境可以独立的命名 beta环境有sdk服务,命名为:sdk_beta beta环境有console,命名为:beta_console PS:环境命名、细化、拆解,开发人员根据项目功能类型进行自定义,Rancho自动识别和拆解命名体系 每个发布环境对应发布的机器,其中一个项目页面如下展示 前台首页图 用户登陆进来看到的所拥有项目的页面,功能有发布、查看、发布历史、需说明(只有管理员才有展示启用/禁用权限) 启用:代表这个项目是正常运行发布禁用:可以看作删除,但是我们不作为真正删除,临时迁入回收站,如果哪天这个项目需要启用发布了,我们再打开进行该项目发布 前台发布确认清单 发布前让发布用户再次确认上线的项目,tag,发布环境,是否重启机器(现有的和临时添加的主机): 发布清单提交请求 避免脏数据的方法: 程序监控对发布队列是否正常服务检测,并且自动做干预 程序监控对数据库/缓存正常服务检测,并且自动做干预 程序监控对生成的task_ID是否存在,并且自动做干预 程序监控对生成的发布指令做严格的判断,是否为不正确指令,并且自动做出干预 代码发布后台 后台项目管理的成功/失败,对整个前台发布起到至关重要的 后台操作权限为管理员:一般是指定对应的运维人员 操作程度:简单、易用,所有处理逻辑都交给Rancho去搞定 后台操作新项目流程页面 新建字段说明 名称: 代表项目的主名称(唯一,如果重复则提示错误详情),别名代表项目的描述,可以是中文/英文,名称可以重复 git clone url地址:开发提供,这个地址Rancho在处理的过程中,会对本身项目权限,该项目类型标识进行判断和提取,比如我们有2种功能发布:rigger和ansible,而发布语言有:golang、php、nodejs、python、lua、c++等多种混合语言,排名不分先后 项目组权限:添加该项目允许哪些项目组成员进行发布 备注: 可写/可不写 至此,运维管理员需要做的事情已经完成,剩下的点击提交,剩下的事情交给Rancho去处理了。 后台新建页面 Rancho底层基本处理流程 项目失败手动触发 Rancho 处理恢复流程 发布过程/结果 前期的工作: 后台新建项目完成,到发布提交申请,最后查看发布过程/结果的验证 某一个项目单次发布127台主机,用时3分32秒,截图如下: 发布过程的处理流程概述和原理图例展示 发布过程有3种场景: 负载均衡四/七层策略 无负载均衡策略 项目服务是否重启 针对以上3种场景,分别作了不同的处理规则: 负载均衡场景有白名单策略代表该项目拥有负载均衡策略(至于挂了多少负载均衡节点在发布的时候,Rancho发布系统会自动的计算,并且做相对应的平滑策略切换) 无负载均衡策略走正常的发布流程 项目服务发布是否重启(Rancho支持重启项目服务/支持不重启项目服务)需求描述: 项目发布更新,但是不重启服务,看下项目代码发布过程是否成功/失败。(这点对于发布项目业务正常运行不会出现有损情况) 项目发布更新,重启服务(项目发布代码完成,自动重启项目服务) 发布速度:无负载均衡策略项目相对于比有LB策略的项目快2ms-30ms,根据项目绑定的LB有关联。 项目发布锁图例展现 发布锁作用: 防止同项目同发布环境多任务一起发布,会有覆盖,冲突 项目发布历史统计图例展现 状态分为: 正在发布 触发失败 发布成功 项目发布手工终止图例展现 发布结果成功图例展现 发布结果失败/终止图例展现 失败单台,未执行的机器程序自动干预停止发布实例子 发布过程中,手工可以终止发布功能,说明 防止发布过程中有未知的原因或长时间缓慢/卡顿等,发布人员可以根据业务重要评估,进行降级发布过程停止操作,并且系统会把操作用户、时间、项目、降级操作等做详细记录 正常发布完成后,终止发布按钮功能会自动消失 下面截图所示 项目回滚策略 当某个项目发布失败或者异常,想回滚到上个正常版本,可以以对应的tag号来进行重新发布 发布结果日志截图展现 自动按天生成日志,并且按天做发布日志全量汇总 建立完善的Wiki文档 Rancho发布系统在熊猫直播循序渐进的优化功能/需求、bug修复等、wiki文档的规范化也要随之建立起来。 以下是wiki文档建立的图例: 小结 Rancho发布系统已经在线上运行了将近5个月的时间,目前 Rancho系统功能包含了: 项目建立 用户登陆权限严格的隔离 项目锁机制 项目前台 项目后台 LB 4/7层和 Nginx upstream 白名单策略 平滑摘取/绑定主机 支持Rigger发布功能和Ansible发布功能 多语言混合并行发布(Golang、PHP、Nodejs、C++、Lua、Python、Shell等,语言排名不分先后) 异步实时处理发布任务 实时可视化展现发布结果 多环境发布 跨多机房发布 手工/自动干预终止发布 避免严重的错误影响到正常业务 详细的发布操作记录:用户操作、时间、发布环境、发布tag、发布主机成功次数统计、发布主机失败次数统计、发布主机程序自动干预终止次数统计、发布主机手工干预终止次数统计、发布主机正在发布中次数统计等 目前熊猫直播Rancho发布系统解决的痛点: 研发自助运维熊猫直播产品业务线的发布更新/回滚变更等操作,都由各自的项目线开发人员操作发布/回滚,运维不直接参与整个发布/回滚流程,遇到发布错误/异常,运维才介入和开发一起排查相关问题 发布时间周期长目前发布系统异步处理整个发布流程,点击发布提交之后,页面关闭都可以,发布人员想看结果的时候,才登陆系统查看即可 平滑切换负载均衡发布系统增加了白名单策略,发布项目上线前,Rancho发布系统会自动判断白名单策略项目,如果该项目存在白名单策略,Rancho发布系统会自动做整个负载均衡下线—上线—绑定上线流程操作 发布系统详细的审计功能从用户登陆-创建发布清单-点击发布-发布过程-发布结果都做了详细的记录,记录纬度:登陆时间、发布起始时间、发布完成时间、用户、发布环境、发布项目(平滑,服务是否重启,tag,主机数量,主机信息清单),发布结果(成功、失败、终止)等 目前发布次数/项目总数统计 2017年2月16日上线到目前,累计发布工单12000次,最多单次工单发布主机100台+,成功96%,失败3%,终止1%,接入发布项目将近100+。 Rancho发布系统未来优化 Rancho发布系统未来优化的路还有很多,优化方向分为以下3点: 接入发布预警平台当某个项目出现异常的时候,运维能及时收到短信/邮件的提示 定时作业发布可以按照用户自定义的发布时间,定时发布代码 发布错误/异常自动修复目前Rancho发布系统已经可以收集到全部错误发布类型,但是真正修复还需人工,以后当错误出现了,自动上报到修复库里进行存档,在下一次同样错误出现的时候,Rancho自动修复,并优雅提示用户发布错误修复完成,请重新发布

优秀的个人博客,低调大师

如何使用JavaScript构建机器学习模型

目前,机器学习领域建模的主要语言是 Python 和 R,前不久腾讯推出的机器学习框架 Angel 则支持 Java 和 Scala。本文作者 Abhishek Soni 则用行动告诉我们,开发机器学习模型,JavaScript 也可以。 JavaScript?我不是应该使用 Python 吗?甚至 Scikit-learn 在 JavaScript 上都不工作。 这是可能的,实际上,连我自己都惊讶于开发者对此忽视的态度。就 Scikit-learn 而言,Javascript 的开发者事实上已经推出了适用的库,它会在本文中有所提及。那么,让我们看看 Javascript 在机器学习上能够做什么吧。 根据人工智能先驱 Arthur Samuel 的说法,机器学习为计算机提供了无需明确编程的学习能力。换句话说,它使得计算机能够自我学习并执行正确的指令,无需人类提供全部指导。 谷歌已经把自己移动优先的策略转换到人工智能优先很久了。 为什么 JavaScript 在机器学习界未被提及过? · 慢(真的假的?) · 矩阵操作很困难(这里有库,比如 math.js) · 仅用于 Web 开发(然而这里还有 Node.js) · 机器学习库通常是在 Python 上的(还好,JS 的开发者人数也不少) 在 JavaScript 中有一些可供使用的预制库,其中包含一些机器学习算法,如线性回归、SVM、朴素贝叶斯等等,以下是其中的一部分。 · brain.js(神经网络) · Synaptic(神经网络) · Natural(自然语言处理) · ConvNetJS(卷积神经网络) · mljs(一组具有多种功能的子库) 首先,我们将使用 mljs 回归库来进行一些线性回归操作。 参考代码:https://github.com/abhisheksoni27/machine-learning-with-js 1. 安装库 $ npm install ml-regression csvtojson $ yarn add ml-regression csvtojson ml-regression 正如其名,负责机器学习的线性回归。 csvtojson 是一个用于 node.js 的快速 CSV 解析器,它允许加载 CSV 数据文件并将其转换为 JSON。 2. 初始化并加载数据 下载数据文件(.csv),并将其加入你的项目。 链接: http://www-bcf.usc.edu/~gareth/ISL/Advertising.csv 如果你已经初始化了一个空的 npm 项目,打开 index.js,输入以下代码。 我把文件放在了项目的根目录下,如果你想放在其他地方,请记得更新 csvFilePath。 现在我们使用 csvtojson 的 fromFile 方法加载数据文件: 3. 打包数据,准备执行 JSON 对象被存储在 csvData 中,我们还需要输入数据点数组和输出数据点。我们通过一个填充 X 和 Y 变量的 dressData 函数来运行数据。 4. 训练模型开始预测 数据已经打包完毕,是时候训练我们的模型了。 为此,我们需要写一个 performRegression 函数: performRegression 函数有一个方法 toString,它为浮点输出获取一个名为 precision 的参数。predictOutput 函数能让你输入数值,然后将模型的输出传到控制台。它是这样的(注意,我使用的是 Node.js 的 readline 工具): 以下是为了增加阅读用户的代码 5. 大功告成! 到你的终端上运行 node index.js,得到的输出会是这样: 恭喜!你刚刚在 JavaScript 中训练了第一个线性回归模型。(PS. 你注意到速度了吗?) 文章来源:机器之心 原文地址 欢迎关注个人公众号,查看更多好文。

资源下载

更多资源
Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册