首页 文章 精选 留言 我的

精选列表

搜索[实时风控],共10000篇文章
优秀的个人博客,低调大师

HBase实操 | 使用Java调用HBase的Endpoint Coprocessor

1.文档编写目的 HBase是一款基于Hadoop的Key-Value数据库,提供了对HDFS上数据的高效随机读写服务,填补了Hadoop MapReduce批处理的缺陷,但HBase作为列簇数据库无法轻易的建立“二级索引”、难以执行求和、计数、排序等操作。在HBase0.96版本后引入了协处理器(Coprocessor),用户可以编写运行在HBase Server端的代码。HBase支持两种类型的协处理器,Endpoint和Observer。 Endpoint协处理器类似传统数据库中的存储过程,客户端可以调用这些Endpoint协处理器执行一段Server端代码,并将Server端代码的结果返回给客户端处理。 Observer Coprocessor,这中协处理器类似于传统数据库中的触发器,当发生某些事件的时候,Observer协处理

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

Maxcompute Spark作业管控利器—Cupid Console

一、背景 Maxcompute平台目前可以支持运行Spark作业,Spark作业依托于Maxcompute的Cupid平台可以按照社区兼容的方式提交到Maxcompute上运行,支持读写Maxcompute表,和Maxcompute上原有的SQL/MR等作业共用Project的资源。相关产品的详细介绍可以参考官方文档:https://help.aliyun.com/document_detail/102357.html Maxcompute Spark作业也是Maxcompute平台上的一种作业类型,和其他作业一样,每一个Spark作业都具有一个唯一的InstanceId,可以通过InstanceId来管理相应的Spark作业,比如通过InstanceId我们可以获取到作业的Logview和停止作业。但是目前通过Ins

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

【DevOps】第3步:中控平台jenkins

一,安装 服务器安装 以centos7为例 1, 安装 添加yum repos,然后安装 sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo sudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key sudo yum install jenkins 2, 如果没有java的话要安装java sudo yum install java 3. 启动和停止 sudo service jenkins start/stop/restart sudo chkconfig jenkins on #开机自启动 4. 更换主目录 参考:jenkins 更换主目录 容器安装 jenkins官方镜像:https://hub.docker.com/_/jenkins,选择合适的tag。 创建docker-compose.yml文件: version: '2' services: jenkins: image: jenkins/jenkins:2.168-alpine volumes: - ./jenkins_data:/var/jenkins_home ports: - "8080:8080" restart: always volumes: 配置是将jenkins文件夹挂载在宿主机,做持久化处理。ports: 将jenkins容器的8080端口映射至主机的8080端口restart: 自动重启注意:宿主机jenkins_data目录需要给读写权限 二、访问 http://localhost:8080/ 第一次访问: 在服务器上的/var/lib/jenkins/secrets/initialAdminPassword 处拷贝初始密码,继续。 安装插件:完成 三、配置 1,配置凭据 配置访问远程服务器的账号密码 2,配置远程服务器 Jenkins-> 配置->系统配置 注:需安装SSH Plugin插件,才会有SSH remote hosts这一项。 3,配置Job信息 参考批量创建Job 4,授权子用户 安装插件:Role-based Authorization Strategy jenkins->全局安全设置: 改为Role-Based Stategy系统管理中会出现【Manage and Assign Roles】选项,点击进入 参考:http://blog.51cto.com/zengestudy/1782494 四、Job任务创建示例 1,新建项目 2,配置 源码管理 构建触发器 Poll SCM 配置为每半小时扫描一次源码变动。 构建 五、主从节点设置 系统管理->管理节点-> 新建节点 创建好的节点列表如下: 六、job配置备份 安装插件:ThinBackup安装完成后在系统管理列表下方会出现ThinBackup的图标。点击进入后有3个选项: Backup Now Restore Settings 要做到自动备份,就在Settings中修改: 七、问题解决 1,出现报错 Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post 权限问题,执行如下命令: 1183 2018-03-20 00:32:26 sudo usermod -a -G root jenkins 1184 2018-03-20 00:32:33 sudo service jenkins restart 1185 2018-03-20 00:34:29 chmod 664 /var/run/docker.sock 1186 2018-03-20 00:34:56 chmod 777 /var/run/docker.sock 1187 2018-03-20 00:35:04 sudo service jenkins restart 或者 [root@VM_32_86_centos fof_api]# usermod -a -G root jenkins [root@VM_32_86_centos fof_api]# usermod -a -G docker jenkins [root@VM_32_86_centos fof_api]# sudo service jenkins restart 2, jenkins mvn: command not found Jenkins 通过shell脚本调用mvn 命令的时候,是从/usr/bin 文件夹中找命令的,这个时候需要做个软链接 ln –s /opt/maven/bin/mvn /usr/bin/mvn 参考 https://testerhome.com/topics/10055 http://www.cnblogs.com/reblue520/p/7130914.html centos7安装jenkins https://segmentfault.com/a/1190000007837054 Centos 7安装 jdk 8 jenkins权限管理,不同用户显示不同项目 批量克隆jenkins的job

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

用 NTP 把控时间(一):使用概览

这系列共三部分,首先,Chirs Binnie 探讨了在一个合理的架构中 NTP 服务的重要性。 鲜有互联网上的服务能如时间服务一样重要。影响你系统计时的小问题可能需要一两天才能被发现,而这些不期而遇的问题所带来的连锁反应几乎总是让人伤脑筋的。 设想你的备份服务器与网络时间协议(NTP)服务器断开连接,过了几天,引起了几小时的时间偏差。你的同事照常九点上班,发现需要大量带宽的备份服务器消耗了所有网络资源,这也就意味着他们在备份完成之前几乎不能登录工作台开始他们的日常工作。 这系列共三部分,首先,我将提供简要介绍 NTP 来防止这种困境的发生。从邮件的时间戳到记录你工作的进展,NTP 服务对于一个合理的架构是如此的重要。 可以把如此重要的 NTP 服务器(其他的服务器从此获取时钟数据)看做是倒置金字塔的底部,它被称之为一层Stratum 1服务器(也被称为“主primary”服务器)。这些服务器与国家级时间服务(称为零层Stratum 0,通常这些设备是是原子钟和 GPS 钟之类的装置)直接交互。与之安全通讯的方法很多,例如通过卫星或者无线电。 令人惊讶的是,几乎所有的大型企业都会连接二层Stratum 2服务器(或“次级secondary”服务器)而是不是主服务器。如你所料,二层服务器和一层直接同步。如果你觉得大公司可能有自己的本地 NTP 服务器(至少两个,通常三个,为了灾难恢复之用),这些就是三层服务器。这样,三层服务器将连接上层预定义的次级服务器,负责任地传递时间给客户端和服务器,精确地反馈当前时间。 由简单设计而构成的 NTP 可以工作的前提是——多亏了通过互联网跨越了大范围的地理距离——在确认时间完全准确之前,来回时间(包什么时候发出和多少秒后被收到)都会被清楚记录。设置电脑的时间的背后要比你想象的复杂得多,如果你不相信,那这神奇的网页值得一看。 再次重提一遍,为了确保你的架构如预期般工作,NTP 是如此的关键,你的 NTP 与层次服务器之间的连接必须是完全可信赖并且能提供额外的冗余,才能保持你的内部时钟同步。在NTP 主站有一个有用的一层服务器列表。 正如你在列表所见,一些 NTP 一层服务器以 “ClosedAccount” 状态运行;这些服务器需要事先接受才可以使用。但是只要你完全按照他们的使用引导做,“OpenAccess” 服务器是可以用于轮询使用的。而 “RestrictedAccess” 服务器有时候会因为大量客户端访问或者轮询间隙太小而受限。另外有时候也有一些专供某种类型的组织使用,例如学术界。 尊重我的权威 在公共 NTP 服务器上,你可能发现遵从某些规则的使用规范。现在让我们看看其中一些。 “iburst” 选项作用是如果在一个标准的轮询间隔内没有应答,客户端会发送一定数量的包(八个包而不是通常的一个)给 NTP 服务器。如果在短时间内呼叫 NTP 服务器几次,没有出现可辨识的应答,那么本地时间将不会变化。 不像 “iburst” ,按照 NTP 服务器的通用规则, “burst” 选项一般不允许使用(所以不要用它!)。这个选项不仅在轮询间隔发送大量包(明显又是八个),而且也会在服务器能正常使用时这样做。如果你在高层服务器持续发送包,甚至是它们在正常应答时,你可能会因为使用 “burst” 选项而被拉黑。 显然,你连接服务器的频率造成了它的负载差异(和少量的带宽占用)。使用 “minpoll” 和 “maxpoll” 选项可以本地设置频率。然而,根据连接 NTP 服务器的规则,你不应该分别修改其默认的 64 秒和 1024 秒。 此外,需要提出的是客户应该重视那些请求时间的服务器发出的“亲一下就死(死亡之吻)Kiss-Of-Death” (KOD)消息。如果 NTP 服务器不想响应某个特定的请求,就像路由和防火墙技术那样,那么它最有可能的就是简单地遗弃或吞没任何相关的包。 换句话说,接受到这些数据的服务器并不需要特别处理这些包,简单地丢弃这些它认为这不值得回应的包即可。你可以想象,这并不是特别好的做法,有时候礼貌地问客户是否中止或停止比忽略请求更为有效。因此,这种特别的包类型叫做 KOD 包。如果一个客户端被发送了这种不受欢迎的 KOD 包,它应该记住这个发回了拒绝访问标志的服务器。 如果从该服务器收到不止一个 KOD 包,客户端会猜想服务器上发生了流量限速的情况(或类似的)。这种情况下,客户端一般会写入本地日志,提示与该服务器的交流不太顺利,以备将来排错之用。 牢记,出于显而易见的原因,关键在于 NTP 服务器的架构应该是动态的。因此,不要给你的 NTP 配置硬编码 IP 地址是非常重要的。通过使用 DNS 域名,个别服务器断开网络时服务仍能继续进行,而 IP 地址空间也能重新分配,并且可引入简单的负载均衡(具有一定程度的弹性)。 请别忘了我们也需要考虑呈指数增长的物联网(IoT),这最终将包括数以亿万计的新装置,意味着这些设备都需要保持正确时间。硬件卖家无意(或有意)设置他们的设备只能与一个提供者的(甚至一个) NTP 服务器连接终将成为过去,这是一个非常麻烦的问题。 你可能会想象,随着买入和上线更多的硬件单元,NTP 基础设施的拥有者大概不会为相关的费用而感到高兴,因为他们正被没有实际收入所困扰。这种情形并非杞人忧天。头疼的问题多呢 -- 由于 NTP 流量导致基础架构不堪重负 -- 这在过去几年里已发生过多次。 原文发布时间为:2017-04-28 本文来自云栖社区合作伙伴“Linux中国”

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

原来Android触控机制竟是这样的?

image 有什么料? 从这篇文章中你能获得这些料: 了解一次触摸事件究竟是如何产生的? 了解触摸事件究竟是如何传递的? 学会从根源处分析你的App中的滑动冲突。 能够更自信的创作出具有复杂交互的App。 收获一张图,帮助你理解和使用Android的触摸事件分发。 link 老规矩,先来看图吧。 image 在你触摸屏幕之后 首先在上图中找到那只黑手,它是一次触摸事件的开始。 当屏幕被触摸,Linux内核会将硬件产生的触摸事件包装为Event存到/dev/input/event[x]目录下。对,你没看错,事件被搞成文件保存了下来! 接着,系统创建的一个InputReaderThread线程loop起来让EventHub调用getEvent()不断的从/dev/input/文件夹下读取输入事件。 然后InputReader则从EventHub中获得事件交给InputDispatch。 而InputDispatch又会把事件分发到需要的地方,比如ViewRootImpl的WindowInputEventReceiver中。 以上过程是在底层中完成,大部分由c++实现,我们了解流程就行。 image 下面从ViewRootImpl收到触摸事件开始分析触摸事件的去向。 触摸事件的旅行 第一站:从InputEventReceiver开始 我们现在图中找到WindowInputReceiver。可以看到,它继承了InputEventReceiver,并且是ViewRootImpl的一个内部类。 ViewRootImpl.java final class WindowInputEventReceiver extends InputEventReceiver{ @Override public void onInputEvent(InputEvent event) { ... enqueueInputEvent(event, this, 0, true); ... } } 当一个输入事件产生时(这里我们认为是触摸事件),会回调InputEventReceiver.onInputEvent()。从名字也可以看出,它是接收输入事件的。然后进一步调用 ViewRootImpl.enqueueInputEvent() 将输入事件加入单链表队列。 ViewRootImpl.java void enqueueInputEvent(InputEvent event, InputEventReceiver receiver, int flags, boolean processImmediately) { ... mPendingInputEventTail = q; //进行队列操作后, //将ViewRootImpl的mPendingInputEventTail复制为新的触摸事件。 ... if (processImmediately) { doProcessInputEvents(); //立即处理事件 } else { scheduleProcessInputEvents(); //走一遍Handler延迟处理事件 } } 上面这个方法主要对触摸事件进行队列操作(即排了个序),然后再根据processImmediately参数,决定是立即处理,还是延后处理。 下面看看是如何进行处理的。 void doProcessInputEvents() { while (mPendingInputEventHead != null) { ... deliverInputEvent(q); //进一步派发事件处理 ... } } 在这个方法中有一个while{}循环体。它会将事件队列循环处理,直到队列中没有数据为止。如何处理呢?我们看看deliverInputEvent()。 private void deliverInputEvent(QueuedInputEvent q) { ... InputStage stage; if (q.shouldSendToSynthesizer()) { stage = mSyntheticInputStage; } else { stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage; } //上面决定将事件派发到那个InputStage中处理 if (stage != null) { stage.deliver(q); //派发事件到InputStage中处理 } else { finishInputEvent(q); } } 这里说一下有意思的InputStage。 image 在ViewRootImpl中,有这样一段代码: public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { ... // mSyntheticInputStage = new SyntheticInputStage(); InputStage viewPostImeStage = new ViewPostImeInputStage(mSyntheticInputStage); InputStage nativePostImeStage = new NativePostImeInputStage(viewPostImeStage, "aq:native-post-ime:" + counterSuffix); InputStage earlyPostImeStage = new EarlyPostImeInputStage(nativePostImeStage); InputStage imeStage = new ImeInputStage(earlyPostImeStage, "aq:ime:" + counterSuffix); InputStage viewPreImeStage = new ViewPreImeInputStage(imeStage); InputStage nativePreImeStage = new NativePreImeInputStage(viewPreImeStage, "aq:native-pre-ime:" + counterSuffix); // mFirstInputStage = nativePreImeStage; // mFirstPostImeInputStage = earlyPostImeStage; ... } 如你所见,InputStage 是在setView()的时候创建的,也就是在Activity的onResume()阶段,关于这点,你可以看看我这篇文章:【用两张图告诉你,为什么你的App会卡顿?http://www.jianshu.com/p/df4d5ec779c8】。这些InputStage也相当于是单链表结构,一个套一个。也就是说,比如调用了mFirstPostImeInputStage.deliver(q)。那么SyntheticInputStage, ViewPostImeInputStage, NativePostImeInputStage, EarlyPostImeInputStage都将能够处理这个触摸事件。这里我们主要看看ViewPostImeInputStage是如何处理的。 final class ViewPostImeInputStage extends InputStage { public final void deliver(QueuedInputEvent q) { ... apply(q, onProcess(q)); //onProcess()中处理处理事件 ... } @Override protected int onProcess(QueuedInputEvent q) { ... return processPointerEvent(q); //处理点触摸事件 ... } private int processPointerEvent(QueuedInputEvent q) { final MotionEvent event = (MotionEvent)q.mEvent; ... final View eventTarget = (event.isFromSource(InputDevice.SOURCE_MOUSE) && mCapturingView != null) ? mCapturingView : mView; //DecorView ... boolean handled = eventTarget.dispatchPointerEvent(event); //eventTarget一般取到mView,即DecorView ... return handled ? FINISH_HANDLED : FORWARD; } } 啊哈,这段代码稍有点长。但是过程很简单。ViewPostImeInputStage.deliver(q)调用后,会进一步调用onProcess()处理。对于点触摸事件会再进一步调用processPointerEvent()处理,并且在这个方法中,通过eventTarget.dispatchPointerEvent(event)将触摸事件传递给了DecorView的dispatchPointerEvent()处理。 现在越来越清晰了。触摸事件几经辗转终于传递到了View上。赶紧接着看看触摸事件后面的旅途是怎样的? 奇怪的辗转 上面说到触摸事件传递到了DecorView.dispatchPointerEvent()中。在图中找到对应位置哦。看看在这个方法中发生了什么? 找了一会儿可能在DecorView中没有找到dispatchPointerEvent()方法?哈哈,那一定在更上级。事实上,这个方法是在View中实现的。View.java public final boolean dispatchPointerEvent(MotionEvent event) { ... return dispatchTouchEvent(event); //这个方法大家该熟悉了吧? ... } 由于调用的是DecorView.dispatchPointerEvent(),所以上面调用的dispatchTouchEvent(event)实际是DecorView中的。多态!知识点啊!忘了吧?面壁思过吧。DecorView.java @Override public boolean dispatchTouchEvent(MotionEvent ev) { final Window.Callback cb = mWindow.getCallback(); //还记得Activity实现了Window.Callback接口吗? return cb != null && !mWindow.isDestroyed() && mFeatureId < 0 ? cb.dispatchTouchEvent(ev) //通常是走这。 : super.dispatchTouchEvent(ev); } 在DecorView.dispatchTouchEvent()中,又把事件传递到了Activity中去了。WHAT?(需要说明一点,Activity实现了Window.Callback,并且在PhoneWindow创建后立即调用Window.setCallback(this),把Activity设置为PhoneWindow的Window.Callback。)好吧,再到Activity中看看发生了什么?Activity.java public boolean dispatchTouchEvent(MotionEvent ev) { ... if (getWindow().superDispatchTouchEvent(ev)) { //又把事件传到了Window中! return true; } return onTouchEvent(ev); //这就是为什么最后事件没有被消费的话,Activity会去处理的原因。 } 如你所见,事件又被传递到了PhoneWindow中去了。我的天,不是都到View里了吗?为什么还要一直传递?好吧,继续看应该就知道了。 image PhoneWindow.java @Override public boolean superDispatchTouchEvent(MotionEvent event) { return mDecor.superDispatchTouchEvent(event); } WTF?mDecor分明就是DecorView嘛。关于这点,你可以看看我这篇文章:【用两张图告诉你,为什么你的App会卡顿?http://www.jianshu.com/p/df4d5ec779c8】。为什么来回捣腾一圈又回到DecorView中了呢?我们继续看吧。DecorView.java public boolean superDispatchTouchEvent(MotionEvent event) { return super.dispatchTouchEvent(event); //千万不要告诉我你不知道这实际会调用ViewGroup的dispatchTouchEvent()方法啊。 } 好吧,来回绕啊绕,终于到了各大论坛,各大博客,各大书籍所讲的触摸事件分发流程了,即从ViewGroup的dispatchTouchEvent()开始。相信很多同学早已滚瓜烂熟了,但是下面我还是再撸一遍,以保持整个流程的完整性! 辗转的原因 在开始之前,我们思考一下。既然事件最后要看起来是从Activity的dispatchTouchEvent()开始往下分发传递,为什么在InputStage.processPointerEvent()中不直接把事件传递给Activity,而是这样来回绕一圈。这样DecorView -> Activity -> PhoneWindow -> DecorView的来回绕一圈不是很折腾吗?看吧,这就是为什么我一直在说你需要看看这篇文章:【用两张图告诉你,为什么你的App会卡顿?http://www.jianshu.com/p/df4d5ec779c8】的原因。 首先,为了解耦,ViewRootImpl并不知道有Activity这种东西存在!不知道!它只是持有了DecorView。所以,想要直接把触摸事件送到Activity.dispatchTouchEvent() 是不行的。 那么,既然触摸事件已经到了Activity.dispatchTouchEvent()中了,为什么不直接分发给DecorView ,而是要通过PhoneWindow 来间接发送呢?因为Activity 不知道有DecorView 这种奇怪的东西存在啊!不知道!但是,Activity持有PhoneWindow ,而PhoneWindow当然知道自己的窗口里有些什么了,所以能够把事件派发给DecorView 。你看,在Android中,Activity并不知道自己的Window中有些什么,这样耦合性就很低了。我们换一个Window试试?不管Window里面的内容如何,只要Window任然符合Activity制定的标准,那么它就能在Activity中很好的工作。这就是解耦所带来的扩展性的好处。 这是我的想法,童鞋们可以对照着图思考思考。 最后的事件分发 看图中辣眼睛的蓝色部分。这很熟悉了吧?一般讲触摸事件分发就是从这里开始的。 我从DecorView开始。假设ViewGroup_1是DecorView的子View,ViewGroup_2是ViewGroup_1的子View,View是ViewGroup_2的子View。现在,我要开始描述这个过程了啊,这个地方一定要对照着图撸啊。发车了啊,头手不要伸出窗外。 DecorView是ViewGroup,所以dispatchTouchEvent()【分发器】收到触摸事件后,会询问onInterceptTouchEvent()【拦截器】(注意,拦截器是ViewGroup类型的View特有的!)是否需要拦截此次触摸事件?如果拦截返回true,事件将会转到自己的onTouchEvent()【处理器】中处理。如果不拦截,事件将传到它的子View,ViewGroup_1的【拦截器】。 ViewGroup_1的【分发器】被调用后,会询问自己的【拦截器】是否需要拦截此次触摸事件?如果拦截放回true,事件将会转到自己的【处理器】中处理。如果不拦截,事件将传到它的子View,ViewGroup_2的【拦截器】。 ViewGroup_2重复上述步骤。 如果触摸事件到了最后的View中,由于没有【拦截器】,事件将会直接由【分发器】分发到【处理器】中。如果处理了返回true,此次触摸事件的传递到此结束,不会在往下传了。如果不处理,返回false,那么事件将传递到它的父级的【处理器】中。 事实上,不管个层级的【处理器】,如果处理事件返回true,一次触摸事件就结束了。如果不处理事件,返回false,就会传送到上一级的【处理器】中。最终,如果DecorView的【处理器】也不打算处理事件,那么事件将会被发送到Activity的【处理器】中处理。 总结 抽出空余时间写文章分享需要动力,还请各位看官动动小手点个赞,给我点鼓励吧 我一直在不定期的创作新的干货,想要上车只需进到我的【个人主页】点个关注就好了哦。发车喽~ 本篇从一次触摸事件的产生,讲了它的整个传递过程。对着图撸一撸,然后去教训你的App中的各种滑动冲突 、点击穿透吧。 这是一个彩蛋 image 很多筒靴可能走了很多路,但任然不知道onTouchEvent()和onTouch()有何区别?下面将简单的讲一讲。 首先需要知道onTouch()和onTouchEvent()都可以接收到触摸事件,但是onTouch()的优先级比onTouchEvent()更高。也就是说,如果onTouch()把事件处理了,那么onTouchEvent()就接收不到事件了。 onTouch()是专门被设计用来在View外部对触摸事件进行处理的,你可以通过View.setOnTouchListener()来设置一个OnTouchListener。 mView.setOnTouchListener((v, event) -> { LogUtils.e("onTouch"); return true; //返回true才能处理事件。 }); 你看,你其实不必为了处理触摸事件专门自定义View,然后重载onTouchEvent()的。你可以在View外部使用View.setOnTouchListener()来设置一个OnTouchListener 处理。 需要注意一点,不管onTouch()或是onTouchEvent(),即使是返回false,你任然可以收到一次ACTION_DWON事件,但是后面的事件就不能继续收到了。 参考链接 用两张图告诉你,为什么你的App会卡顿?http://www.jianshu.com/p/df4d5ec779c8 InputManagerService分析一:IMS的启动与事件传递http://blog.csdn.net/lilian0118/article/details/28617185 Android跨进程模拟触屏事件(sendevent)http://azard.me/blog/2015/06/13/android-cross-app-touch-event-injection/ Android输入事件流程中的EventHub分析及源码演示http://blog.csdn.net/a345017062/article/details/6417929 Android 4.0 事件输入(Event Input)系统http://blog.csdn.net/myarrow/article/details/7091061 Correctly implementing onInterceptTouchEvent and onTouchEvent methods for ViewGroup:http://neevek.net/posts/2013/10/13/implementing-onInterceptTouchEvent-and-onTouchEvent-for-ViewGroup.html 看到这里的童鞋快奖励自己一口辣条吧!

资源下载

更多资源
Mario

Mario

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

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部分的功能。

用户登录
用户注册