inotifyjava的简单介绍

博主:adminadmin 2022-12-05 15:45:09 70

今天给各位分享inotifyjava的知识,其中也会对进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

如何使用Android Studio开发/调试Android源码

开发调试环境: Ubuntu 14.10,openJdk 1.7,Android Studio 1.0.2,android-5.0.1_r1源码

由于AS是基于IntelliJ IDEA开发的,所以本文也适用于IntelliJ IDEA

一、修改Android Studio(以下简称AS)的内存配置

因为在导入源码时需要消耗大量内存,所以先修改IDEA_HOME/bin/studio64.vmoptions(x86的机器修改studio.vmoptions)中-Xms和-Xmx的值。文档中使用的是748m, 可自行修改。

二、配置AS的JDK、SDK

在IDE中添加一个没有classpath的JDK, 这样可以确保使用源码里的库文件

并将其作为要使用的SDK的Java SDK。如下图

三、生成导入AS所需配置文件(*.ipr)

①编译源码(为了确保生成了.java文件,如R.java;如果编译过,则无需再次编译)

②检查out/host/linux-x86/framework/目录下是否有idegen.jar

如果idegen.jar不存在,执行:

mmm development/tools/idegen/

在5.0.1的源码中会生成res.java的文件夹,导致idegen.jar运行时抛FileNotFoundException,这是idegen的代码不够严谨造成的。

我的分享里有修改这个bug的patch,或者直接使用我分享的idegen.jar。

③执行

development/tools/idegen/idegen.sh

等待出现类似下面的结果:

Read excludes: 5ms

Traversed tree: 44078ms

这时会在源码的根目录下生成android.ipr和android.iml两个IntelliJ IDEA(AS是基于IntelliJ IDEA社区版开发的)的配置文件

Tips:

AS在导入代码时比较慢,建议先修改android.iml,将自己用不到的代码exclude出去.可以仿照过滤.repo文件夹的语法,如:

excludeFolder url="" /

excludeFolder url="" /

excludeFolder url="" /

这样在导入时就会跳过abi和art文件夹.过滤的越多,AS的处理速度就会越快.

④在AS中打开源码根目录下新生成的android.ipr

如果在导入时AS出现

则建议按照其给定的解决方法来解决(网址:),具体内容如下图:

四、解决源码中跳转错误问题

①为当前工程设置正确的SDK和JDK

②设置'Modules'的依赖

先将所有依赖删掉,只留下上图'1'所指向的两个(注意:这里删除全部只是为了方便。如果确实用到了.jar,在将它们的路径添加进来就可以了.

如:5.0.1的ContactsCommon用到了geocoder-2.9.jar和libphonenumber-6.2.jar)

点击上图中'2'指向的'+'并选择上图'3'指向的'Jars or directories'选项,依次将frameworks和external文件夹添加进来.如:

其它版本的代码在添加frameworks时可能会显示成:

没有关系,只是显示问题,点击OK还是会把frameworks路径添加进去的.

如果还有代码跳转错误,请仿照上面的步骤将相应代码的路径或jar文件添加到其Dependencies标签页中即可.

五、DEBUG源码

我们可以通过给刚导入的工程在'Modules'中添加'Android Framework'来让AS将它作为一个Android工程,从而方便我们调试代码.

可以按照上图中'1'和'2'来添加Android Framework支持.

在代码中加断点,然后选择'Run'-'Attach debugger to Android process'或者直接点击下图所示的图标

在弹出的选择进程(Choose Process)对话框中,勾选显示所有进程,选择要DEBUG的代码所在的进程,点击OK即可.

六、其它

代码中很多地方提示Call requires API Level x.... 出现这个问题是因为AS将我们的工程当做安卓应用程序工程了,且源码中没有指定minSdkVersion.

我们只需在源码根目录加一个声明minSdkVersion的AndroidManifest.xml文件即可(分享了一个AndroidManifest.xml)。

也可以考虑使用build.gradle来解决该问题。

云计算主要学习什么课程,跟java有关联吗?

入门学习云计算,必须得会Linux基础和网络基础,包括基本命令的使用,Linux系统的基本结构原理,系统管理,磁盘管理,raid阵列,常见的故障拍错,系统性能的监控调优,网络方面除了学好网络基本原理还要深入tcp/ip http 等;

1、云计算基础,包括Linux云计算网络管理、Linux云主机系统管理和服务配置。学完这部分的内容,可以根据网络协议准确判断error的位置、可以在交换机上进行VLAN的划分、可以利用抓包工具分析网络数据,可以对Linux系统进行基本的管理操作、可以在Linux系统中配置部署域名解析服务、能够在Linux系统中配置LAMP架构的网站服务。

2、云计算高级,包括Linux Shell脚本自动化编程、开源数据库MySQL DBA运维。学完这部分的内容,可以使用awk or sed在命令行中处理文本文件、实现服务器的初始化、批量传输文件、编写运维工具,可以搭建MySQL主从复制的架构实现数据实时备份、可以运维MySQL组建的集群、能够实现数据可视化操作。

3、云计算项目,包括公有云运维实战、大型网站高并发架构运维实战、Web安全渗透攻防项目实战。学完此阶段,可部署出一台服务器给多台主机安装系统、可以利用Ansible管理成千上百台服务器、利用Nginx部署支持高并发的网站、部署Zabbix来监控主机的异常情况以及编写自定义报警处理脚本。

4、企业综合项目,包括企业私有云容器化架构运维实战、企业级大型综合项目实战。学完此阶段,可以做网站的容灾策略,保证服务的在线率、利用Nginx缓存加快用户访问网站的速度、提高网站的并发量,能够在企业中构建私有云平台、维护私有云出现的错误、搭建混合云。

Android输入事件原理总结

接受输入设备的中断,并将原始事件的输入写入设备节点中;

作为内核和IMS的桥梁,将原始事件的数据暴露给用户空间,以便IMS可以从中读取事件;

Android系统服务,它分为java层和native层两部分;java层负责与WMS通信,native层则是InputReader和InputDispatcher两个输入系统关键组件的运行容器;

使用inotify监听输入设备的添加和移除。

使用epoll机制监听输入设备的数据变化。

读取设备文件的数据。

将原始数据(生事件)返回给InputReader。

IMS中的关键组件之一,它运行于一个独立的线程中,负责管理输入设备的列表与配置,以及进行输入事件的加工处理。它通过其线程循环不断地通过getEvents()函数从EventHub中将事件取出并进行处理。对于设备节点的增删事件,它会更新输入设备列表与配置。对于原始输入事件,InputReader对其进行翻译、组装、封装为包含更多信息、更具可读性的输入事件,然后交给InputDispatcher进行派发;

IMS中的另一个关键组件,它也运行于一个独立的线程中。InputDispatcher中保管了来自WMS的所有窗口的信息,其收到来自InputReader的输入事件后,会在其保管的窗口中寻找合适的窗口,并将事件派发给此窗口;

InputChannel支持跨进程传输。

保存socketpair的FD,App进程持有一端,WMS进程持有一端。

InputChannel负责事件最终的读写。

包装了InputChannel,负责将InputChannel的FD加入到main looper并负责读写InputChannel。

将事件封装成Java层的事件对象向上派发给ViewRootImpl。

不是输入系统的一员,但它对InputDispatcher的正常工作起到重要作用。当新建窗口时,WMS为新窗口和IMS创建了事件传递所用的通道。另外,WMS还将所有窗口的信息,包括窗口的可点击区域,焦点窗口等信息,实时的更新到IMS的InputDispatcher中,使得InputDispatcher可以正确地将事件派发到指定的窗口;

对某些窗口,如壁纸窗口、SurfaceView的窗口来说,窗口就是输入事件派发的终点。而对其他的activity、对话框等使用了Android控件系统的窗口来说,输入事件的终点是控件View。ViewRootImpl将窗口所接收的输入事件沿着控件树将事件派发给感兴趣的控件;

INotify是一个Linux内核所提供的一种文件系统变化通知机制。它可以为应用程序监控文件系统的变化,如文件的新建、删除、读写等。INotify机制有两个基本对象,分别为inotify对象与watch对象,都使用文件描述符表示。

inotify对象对应了一个队列,应用程序可以向inotify对象添加多个监听。当被监听的事件发生时,可以通过read()函数从inotify对象中将事件信息读取出来。Inotify对象可以通过以下方式创建:

而watch对象则用来描述文件系统的变化事件的监听。它是一个二元组,包括监听目标和事件掩码两个元素。

当没有监听事件发生时,可以通过如下方式将一个或多个未读取的事件信息读取出来:

总结一下INotify机制的使用过程:

通过inotify_init()创建一个inotify对象。

通过inotify_add_watch将一个或多个监听添加到inotify对象中。

通过read()函数从inotify对象中读取监听事件。当没有新事件发生时,inotify对象中无任何可读数据。

Epoll可以使用一次等待监听多个描述符的可读/可写状态。等待返回时携带了可读的描述符或自定义的数据,使用者可以据此读取所需的数据后可以再次进入等待。因此不需要为每个描述符创建独立的线程进行阻塞读取,避免了资源浪费的同时又可以获得较快的响应速度。

Epoll机制的接口只有三个函数,十分简单。

epoll_create(int max_fds):创建一个epoll对象的描述符,之后对epoll的操作均使用这个描述符完成。max_fds参数表示了此epoll对象可以监听的描述符的最大数量。

epoll_ctl (int epfd, int op,int fd, struct epoll_event *event):用于管理注册事件的函数。这个函数可以增加/删除/修改事件的注册。

int epoll_wait(int epfd, structepoll_event * events, int maxevents, int timeout):用于等待事件的到来。当此函数返回时,events数组参数中将会包含产生事件的文件描述符。

Epoll的使用步骤总结如下:

通过epoll_create()创建一个epoll对象。

为需要监听的描述符填充epoll_events结构体,并使用epoll_ctl()注册到epoll对象中。

使用epoll_wait()等待事件的发生。

根据epoll_wait()返回的epoll_events结构体数组判断事件的类型与来源并进行处理。

继续使用epoll_wait()等待新事件的发生。

IMS在SystemServer中的ServerThread线程中启动,在InputManagerService的构造函数中调用nativeInit方法,nativeInit方法创建了一个类型为NativeInputManager的对象,它是Java层与Native层互相通信的桥梁。NativeInputManager位于IMS的jni层,负责native层的组件与java层的IMS的相互通信,同时它为主要工作是为InputReader和InputDispatcher提供策略请求接口InputReaderPolicyInterface和InputDispatcherPolicyInterface,策略请求被它转发为Java层的IMS,由IMS最终确定。在NativeInputManager构造函数中创建了EventHub和InputManager。在InputManager中创建了四个对象,分别为InputDispatcher,InputReader,InputReaderThread和InputDispatcherThread。

####### InputReader总体流程

1、首先从EventHub中抽取未处理的事件列表,这些事件分为两类,一类是从设备节点读取的原始输入事件,另一类是设备事件。

2、对原始输入事件进行封装与加工将结果暂存到mQueuedListener中。

3.所有事件处理完毕之后,调用mQueuedListener.flush()将所有暂存的输入事件一次性的交付给InputDispatcher.

EventHub中抽取未处理的事件列表主要是调用getEvents函数,getEvents函数的本质是通过epoll_wait()获取Epoll事件到事件池,并对事件池中的事件进行消费的过程。从epoll_wait()的调用开始到事件池的最后一个时间被消费完毕的过程称为EventHub的一个监听周期。由于buffer参数的额尺寸限制,一个监听周期可能包含多个getEvents调用。

InputReader经过加工之后,输出的事件分为三种基本类型,分别为:按键类型,手势类型和开关类型。三种类型分别由NotifyKeyArgs,NotifyMotionArgs,NotifySwitchArgs三个结构体描述。可以说EventHub的EawEvent是InputReader的输入,而上述三个结构体是InputReader的输出。InputDispatcher继承了InputListenerInterface,实现了notifyKey和notifyMotion和notifySwitch等方法。创建InputReader时将InputDispatcher传给了InputReader。InputReader以InputListenerInterface类型持有InputDispatcher。然后调用mQueuedListener.flush()将三种类型事件传给InputDispatcher。

在这有个问题,为什么不直接使用InputDispatcher作为事件的接受者,而是用QueuedInputListener这个中间人?QueuedInputListener是使用mArgsQueue队列将信息保存起来,当InputReader处理完自EventHub的所有原始输入事件之后,调用flush()函数将缓存的事件信息取出,这样做的目的是,减少InputDispatcher的休眠与唤醒次数,因为InputDispatcher派发的速度快于InputReader加工一个原始输入事件的速度,就会导致InputDispatcher多次休眠与唤醒。

InputReader将处理好的事件提交给InputDispatcher之后,会将输入事件放进派发队列,但是在放进派发队列之前,需要先过滤。过滤之后将事件封装成EventEntry的子类,然后调用enqueueInboundEventLocked()将事件注入mInboundQueue的队尾,并且根据mInboundQueue是否为空来是否唤醒派发线程。

真正的派发是调用dispatchOnceInnerLocked()函数,如果派发队列为空,则会使派发线程陷入无限期休眠状态,即将被派发的事件从派发队列中取出,事件也有可能某些原因被丢弃,被丢弃的原因保存在dropReason中,然后去寻找合适的窗口,目标窗口分为两种:普通窗口和监听窗口。普通窗口通过按点查找与按焦点查找两种方式获得,而监听窗口则无条件监听所有输入事件。

Motion事件派发与按键事件派发的区别:

按键事件在正式派发给窗口之前,进行一次额外的派发策略查询,这个查询结果决定此事件是正常派发、稍后派发还是丢弃。

按键事件的派发目标仅通过焦点方式进行查找。

派发找到对应的窗口之后,然后根据window找到Connection,然后将事件加到Connection的outboundQueue, 然后从outboundQueue队头取一个消息,调用Connection的InputPublisher发送事件,InputPublisher最终会调用InputChannel,InputChannel用自己保存的FD调用socketpair的senMsg函数将事件发出。

一个window对应一个InputChannel对应一个Connection。

发完事件后,将这个消息记录到Connection的waitQueue的队尾。InputDispatcherThread再次等待在Looper上,等App窗口消费完事件并发送finish事件后,InputDispatcherThread就会被唤醒,然后根据发生消息的FD(一个窗口对应一个FD)找到Connection,再根据事件的序列号(seq)找到事件然后将事件从waitQueue移除,并继续派发属于这个Connction的消息。

InputChannel本质是一对SocketPair(非网络套接字)。SocketPair用来实现在本机内进行进程间的通信。一对SocketPair通过socketpair()函数创建,其使用者可以因此而得到两个相互连接的文件描述符。这两个描述符可以通过套接字接口send()和recv()进行写入和读取,并且向其中一个文件描述符写入的数据,可以从另一个描述符中读取。同pipe()所创建的管道不同,SocketPair的两个文件描述符是双通的,因此非常适合用来进行进程间的交互式通信;

1.事件发送主要是通过InputChannel来完成;

2.在wms 执行addView()时,调用openInputChannel来从native层获取inputchannels数组,一个通过ims

registerInputChannel来连接InputDispatcher,另外一个通过InputEventReceiver来连接窗口;

3.InputDispatcher经过Connection最终通过InputPublisher将事件发送到目标窗口;

4.NativeInputEventListener监听到事件到来时通过InputConsumer处理InputMessage后回调Java层接口;

Connection包含两个队列,分别为outboundQueue和waitQueue。还持有InputPublisher对象。

InputPublisher封装InputChannel并直接对齐进行写入和读取,也负责InputMessage结构体的封装和解析。

outboundQueue保存等待Connection进行发送事件的队列。

waitQueue已发送等待反馈的队列,得到反馈后则从队列中删除。

App进程获取到InputChannel后将之内部的socketpair的FD加入到main looper的FD监听列表中去,后续如果收到事件,事件的处理会直接发生在主线程,main looper监听到FD上有数据后回调FD绑定的回调函数,回调函数将事件读出来封装成对应的Event对象,然后层层传递到ViewRootImpl。ViewRootImpl通过一个责任链决定事件的处理顺序和方式,某些事件可能会先派发给输入法窗口进行消费,如果输入法窗口不消费就继续派发给view tree消费,派发给view tree是直接派发的,因为这时已经在主线程了,流程大致是:

ViewRootImpl - DecorView - Activity - View(DecorView) - DecorView的子View

如果App进程没有消费事件,也就是Activity、View等都没有处理这个事件,App进程发送给InputDispather的finish事件会标志这个事件的handled为false。

InputDispatcher收到handled为false的事件后会询问IMS是否备选(fallback)事件,IMS最终会经过WMS到PhoneWindowManager询问是否有备选事件,如果有就将PhoneWindowManager返回的备选事件加入到窗口对应的connection的outboundQueue的队头,在下一次窗口派发循环(注意InputDispather的mInboundQueue队列对应的大循环和connection的outboundQueue对应的窗口事件小循环)中将这个事件发给窗口。

派发循环和事件发送循环

派发循环是InputDiapatcher不断的从派发队列取出事件,寻找合适的窗口进行发送的过程,主要是InputDispatcherThread线程主要的工作。

事件发送循环是InputDispatcher通过Connection对象将事件发送到窗口,并接受反馈的过程

北大青鸟java培训:程序员应该选择java还是c#?

java还是c#?其实这不应该是我们真正的主题,而且入了行的也很少会java还是c#这么比,但初学的,java和c#往往就代表了两大流派,java代替了j2ee,c#代替了.net,ok,没有关系,这么作为title,不影响我们说事。

如果从语言的角度上来讲,c#毫无疑问胜出,易用、门槛低、优雅、较为简洁。

但java和c#的语言特性是相似的。

在很多类的命名上,它们都如出一辙://javaSystem.out.println("java比C#强!j-a-v-a!");//C#System.WriteLine("你没看到#是4个+吗,我比c++还强2个+,你就歇菜吧!");c#出现的时间比java晚,所以自然吸收、借鉴,同时又有它的创新,比如很早就支持lamda表达式、比如event和委托,比如var,比如linq。

但如果从面向接口来讲,java同样可以做到event和listener,只不过对象引用的传递比较直接。

而.Net的类库和jdk则各有千秋。

如果从应用的角度来看,javaee和.Net体系几乎都涵盖了主流的开发方向:桌面、Web、服务端、数据库、网络、移动端、中间件。

哪个方向,哪个更强?这个留给读者自己体会吧。

微软给.Net一个宇宙最强的IDE,也给了各个方向统一而平滑的编程体验,不得不说,微软的上手要容易的多。

而java则一开始就和开源分不开,多如牛毛的框架、引擎、包,blabla,用java开发,程序员要懂得东西更多一些。

应为你大部分情况下得自己整合。

但整合的好了就是很强大的,比如SSH。

在近几年很热的大数据和云计算领域,hadoop、spark、tez、leveldb、mongodb、mariadb、hive、hbase,还有oracle,都各自在自己不同的层面发力,大部分的这些都对java是极为友好的。

很多java程序员,都觉得搞.net开发的,就是拖拖控件而已,其实我可以告诉你,说出这种话的java程序员一般都还比较小白,如果你是搞.net的,你也可以说搞java的都是拷贝别人的开源软件的代码,然后改改而已。

当然改改没什么问题,谁都不喜欢重复造轮子,比如,google里面也并非全部是创新,经常”拿“别人的东西自己改吧改吧,淘宝就很不用说了,招了一些能改c、会点编译的程序员,经常拿各种开源框架开刀,然后表明是自己的东西。

比如双11的那个问题。

当然不是说淘宝找的人有问题,而是这个企业的文化就是销售和广告文化,后来的google也如此。

回到正题,wpf和silverlight(虽然已经EOL)中最大的创新莫过于xaml技术,如果你认为wpf只是winform的简单升级,或者说你只会在wpf中拖控件,说明你还是一个非常初级的.net程序员,不管你工资上w没有,或者你已经是项目经理了。

xaml天生就是为mvvm模型而生,这一点,搞前端的同学,应该熟悉,即使你不懂wpf,js和html怎么做mvvm,你也应该体会过它的好处。

wpf中在xaml中布局控件,并支持INotifyPropertyChanged接口,可以非常容易的实现界面和数据分离,做出一个mvvm模型出来。

说到标记性语言,我们看看jsp的jstl、struts2的tags,还有asp.netmvc3之后的razor引擎:jstl和aspx的标签类似,自由、强大,可以很容易的穿插交织到html标记中;struts的标签就是个另类,我个人反感这种既不遵循主流标准也不简洁的东西,虽然好多人会说好用,那是个习惯问题,我这么说,不是说这东西难学难掌握,只是比较一下和razor引擎中的标签语法,弱爆了。

razor,强大、简洁、优雅。

你肯定觉得我是微软.net的粉丝,其实我想告诉你的是,最强的标签语言只有两种,html和xml,穿插动态语句到服务端页面上,然后刷出html,从来都不是好的做法,因为不只你一个人写代码,后面可能会有其他人维护这个页面,本来这是需要由webdesigner来做的事情,但是有了语句,他的维护成本就很高。

规范的页面开发,程序员是不会染指一个css、style的,动态语言在aspx、view、jsp上面应该尽量少用。

否则你不如使用php和asp。

这一点,你会在工作中会深有体会的。

青春的你,怎么选择?看看现在的招聘吧,动不动就是精通j2ee,精通struts、springmvc、hibernate或者mybatis,对mysql、oracle有深入理解,精通webservice、精通多线程,能处理高并发,有的还得懂jvm,最好有hadoop等开发经验。

最后再来个211以上。

.net方面呢?精通.Net,精通mvc3-5、精通wpf、wcf、多线程,mssql等等等等。

我现在处于离职状态,所以每天收到猎聘上的一些推荐,都很郁闷,因为没有一项是我精通的。

但是不妨碍我在2012年实习中,就拿到了13K的月薪,比一些正式员工可能还要高。

而且,仔细想想,代码中经常讲到要容易维护、这个设计模式、那个AOP,这个大并发,那个高性能,我个人没有见到容易维护的代码。

学习一个新公司的一套模式,一套老产品,比学习一门新技术需要的时间长得多,你会发现,99%的情况下,你最需要的,不是什么代码,模式,而是对产品的理解、对业务的理解,很多情况下,除非太菜太小白,大家的代码都差不多,谁有时间重构代码?程序员又为何加班?这是行情,一个项目接一个项目,公司需要挣钱的,这是大部分公司的现状。

一些疑问访问数据库,随便找个高效的connector或者driver就行了,一般提供数据的厂家,谁不提供connector?ORM是很必要,但是追求性能和反框架泛滥的公司不在乎ORM带来的那点便利性,用一个jdbc+sql照样写稳定高效的数据访问。

做web前端,真的需要自己写一个框架出来?真正需要这种开发的项目有几个呢?jQuery和d3,原生的javascript就够了,你写的也许不叫框架,最多就是个wrapper。

数据库的唯一性索引、聚合索引、辅助索引都没搞清楚,就开始搞hadoop、spark、hbase、mongodb,用人单位也一再这么要求的,你的项目中真的有那么大的数据量?在传统的rdbms下解决不了?你开始知道轮子的概念了,并且知道不要重复造轮子。

可是你快不是程序员了,而是框架员了。

所以,回到java还是c#,这个问题,要比我遇到的技术分裂要简单的多。

我的意见是,忘记java或者c#的对立,如果要做一个开心、有自我追求、同时满足就业的程序员,你需要重视以下方面: 1.函数调用栈,这个很多高级程序员只知其然不知其所以然。

你可以不懂的汇编、函数入口、返回地址、寄存器,但你需要调试,你得深刻理解函数调用栈,无论是在dev模式调试struts开发的jsp页面,还是debug模式调试aspx页面,你得看懂调用栈的信息;2.基本的数据结构和算法,数据库中索引的组织方式,是B+树还是Hash,还是堆,你的公司有Web、桌面、移动用户,有社区,有产品,你可能要做个推荐什么的,或者研究个社交图谱什么的,这门技术可以帮助你。

3.一门动态语言。

lua、python、javascript,都可以,你需要随时和系统进行交互,或者实现一个原型,或者用程序的方式来画点界面、数据图什么,它们够轻量、够快捷 4.一门重量级语言。

比如java或者c#。

你靠它们吃饭。

5.理解跨平台的含义。

掌握一些基本的跨平台技术,比如xml、c、html、json。

6.重视网络编程的练习和理解,在你使用URLConnection或者MySqlConnection或者WebRequest的时候,你是否理解它们的生命周期和底层实现,用什么语言无所谓,你要记住tcp/ip协议和http的基本特性。

这样不至于你写了几年程序,还不知道method=post是什么原理。

7.找一个顺手的IDE,我个人不是CLI控,虽然不得不CLI,一个顺手的IDE真的可以提高生产效率。

搞.Net推荐vs+resharper,搞java推荐intellijIDEA.  8.关注一些热门而经典的领域,比如机器学习、图像处理、数据挖掘,即使已经有了mahout,不代表你不需要了解这些领域,你可能永远不会在工作中使用它们,但它们的思想值得你拥有,因为你选择了做程序员,而不是哪个公司的程序员。

 剩下的,就是你的解决问题的思路和你实现的硬功夫(编码能力),我相信,很多看这篇文章的人,不能够轻易写出一个ftp服务器,不能够不参考、不联网查询资料写出一个简单的快速排序,也不能够轻易写出一段通用分页SQL,但他们依然可以正常工作。

所以外面的功夫容易忘记,有网络就能拾起,内功才是入骨的东西。

架构不是学出来的,是你的理解到位了,恰好工作中有这么个需求,你就开始整合你的已知,然后开始选择轮子。

回答于 2022-10-28

详情

该链接由问题回答方推荐

官方电话

在线客服

官方服务

官方网站

领学习资料

inotifyjava的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于、inotifyjava的信息别忘了在本站进行查找喔。

The End

发布于:2022-12-05,除非注明,否则均为首码项目网原创文章,转载请注明出处。