首页 文章 精选 留言 我的

精选列表

搜索[场景赋能],共10000篇文章
优秀的个人博客,低调大师

OpenVINO 能支持ARM架构了?!

点击蓝字 关注我们,让开发变得更有趣 内 容 来 源| 康 瑶 明 全文字数625,预计阅读4min 1.扩展模块的介绍 OpenVINO诞生至今,其功能越来越强,模块也越来越多。为了保证发布版本的稳定性,Github上新增了openvino_contrib代码库用来开发扩展模块,功能稳定后再合并到OpenVINO库中。扩展模块中的每个模块都是解耦的,可以独立编译使用。主要包括三部分:arm_plugin、java_api、mo_pytorch。本文主要介绍 arm_plugin 模块的使用。arm_plugin使用 OpenVINO API 在 ARM CPU 上启用深度神经网络推理。该插件使用 ARM Compute Library 作为后端。 2.支持的平台 OpenVINO ARM CPU 插件在以下平台上受支持和验证: 硬件 系统 树莓派4B Debian 10.3 (32-bit) 树莓派4B Ubuntu 18.04 (64-bit) 3.编译构建 编译方法和使用环境: github 文档提供了三种方法(文档链接见文章末尾Q&A)。我这里使用了第一种交叉编译的方式,在 ubuntu18.04 系统上 Build Dockerfile 来构建 OpenVINO、OpenCV 和 ARM CPU Plugin。 克隆 openvino_contrib 存储库 git clone --recurse-submodules --single-branch --branch=master https://github.com/openvinotoolkit/openvino_contrib.git 转到 ARM_Plugin 目录 cd openvino_contrib/modules/arm_plugin Build Docker Image Build 过程由/armplg_build.sh在 armcpu_plugin 路径执行脚本,共有15步。 docker image build -t arm-plugin -f Dockerfile.RPi32 . Build the plugin in Docker container 所有的中间结果和 build artifacts 都保存在工作路径下, 因此,我们可以挂载整个工作目录以将所有结果存储在容器外部。 mkdir builddocker container run --rm -ti -v $PWD/build:/armcpu_plugin arm-plugin 完成后如图所示 查看目录包含哪些文件 上述操作耗时近2小时,生成的 build 文件2.4GB。我们可以只导出带有 artifacts 的归档文件OV_ARM_package.tar.gz,比较节约时间,只有108MB,即执行下面命令: docker container run --rm -ti --tmpfs /armcpu_plugin:rw -v $PWD:/remote \ arm-plugin sh -c "sh /armplg_build.sh && cp ./OV_ARM_package.tar.gz /remote" 4.运行加速 把编译生成的包OV_ARM_package.tar.gz拷贝到树莓派4B上 ,并解压。 我这里提前准备了优化好的IR文件,并拷贝到树莓派4B上,这样就可以直接在模型中加载。 vehicle-license-plate-detection-barrier-0106.xmlvehicle-license-plate-detection-barrier-0106.bin 转到推理引擎bin目录 cd /home/pi/deployment_tools/inference_engine/bin/armv7l 下载车辆图像 wgethttps://raw.githubusercontent.com/openvinotoolkit/openvino/master/scripts/demo/car_1.bmp 将 OpenCV 和 OpenVINO 库目录添加到 LD_LIBRARY_PATH export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/opencv/lib/:~/deployment_tools/inference_engine/lib/armv7l/ 在ARM平台上运行对象检测demo ./object_detection_sample_ssd -m ~/FP32/vehicle-license-plate-detection-barrier-0106.xml -i car_1.bmp -d CPU 查看使用ARM CPU加速推理后的输出图像 Q&A: 1.请问项目在哪里可以看到? 项目地址: 推荐使用Gitee开源版下载: https://gitee.com/openvinotoolkit-prc/openvino https://gitee.com/openvinotoolkit-prc/openvino_contrib Github链接: https://github.com/openvinotoolkit/openvino_contrib/tree/master/modules/arm_plugin 2.请问编译阶段可以在ARM平台执行吗? 由于文档没有详细说明,编译阶段我尝试在树莓派4B上build,但是发现各种莫名其妙的问题,在此建议编译在x86架构的硬件上进行。 3.请问文章所用的IR文件和编译生成的tar包哪里可以下载,可以跳过编译阶段直接用tar包进行推理吗? IR文件和tar包我已经上传到百度云网盘,可以扫码获取。可以跳过编译阶段,直接把tar包拷贝到ARM平台加载模型进行推理。 --END-- 你也许想了解(点击蓝字查看)⬇️ ➡️「OpenVINO + ROS 开源项目组」成员招募 ➡️「领航者联盟」发榜啦|OpenVINO 开发者界的“奥斯卡”,属于最 IN 社区人 ➡️早餐 | 第三十期Graph Transformation(二) ➡️4月22日研讨会预热|为企业寻良将,为人才筑舞台! ➡️OpenVINO 部署加速 Keras 训练生成的模型 ➡️OpenVINO 视觉开发与加速框架介绍 ➡️转换和模型推理优化指南 ➡️OpenVINO 部署 Mask-RCNN 实例分割网络 ➡️OpenVINO 部署模型时如何自定义任意尺寸的支持 ➡️ROS C++ 代码规范 ➡️快速构建 OpenVINO X Azure IoT 云边协同方案 ➡️OpenVINO 配置系统环境变量 👇欢迎在留言区与我们互动哦, 点击小程序 留言区 即可参与 留言区 ○点击“在看”,让更多人看见 点击阅读原文跳 转 社 区专区进行讨论! 本文分享自微信公众号 - OpenVINO 中文社区(openvinodev)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

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

能携号转网后,移动转出的用户最多

携号转网已于 11 月 27 日正式在全国范围内上线,此前不少人猜测中国移动会是压力最大的一家,从工信部公布的试运行期间的数据来看,移动确实是三大运营商中流失用户最多的。 截至 11 月 26 日,携号转网的人员不到整体的 2%,占比虽小,绝对数字还是相当可观的。正式上线前,携号转网于 2018 年 12 月 1 日在天津、海南、江西、湖北、云南等五省进行试点,共有 316 万用户完成携号转网,占用户总量的 1.8%,其他 26 个省份自今年 11 月 10 日试运行携号转网以来,截至 26 日,共发放携出授权码 11.2 万人次,协助 7.2 万个用户完成携转。 ▲ 图片来自:中国移动 中国电信、中国移动、中国联通转出的用户数占全部转出用户的比例分别是 16.3%、57.6% 和 26.1%,转入的占比 是 49.3%、28.1% 和 22.6%。也就是说,移动的转出用户最多,在转入其他运营商的时候,近一半的人选择了电信。 然而,移动在公布数据的时候,换了另一种比较口径:携出率。移动表示 26 省试运行期间他们的携出率只有 0.003%,远少于电信的 0.007% 和联通的 0.010%。要注意的是,截至今年 8 月,移动的总用户数高达 9.4 亿,比电信和联通相加还多 2 亿,但也可以说,凭借原有的用户基础,移动可以不慌。 ▲ 试运行期间,我们测试了近 10 个号码,只有一个有携号转网的资格 在携号转网试运行期间,被吐槽最多的恐怕是运营商的「百般阻挠」,用合约未到期、开通了某项业务等理由拒绝用户转网,不过在正式上线后,或许是受到舆论的压力以及工信部出台的《携号转网服务管理规定》中要求「不得干扰用户选择、阻挠携转」的限制,这种情况似乎有所好转,而有意转网的用户,接到运营商的「关怀」电话,意外解锁低价套餐的也不在少数。显然不管用户多寡,携号转网还是让三大运营商有了危机感,这对用户来说是好事。 从网络上的普遍反馈来看,价格和信号是促使用户更换运营商的两大主要原因,联通和电信这几年凭借互联网套餐俘获了不少用户,在这一点上移动的反应相当迟缓,但联通和电信的信号问题也经常为人诟病,看起来很难两全其美。 除了转出受限外,携转后手机无法正常充值、收不到短信等技术问题也让不少人心生犹豫,据工信部介绍,对于收不到短信的问题,三家运营商已采取「兜底转发」的方式,对携号转网后送错电信企业的短信采用网间转发功能来解决。 随着 5G 的到来,三家在套餐价格相差无几的情况下,5G 信号的覆盖和体验的好坏将起到决定性作用,或许携号转网的高峰将未来几年 5G 普及后来临。

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

Android打造万能自定义阴影控件

目录介绍 01.阴影效果有哪些实现方式 02.实现阴影效果Api 03.设置阴影需要注意哪些 04.常见Shape实现阴影效果 05.自定义阴影效果控件 06.如何使用该阴影控件 07.在recyclerView中使用注意点 01.阴影效果有哪些实现方式 阴影效果有哪些实现方式 第一种:使用CardView,但是不能设置阴影颜色 第二种:采用shape叠加,存在后期UI效果不便优化 第三种:UI切图 第四种:自定义View 否定上面前两种方案原因分析? 第一个方案的CardView渐变色和阴影效果很难控制,只能支持线性或者环装形式渐变,这种不满足需要,因为阴影本身是一个四周一层很淡的颜色包围,在一个矩形框的层面上颜色大概一致,而且这个CardView有很多局限性,比如不能修改阴影的颜色,不能修改阴影的深浅。所以这个思路无法实现这个需求。 第二个采用shape叠加,可以实现阴影效果,但是影响UI,且阴影部分是占像素的,而且不灵活。 第三个方案询问了一下ui。他们给出的结果是如果使用切图的话那标注的话很难标,身为一个优秀的设计师大多对像素点都和敏感,界面上的像素点有一点不协调那都是无法容忍的。 在下面开源案例代码中,我会一一展示这几种不同方案实现的阴影效果。 网上一些介绍阴影效果方案 所有在深奥的技术,也都是为需求做准备的。也就是需要实践并且可以用到实际开发中,这篇文章不再抽象介绍阴影效果原理,理解三维空间中如何处理偏移光线达到阴影视差等,网上看了一些文章也没看明白或者理解。这篇博客直接通过调用api实现预期的效果。 阴影是否占位 使用CardView阴影不占位,不能设置阴影颜色和效果 使用shape阴影是可以设置阴影颜色,但是是占位的 02.实现阴影效果Api 思考一下如何实现View阴影效果? 首先要明确阴影的实现思路是什么,其实就是颜色导致的视觉错觉。说白了就是在你的Card周围画一个渐变的体现立体感的颜色。基于上述思路,我们在一个在一个view上画一个矩形的图形,让他周围有渐变色的阴影即可。于是我们想起几个API: 类:Paint 用于在Android上画图的类,相当于画笔 类:Canvas 相当于画布,Android上的view的绘制都与他相关 方法:paint.setShadowLayer可以给绘制的图形增加阴影,还可以设置阴影的颜色 paint.setShadowLayer(float radius, float dx, float dy, int shadowColor); 这个方法可以达到这样一个效果,在使用canvas画图时给视图顺带上一层阴影效果。 简单介绍一下这几个参数: radius: 阴影半径,主要可以控制阴影的模糊效果以及阴影扩散出去的大小。 dx:阴影在X轴方向上的偏移量 dy: 阴影在Y轴方向上的偏移量 shadowColor: 阴影颜色。 终于找到了设置颜色的,通过设置shadowColor来控制视图的阴影颜色。 03.设置阴影需要注意哪些 其中涉及到几个属性,阴影的宽度,view到Viewgroup的距离,如果视图和父布局一样大的话,那阴影就不好显示,如果要能够显示出来就必须设置clipChildren=false。 还有就是视图自带的圆角,大部分背景都是有圆角的,比如上图中的圆角,需要达到高度还原阴影的效果就是的阴影的圆角和背景保持一致。 04.常见Shape实现阴影效果 多个drawable叠加 使用layer-list可以将多个drawable按照顺序层叠在一起显示,默认情况下,所有的item中的drawable都会自动根据它附上view的大小而进行缩放,layer-list中的item是按照顺序从下往上叠加的,即先定义的item在下面,后面的依次往上面叠放 阴影效果代码如下所示 这里有多层,就省略了一些。然后直接通过设置控件的background属性即可实现。 <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape android:shape="rectangle"> <solid android:color="@color/indexShadowColor_1" /> <corners android:radius="5dip" /> <padding android:bottom="1dp" android:left="1dp" android:right="1dp" android:top="1dp" /> </shape> </item> <item> <shape android:shape="rectangle"> <solid android:color="@color/indexShadowColor_2" /> <corners android:radius="5dip" /> <padding android:bottom="1dp" android:left="1dp" android:right="1dp" android:top="1dp" /> </shape> </item> …… <item> <shape android:shape="rectangle"> <corners android:radius="5dip" /> <solid android:color="@color/indexColor" /> </shape> </item> </layer-list> 05.自定义阴影效果控件 首先自定义属性 <declare-styleable name="ShadowLayout"> <!--阴影的圆角大小--> <attr name="yc_cornerRadius" format="dimension" /> <!--阴影的扩散范围(也可以理解为扩散程度)--> <attr name="yc_shadowLimit" format="dimension" /> <!--阴影颜色--> <attr name="yc_shadowColor" format="color" /> <!--x轴的偏移量--> <attr name="yc_dx" format="dimension" /> <!--y轴的偏移量--> <attr name="yc_dy" format="dimension" /> <!--左边是否显示阴影--> <attr name="yc_leftShow" format="boolean" /> <!--右边是否显示阴影--> <attr name="yc_rightShow" format="boolean" /> <!--上边是否显示阴影--> <attr name="yc_topShow" format="boolean" /> <!--下面是否显示阴影--> <attr name="yc_bottomShow" format="boolean" /> </declare-styleable> 代码如下所示 /** * <pre> * @author yangchong * blog : https://github.com/yangchong211 * time : 2018/7/20 * desc : 自定义阴影 * revise: * </pre> */ public class ShadowLayout extends FrameLayout { /** * 阴影颜色 */ private int mShadowColor; /** * 阴影的扩散范围(也可以理解为扩散程度) */ private float mShadowLimit; /** * 阴影的圆角大小 */ private float mCornerRadius; /** * x轴的偏移量 */ private float mDx; /** * y轴的偏移量 */ private float mDy; /** * 左边是否显示阴影 */ private boolean leftShow; /** * 右边是否显示阴影 */ private boolean rightShow; /** * 上边是否显示阴影 */ private boolean topShow; /** * 下面是否显示阴影 */ private boolean bottomShow; private boolean mInvalidateShadowOnSizeChanged = true; private boolean mForceInvalidateShadow = false; public ShadowLayout(Context context) { super(context); initView(context, null); } public ShadowLayout(Context context, AttributeSet attrs) { super(context, attrs); initView(context, attrs); } public ShadowLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context, attrs); } @Override protected int getSuggestedMinimumWidth() { return 0; } @Override protected int getSuggestedMinimumHeight() { return 0; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (w > 0 && h > 0 && (getBackground() == null || mInvalidateShadowOnSizeChanged || mForceInvalidateShadow)) { mForceInvalidateShadow = false; setBackgroundCompat(w, h); } } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (mForceInvalidateShadow) { mForceInvalidateShadow = false; setBackgroundCompat(right - left, bottom - top); } } public void setInvalidateShadowOnSizeChanged(boolean invalidateShadowOnSizeChanged) { mInvalidateShadowOnSizeChanged = invalidateShadowOnSizeChanged; } public void invalidateShadow() { mForceInvalidateShadow = true; requestLayout(); invalidate(); } private void initView(Context context, AttributeSet attrs) { initAttributes(context, attrs); int xPadding = (int) (mShadowLimit + Math.abs(mDx)); int yPadding = (int) (mShadowLimit + Math.abs(mDy)); int left; int right; int top; int bottom; if (leftShow) { left = xPadding; } else { left = 0; } if (topShow) { top = yPadding; } else { top = 0; } if (rightShow) { right = xPadding; } else { right = 0; } if (bottomShow) { bottom = yPadding; } else { bottom = 0; } setPadding(left, top, right, bottom); } @SuppressWarnings("deprecation") private void setBackgroundCompat(int w, int h) { Bitmap bitmap = createShadowBitmap(w, h, mCornerRadius, mShadowLimit, mDx, mDy, mShadowColor, Color.TRANSPARENT); BitmapDrawable drawable = new BitmapDrawable(getResources(), bitmap); if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { setBackgroundDrawable(drawable); } else { setBackground(drawable); } } private void initAttributes(Context context, AttributeSet attrs) { TypedArray attr = getTypedArray(context, attrs, R.styleable.ShadowLayout); if (attr == null) { return; } try { //默认是显示 leftShow = attr.getBoolean(R.styleable.ShadowLayout_yc_leftShow, true); rightShow = attr.getBoolean(R.styleable.ShadowLayout_yc_rightShow, true); bottomShow = attr.getBoolean(R.styleable.ShadowLayout_yc_bottomShow, true); topShow = attr.getBoolean(R.styleable.ShadowLayout_yc_topShow, true); mCornerRadius = attr.getDimension(R.styleable.ShadowLayout_yc_cornerRadius, 0); mShadowLimit = attr.getDimension(R.styleable.ShadowLayout_yc_shadowLimit, 0); mDx = attr.getDimension(R.styleable.ShadowLayout_yc_dx, 0); mDy = attr.getDimension(R.styleable.ShadowLayout_yc_dy, 0); mShadowColor = attr.getColor(R.styleable.ShadowLayout_yc_shadowColor, getResources().getColor(R.color.default_shadow_color)); } finally { attr.recycle(); } } private TypedArray getTypedArray(Context context, AttributeSet attributeSet, int[] attr) { return context.obtainStyledAttributes(attributeSet, attr, 0, 0); } private Bitmap createShadowBitmap(int shadowWidth, int shadowHeight, float cornerRadius, float shadowRadius, float dx, float dy, int shadowColor, int fillColor) { //根据宽高创建bitmap背景 Bitmap output = Bitmap.createBitmap(shadowWidth, shadowHeight, Bitmap.Config.ARGB_8888); //用画板canvas进行绘制 Canvas canvas = new Canvas(output); RectF shadowRect = new RectF(shadowRadius, shadowRadius, shadowWidth - shadowRadius, shadowHeight - shadowRadius); if (dy > 0) { shadowRect.top += dy; shadowRect.bottom -= dy; } else if (dy < 0) { shadowRect.top += Math.abs(dy); shadowRect.bottom -= Math.abs(dy); } if (dx > 0) { shadowRect.left += dx; shadowRect.right -= dx; } else if (dx < 0) { shadowRect.left += Math.abs(dx); shadowRect.right -= Math.abs(dx); } Paint shadowPaint = new Paint(); shadowPaint.setAntiAlias(true); shadowPaint.setColor(fillColor); shadowPaint.setStyle(Paint.Style.FILL); if (!isInEditMode()) { shadowPaint.setShadowLayer(shadowRadius, dx, dy, shadowColor); } canvas.drawRoundRect(shadowRect, cornerRadius, cornerRadius, shadowPaint); return output; } } 06.如何使用该阴影控件 十分简单,如下所示 <com.ns.yc.yccardviewlib.shadow.ShadowLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="10dp" app:yc_cornerRadius="18dp" app:yc_dx="0dp" app:yc_dy="0dp" app:yc_shadowColor="#2a000000" app:yc_shadowLimit="5dp"> <TextView android:layout_width="wrap_content" android:layout_height="36dp" android:background="@drawable/shape_show_" android:gravity="center" android:paddingLeft="10dp" android:paddingRight="10dp" android:text="完全圆形圆角" android:textColor="#000" /> </com.ns.yc.yccardviewlib.shadow.ShadowLayout> 07.在recyclerView中使用注意点 在createShadowBitmap方法中,其实也可以看到需要创建bitmap对象。大家都知道bitmap比较容易造成内存过大,如果是给recyclerView中的item设置阴影效果,那么如何避免重复创建,这时候可以用到缓存。所以可以在上面的基础上再优化一下代码。 先创建key,主要是用于map集合的键。这里为何用对象Key作为map的键呢,这里是借鉴了glide缓存图片的思路,可以创建Key对象的时候传入bitmap名称和宽高属性,并且需要重写hashCode和equals方法。 public class Key { private final String name; private final int width; private final int height; public Key(String name, int width, int height) { this.name = name; this.width = width; this.height = height; } public String getName() { return name; } public int getWidth() { return width; } public int getHeight() { return height; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } Key key = (Key) o; if (width != key.width) { return false; } if (height != key.height) { return false; } return name != null ? name.equals(key.name) : key.name == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + width; result = 31 * result + height; return result; } } 然后存取操作如下所示 在查找的时候,通过Key进行查找。注意:Bitmap需要同时满足三个条件(高度、宽度、名称)都相同时才能算是同一个 Bitmap。 Key key = new Key("bitmap", shadowWidth, shadowHeight); Bitmap output = cache.get(key); if(output == null){ //根据宽高创建bitmap背景 output = Bitmap.createBitmap(shadowWidth, shadowHeight, Bitmap.Config.ARGB_8888); cache.put(key, output); LogUtil.v("bitmap对象-----","----直接创建对象,然后存入缓存之中---"); } else { LogUtil.v("bitmap对象-----","----从缓存中取出对象---"); } 其他介绍 01.关于博客汇总链接 1.技术博客汇总 2.开源项目汇总 3.生活博客汇总 4.喜马拉雅音频汇总 5.其他汇总 02.关于我的博客 github:https://github.com/yangchong211 知乎:https://www.zhihu.com/people/yczbj/activities 简书:http://www.jianshu.com/u/b7b2c6ed9284 csdn:http://my.csdn.net/m0_37700275 喜马拉雅听书:http://www.ximalaya.com/zhubo/71989305/ 开源中国:https://my.oschina.net/zbj1618/blog 泡在网上的日子:http://www.jcodecraeer.com/member/content_list.php?channelid=1 邮箱:yangchong211@163.com 阿里云博客:https://yq.aliyun.com/users/article?spm=5176.100- 239.headeruserinfo.3.dT4bcV segmentfault头条:https://segmentfault.com/u/xiangjianyu/articles 掘金:https://juejin.im/user/5939433efe88c2006afa0c6e 开源案例地址:https://github.com/yangchong211/YCCardView

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

阿里云实时计算的前世“功”今生“能”

前言:不修内功,难成大器。为了将Apache Flink在阿里巴巴真正运行起来,阿里巴巴实时计算团队做了大量的优化,在阿里云上的产品正式命名为实时计算,以Flink SQL为主要API,致力于打造一款全球领先的实时计算引擎。 正文:阿里云实时计算大可成稻草,小亦是利器在光明日报近期的文章中,回首互联网接入中国的二十多年,特别是最近五年,被互联网之光照耀的地方,许多人的命运因互联网而发生改变,人们可以通过一个鼠标、一根网线或者一部手机就能与广阔的世界相连。 有了互联网,陕西省山阳县贫困山区的孩子可以免费接受数字教育,通过互联网认识到长颈鹿不是猪身马首的动物。有了互联网,甘肃山村贫困户家里养的山羊二十四小时就能通过专业冷链供应给上海市民。有了互联网,80岁的乌镇老太太可以用手机购物,开直播,成为“网红”。这样的故事还有很多很多。 然而科技并

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

Android开发之自定义万能BaseAdapter

话不多说哦,直接上模板: package com.zyzpp.adapter; import android.content.Context; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; public abstract class MyAdapter<T> extends BaseAdapter { private ArrayList<T> mData; private int mLayoutRes; //布局id public MyAdapter() { } public MyAdapter(ArrayList<T> mData, int mLayoutRes) { this.mData = mData; this.mLayoutRes = mLayoutRes; } @Override public int getCount() { return mData != null ? mData.size() : 0; } @Override public T getItem(int position) { return mData.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = ViewHolder.bind(parent.getContext(), convertView, parent, mLayoutRes , position); bindView(holder, getItem(position)); return holder.getItemView(); } public abstract void bindView(ViewHolder holder, T obj); //添加一个元素 public void add(T data) { if (mData == null) { mData = new ArrayList<>(); } mData.add(data); notifyDataSetChanged(); } //往特定位置,添加一个元素 public void add(int position, T data) { if (mData == null) { mData = new ArrayList<>(); } mData.add(position, data); notifyDataSetChanged(); } public void remove(T data) { if (mData != null) { mData.remove(data); } notifyDataSetChanged(); } public void remove(int position) { if (mData != null) { mData.remove(position); } notifyDataSetChanged(); } public void clear() { if (mData != null) { mData.clear(); } notifyDataSetChanged(); } public static class ViewHolder { private SparseArray<View> mViews; //存储ListView 的 item中的View private View item; //存放convertView private int position; //游标 private Context context; //Context上下文 //构造方法,完成相关初始化 private ViewHolder(Context context, ViewGroup parent, int layoutRes) { mViews = new SparseArray<>(); this.context = context; View convertView = LayoutInflater.from(context).inflate(layoutRes, parent, false); convertView.setTag(this); item = convertView; } //绑定ViewHolder与item public static ViewHolder bind(Context context, View convertView, ViewGroup parent, int layoutRes, int position) { ViewHolder holder; if (convertView == null) { holder = new ViewHolder(context, parent, layoutRes); } else { holder = (ViewHolder) convertView.getTag(); holder.item = convertView; } holder.position = position; return holder; } @SuppressWarnings("unchecked") public <T extends View> T getView(int id) { T t = (T) mViews.get(id); if (t == null) { t = (T) item.findViewById(id); mViews.put(id, t); } return t; } /** * 获取当前条目 */ public View getItemView() { return item; } /** * 获取条目位置 */ public int getItemPosition() { return position; } /** * 设置文字 */ public ViewHolder setText(int id, CharSequence text) { View view = getView(id); if (view instanceof TextView) { ((TextView) view).setText(text); } return this; } /** * 设置图片 */ public ViewHolder setImageResource(int id, int drawableRes) { View view = getView(id); if (view instanceof ImageView) { ((ImageView) view).setImageResource(drawableRes); } else { view.setBackgroundResource(drawableRes); } return this; } /** * 设置点击监听 */ public ViewHolder setOnClickListener(int id, View.OnClickListener listener) { getView(id).setOnClickListener(listener); return this; } /** * 设置可见 */ public ViewHolder setVisibility(int id, int visible) { getView(id).setVisibility(visible); return this; } /** * 设置标签 */ public ViewHolder setTag(int id, Object obj) { getView(id).setTag(obj); return this; } /** * 设置文字and颜色 */ public ViewHolder setTextAndColor(int id, CharSequence text,int color) { View view = getView(id); if (view instanceof TextView) { ((TextView) view).setText(text); ((TextView) view).setTextColor(color); } return this; } //其他方法可自行扩展 } } 下面说一下ListView(GridView)的使用流程: private void useListView() { //绑定View listview = (ListView) view.findViewById(R.id.grid_ico); //添加头部View listview.addHeaderView(headview); //添加数据 mData = new ArrayList<>(); mData.add(new ListItem(R.mipmap.dot, "这是自定义JavaBean")); //添加数据源 mAdapter = new MyAdapter<ListItem>(mData, R.layout.item_grid_icon) { @Override public void bindView(ViewHolder holder, ListItem obj) { holder.setImageResource(R.id.img_icon, obj.getId()); holder.setText(R.id.txt_js, obj.getContent()); } }; //把数据源set进视图 listview.setAdapter(mAdapter); //监听点击事件 listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(getActivity(), "你点击了~" + position + "~项", Toast.LENGTH_SHORT).show(); switch (position) { case 1: break; } } }); //监听长按事件 listview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(getActivity(), "你长按了第~" + position + "~项", Toast.LENGTH_SHORT).show(); return true; //默认不处理返回false } }); }

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

spark能传递外部命名参数给main函数吗?

查了资料好像都没有办法。只能通过: def main(args: Array[String]): Unit = { // 读取参数 var city = args(0) var input = args(1) var date = args(2) 下标来获取。不过不确定,去stackoverflow发帖问下。 https://stackoverflow.com/questions/46845292/can-spark-submit-with-named-argument/46845525#46845525 确实不能,如果要的话,就需要自己写代码来解析: object CommandLineUtil { def getOpts(args: Array[String], usage: String): collection.mutable.Map[String, String] = { if (args.length == 0) { log.warn(usage) System.exit(1) } val (opts, vals) = args.partition { _.startsWith("-") } val optsMap = collection.mutable.Map[String, String]() opts.map { x => val pair = x.split("=") if (pair.length == 2) { optsMap += (pair(0).split("-{1,2}")(1) -> pair(1)) } else { log.warn(usage) System.exit(1) } } optsMap } } val usage = "Usage: [--citys] [--num]" val optsMap = CommandLineUtil.getOpts(args, usage) val citysValue = optsMap("citys") val numValue = optsMap("num") 本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/p/7719722.html,如需转载请自行联系原作者

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

假如有一天,AI能自我“繁殖”?

你想过一种能够建设人工智能的人工智能吗?这可能是研究者的梦想,程序员的噩梦。 纽约时报近日就刊登了一篇题为《Building A.I. That Can Build A.I.》的文章,向我们介绍了谷歌AutoML的一些情况,雷锋网在不改变原意的情况下进行了编译。 在最近于硅谷和中国的演讲中,谷歌的大牛Jeff Dean着重介绍了谷歌的AutoML项目。AutoML,顾名思义,就是学习构建其他机器学习算法的机器学习算法。 Jeff Dean是一名出色的计算机科学家和软件工程师,目前,他是谷歌大脑团队中的高级成员(Fellow)。谷歌许多业务的底层架构和系统都是由他参与建设的,如Big Table 和Map Reduce,在国外知乎Quara上,有答主曾如此夸张地形容这位大牛:编译器从不警告Jeff Dean,只有Jeff Dean警告编译

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

内容能修改了

【大咖・来了 第7期】10月24日晚8点观看《智能导购对话机器人实践》 一直以来,新浪微博内容发布之后无法修改都是网友们吐槽最严重的地方,毕竟如果打错一个字的话,就要删除重新发布实在有点麻烦。 现在,微博似乎真的准备对这一功能进行调整了。 昨天下午,微博 CEO@来去之间公布一张内部会议的图片,图片显示新浪微博在未来会增加两大功能,一是微博发布内容后可编辑;二是博主对评论的先审后放。 毫无疑问,增加“发布内容后可编辑”功能之后可大大降低因错字删除微博的几率,但理论上,新浪也会加以限制,不可能任意进行修改。 至于“博主对评论的先审后放”,理论上应该就是会员才能享受的功能了,普通用户是无缘使用的。 值得一提的是,@来去之间还把图片打了码,可能是一个目前尚不愿公开的重磅功能。

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

代码中的汉字 为什么能挡住CIA黑客

日前,维基解密爆料,CIA通过恶意软件等网络武器控制大量美国、欧洲等地企业的电子设备及操作系统产品,包括苹果手机、谷歌安卓系统、微软视窗系统和三星智能电视,把它们变成麦克风进行窃听,并将录音传输到中情局服务器上。 此外,维基解密爆料的一份文件中显示:执行中国任务的特工深受语言障碍的困扰。《参考消息》还以《维基解密网披露代码中的汉字挡住CIA黑客》为标题做了报道。那么,中文挡住CIA黑客究竟是怎么回事呢? 中文并不是抵挡CIA黑客的长远之计 虽然参考消息的报道以《维基解密网披露代码中的汉字挡住 CIA黑客》为标题,且该标题颇有因为中文使CIA黑客束手无策,无法窃取中国秘密资料的含义。但事实上,这仅仅是CIA黑客看不懂中文导致的,若要实现 信息安全,仅仅依靠源代码中的中文或中文注释是远远不够的,而且这也非长远之计。 由于绝大多数程序代码都是用通用编程语言写成,这些英文字母组成的代码,全球程序员都认识,但认识代码归认识,能不能彻底解读就是另一回事了——源代码一般都是比较晦涩的,没有注释的代码换了开发这个程序的工程师之外的人来读其实是很难读懂的。 “维基解密”近期公布的文件显示,美国中情局通过各种方式攻击了中国等很多国家的电子设备。外交部回应:敦促美方攻击停止。 因此,注释就伴随源代码而生,注释的作用是便于理解和交接给其他人,告诉别人代码实现的功能,如果看不懂源代码的注释,或者源代码根本就没有注释,那即便拿到了源代码也犹如天书。 国内一些企业和境外企业合资做CPU,或买授权做SOC,以及合资做所谓的Windows 10政府版操作系统,虽然购买了境外企业的授权,有可能获得了部分源代码,但设计文档和注释这些一般是无法从境外国际公司处获取的。这也是为什么,无论是CPU,还是操作系统,虽然在“十二五”期间,一些企业得到巨额专项资金扶持,但耗费数年时间和巨额资金,至今依旧拿境外技术穿马甲的原因之一。 而这次维基解密曝光的情况,其实是CIA黑客通过特殊手段获得源代码后,发现源代码没有英文注释所以读不懂。 虽然不少科班出身的程序员,一般都是循规蹈矩按部就班的用英文注释。但由于部分中国的软件工程师英文水平不够高,甚至一些程序员的英文其实非常有限,如果用英文注释很可能会出不少问题,因此会在源代码中用中文做注释。 在英文水平有限的情况下,如果用英文而不是中文注释的话,可能会有翻译错误、字母打错、以及英文专用名词过于生僻等一些问题。举例来说,比如创建时间,一般翻译CreateTime,但是也有人写成BuildDate,甚至有的时候会有字母打错,变成BuildData的情况,这种还是算能够看出来是打错字母的。 更多时候,打错字母的英文单词会导致其他程序员解读难度大幅攀升,怎么猜测都不对。如果用中文的话,不仅方便国内同行理解,也可以少发生产生歧义的情况。 另外,由于英文专业名词都是非常生僻的,非该专业领域的业内人士根本不认识该专业的相关专业术语的英文单词。以电力方面来说,程序员仅仅是码农,不是电力工程师,这就导致国内软件工程师在接国内项目后,根本不知道相关专业术语的英文单词,在这种情况下,就直接用中文或者拼音了。 一位软件工程师告诉笔者,“在XX电网的时候开发一套系统,里面上千个电网专业术语,如果用英文,可以撞头去死了……所以注释一般用中文,程序变量名用拼音”。其实,国内不少大公司也是会用中文拼音的。 而本次CIA黑客受阻于中文的真正原因,是因为中文博大精深,而国内程序员写了中文注释又很随意,没有一定的汉语文化功底的CIA黑客很难理解中文注释,所以出现了拿到了源代码,但是因为无法理解源代码中的中文注释而看不懂的情况。 不过,随着CIA招募掌握中文的黑客参与相关工作,看不懂源代码中的中文而产生的问题将不复存在。 维基解密称CIA把欧洲黑客“老巢”建在美国驻德国法兰克福领事馆 打铁还需自身硬 根据斯诺登的披露,美国政府一直通过各种手段对全球很多国家实施监控和网络攻击,除了传统的攻击服务器和PC获得其他国家机密数据之外,随着物联网和各种智能硬件设备的兴起,网络安全和抵御网络攻击的难度大幅攀升。 目前,各种智能硬件设备的增长如井喷之势,2016年约有1.7亿人购买各种物联网的礼品,到2020年,物联网连接的智能设备有望在全球增加到500亿台。加上即将到来的5G时代,会实现万物相连。不仅智能空调、智能电视、智能洗衣机等智能家电会和手机等个人智能终端设备,以及PC相连接,各种摄像头监控设备、智能扬声器、汽车电子、医疗器械、工业生产设备等智能硬件也会通过网络相连。而这些智能硬件设备都有CPU、内存、操作系统,虽然模样千奇百怪,但其实都是一台迷你电脑。 更致命的是,这些智能硬件设备中很大一部分近乎是不设防的,在软件上由于长年得不到更新维护,软件系统存在大量漏洞。而很多智能硬件设备对CPU性能要求不高,反而对功耗和成本非常敏感,因而往往采用近乎于老掉牙的芯片。诚然,这些老芯片在经过多年使用和验证,有着相对成熟的优势。但由于芯片破解难度和芯片的复杂度成正比,加上有充足的时间去破解,因而在安全性上可能存在一定瑕疵。此外,由于西方科技公司往往和所在国政府存在某些合作,因而很多国家的互联网和各种智能硬件设备完全暴露在国家级黑客的攻击之下。 举例来说,维基解密就公布了CIA利用各种技术在电脑、手机平台上的Windows、iOS、Android等各类操作系统下发起入侵攻击,以及操作智能电视、智能监控设备等终端设备进行窃密的文件。最惊悚的是,CIA还可以遥控智能汽车发起暗杀行动。 因此,要实现网络安全,保护国家机密和个人隐私,必须采取技术手段,而非源代码中加入一些中文内容。 技术手段主要解决的是境外国家级攻击者,正面捅刀子和背后捅刀子的问题。 所谓背后捅刀子,就是国人使用的网络设备、电脑、服务器、智能穿戴设备、手机等产品在软件上和硬件上被境外科技公司留下了各种后门,这样国家级攻击者就可以通过这些后门肆意窃取国家秘密和个人隐私。 而境外国家级黑客攻击就是正面捅刀子,面对正面捅刀子,就必须从软件和硬件上加强防护措施,防止非法访问和修改。 对付背后捅刀子,最好的方式就是从软件和硬件上实现国产自主+安全可信,采用国内自主设计、代工生产封装的CPU和自研的操作系统去取代国外的产品。而且这也是对付正面捅刀子的前提条件,因为如果自己不掌握核心技术,依靠购买国外产品的话,老外卖给你什么,你用什么,就没法从整体上考虑安全方案,就很难提升面对黑客攻击的防御能力。 此外,固件也非常重要,固件就是硬件和操作系统之间的部分,基本功能是用来配置硬件引导系统。bios是计算机里最重要的固件之一,nsa、cia和hacking team都很喜欢通过bios植入木马。服务器里还有bmc固件,用来监控管理服务器。在防御黑客的方面,由于bios比操作系统先运行,在把控制权传递给操作系统的时候,bios可以去检验要运行的系统是不是符合预期,是否被篡改,因而bios可以通过传递信任关系到操作系统,让恶意代码无法执行。因此,固件在安全里有非常重要的位置。 总之,源代码中存在中文这仅仅是一个小障碍,而非不可逾越的技术瓶颈。至于用中文编程是根本没有必要的,虽然用中文编程可以解决一些中国人不懂英文的问题,然而现在英文是事实的世界语言,作为程序员不懂英文就没法跟其他国家的人交流,最后很有可能会走到闭门造车的路上,反而得不偿失。要真正提升抵御网络攻击的防御能力,最好的做法是采用自主研发的产品取代国外产品,并在实践中不断使用、磨合、检验,最终实现螺旋式提升。 作者:佚名 来源:51CTO

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

深度学习并非万能,你用对了吗?

[ 导读 ]深度学习随着AlphaGo大胜李世石之后被“神话”,很多人认为深度学习就是挑战人类智力的“神器”。可是,深度学习真的如他们想象的那般“战无不胜”吗?本文编译自hyperparameter.space,作者是Pablo Cordero,就读于加利福尼亚大学圣克鲁斯校区,主攻方向为细胞生物学和再生医学背景下的应用机器学习研究。阅读此文后,你便能够从深层理解,为什么深度学习其实并不像普通百姓想象的那般“神”了,甚至,你还会发现它有时还有些“笨”。 我知道以一种较为消极的态度来作为博客的开头是很奇怪的方式,但是在过去几天里有一波讨论,我认为这是关于我最近一直在思考的话题一个很好的切入点。这一切都从Jeff Leek在Simply Stats博客中发表了一篇关于在小样本规模体系中使用深度学习的注意事项开始的。总之,他认为,当样本量

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

订阅服务能一解SSL证书管理难题吗?

证书误用和滥用已经成为企业颇为忧心的问题,我们需要找到能够解决问题以及改善SSL证书管理的有效方法。那么SSL证书订阅服务会是这一难题的解决方法吗?什么样的企业会从中受益? Michael Cobb:处理敏感或私人身份信息的网站应该已经在使用安全通信协议HTTPS来传送网页,用户及其服务器上的数据交换通过SSL/TLS来加密。然而,网页管理员常常是在所有网站和页面上部署Web服务器数字证书及动态的HTTPS,即使他们并不需要传输敏感信息,他们所提供的身份认证和加密可以防止第三方看到、记录或是篡改用户会话内容。 HTTPS没有在互联网上普及开来有多种原因,最主要一点就是证书安装、配置和运作的成本。(鉴于SPDY和HTTP/2的协议能够减少加载时间,关于HTTPS需要占用更多服务器资源并减慢页面加载时间的争议已不再是问题。)对于企业来说,大量的数字证书管理运营成本较高,HydrantID的SSL订阅服务就是为了解决这种问题,通过其服务让SSL证书管理更便宜、更为轻松。 订阅HydrantID服务可为企业提供一个简化SSL证书管理的云平台,特定类型的SSL证书是按月付费。其目的是让企业集中管理所有的证书,减少由于管理不善造成更新失败带来的风险。应用这类的SSL证书管理服务需要信任HydrantID的云系统及其发行证书背后的基础架构。由于CA发行的一些错误证书,会让黑客滥用虚假证书,并发动诸如网络欺诈、服务器模拟和中间人这类的攻击,企业对证书信任度并不太好。 使用HTTPS互联网可以提供更好的安全性和隐私性,且市场上有不同的方案可供企业购买和管理数字证书,举例来说,StartSSL提供免费的数字证书、二级和三级的证书不到60美元。企业无论选择何种证书,管理员都应该确保其正确安装,且网页中不含有通过未加密HTTP传送的任何内容。 作者:Michael Cobb 来源:51CTO

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

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文件系统,支持十年生命周期更新。

用户登录
用户注册