首页 文章 精选 留言 我的

精选列表

搜索[智能解析],共10000篇文章
优秀的个人博客,低调大师

Ubuntu环境变量解析

在Ubuntu中有如下几个文件可以设置环境变量 /etc/profile:在登录时,操作系统定制用户环境时使用的第一个文件,此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. /etc/environment:在登录时操作系统使用的第二个文件,系统在读取你自己的profile前,设置环境文件的环境变量 ~/.profile:在登录时用到的第三个文件是.profile文件,每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件. /etc/bashrc:为每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取. ~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该该文件被读取. 当你登录并且登录shell是bash时,bash首先执行/etc/profile文件中的命令(如果该文件存在),然后它顺序寻找 ~ /.bash_profile,~/.bash_login或~/.profile文件,并执行找到的第一个可读文件中的命令.当登录bash退出时,它 将执行~/.bash_logout文件中的命令. 当启动一个交互的bash时,它将执行~/.bashrc文件中的命令(如果该文件存在并且可读).当非交互地启动以运行一个shell脚本时,bash将查找bash_env环境变量,确定执行文件的名称. 本文转自我爱物联网博客园博客,原文链接:http://www.cnblogs.com/yydcdut/p/4474154.html,如需转载请自行联系原作者

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

深度解析阿里云存储

国际知名调研机构Gartner近日公布了2017年全球云计算云存储魔力象限,阿里云的云存储强势崛起成为这一核心领域的前四名。 图1 2017年Gartner全球云存储魔力象限图 在去年首次进入Gartner魔力象限即取得了不错的位置之后,今年阿里云存储再次强势进入公共云存储魔力象限,紧跟Google成为公共云存储厂商中在利基象限中最接近领导者象限的公共云存储厂商,而领导者象限中目前只有AWS和Azure。 图2 2016年Gartner全球云存储魔力象限图 作为国内市场排名第一的云厂商的云存储产品系列,取得这样的成绩也并不是水涨船高的结果。首先从整体评估上来说,Gartner的评估方法并不依赖母体厂商的品牌和占有率,而是客观的从云存储类型(对象,块,文件)和冷热存储,全球数据中心的位置、技术成熟度、市场策略、市场份额、服务承诺和SLA

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

Android 使用SAX解析XML

项目的结构 首先新建一个book_info.xml的xml文件,结构如下: <?xml version= "1.0" encoding= "UTF-8" ?> <books> <catalog>Computer</catalog> <book> <country>USA</country> <title>Empire Burlesque</title> <artist>Bob Dylan</artist> <price> 10.90 </price> </book> <book> <country>UK</country> <title>Hide your heart</title> <artist>Bonnie Tyler</artist> <price> 9.90 </price> </book> <book> <country>USA</country> <title>Greatest Hits</title> <artist>Dolly Parton</artist> <price> 9.90 </price> </book> </books> BookItem.java 代表一本书的信息,代码如下: package com.example.utility; public class BookItem { public String name; public String title; public String artit; public String price; public BookItem() { } public String getName() { return name; } public void setName(String countryName) { this .name = countryName; } public String getTitle() { return title; } public void setTitle(String title) { this .title = title; } public String getArtist() { return artit; } public void setArtist(String artit) { this .artit = artit; } public String getPrice() { return price; } public void setPrice(String price) { this .price = price; } } BookFeed代表所有书的信息,代码如下: package com.example.utility; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Vector; public class BookFeed { private String catalog; private List<BookItem> bookList; private int itemcount; public BookFeed() { bookList = new Vector<BookItem>( 0 ); } public int addBookItem(BookItem item) { itemcount++; bookList.add(item); return itemcount; } public BookItem getBookItem( int location) { return bookList.get(location); } public List<BookItem> getAllBooks() { return bookList; } public String getCatalog() { return catalog; } public void setCatalog(String catalog) { this .catalog = catalog; } public List<BookItem> getBookList() { return bookList; } public void setBookList(List<BookItem> bookList) { this .bookList = bookList; } public List GetAllBooks() { List<Map<String, String>> data = new ArrayList<Map<String,String>>() ; int size = bookList.size(); for ( int i = 0 ; i < size; i++) { HashMap<String, String> bookItemHashMap = new HashMap<String, String>(); bookItemHashMap.put( "title" , bookList.get(i).getTitle()); bookItemHashMap.put( "price" , bookList.get(i).getPrice()); data.add(bookItemHashMap); } return data; } } BookHand.java package com.example.utility; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import android.R.integer; public class BookHandle extends DefaultHandler { BookFeed bookFeed; BookItem bookItem; final int Book_Country = 1 ; final int Book_Title = 2 ; final int Book_Artist = 3 ; final int Book_Price = 4 ; int curState = 0 ; public BookHandle() { } public BookFeed getBookFeed() { return bookFeed; } @Override public void startDocument() throws SAXException { bookFeed = new BookFeed(); bookItem = new BookItem(); } @Override public void endDocument() throws SAXException { } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (localName.equals( "books" )) { curState = 0 ; return ; } if (localName.equals( "book" )) { bookItem = new BookItem(); return ; } if (localName.equals( "country" )) { curState = Book_Country; return ; } if (localName.equals( "title" )) { curState = Book_Title; return ; } if (localName.equals( "artist" )) { curState = Book_Artist; return ; } if (localName.equals( "price" )) { curState = Book_Price; return ; } curState = 0 ; } @Override public void endElement(String uri, String localName,String qName) throws SAXException { if (localName.equals( "book" )) { bookFeed.addBookItem(bookItem); return ; } } @Override public void characters( char [] ch, int start, int length) throws SAXException { String str = new String(ch,start,length); switch (curState) { case Book_Country: bookItem.setName(str); curState = 0 ; break ; case Book_Title: bookItem.setTitle(str); curState = 0 ; break ; case Book_Artist: bookItem.setArtist(str); curState = 0 ; break ; case Book_Price: bookItem.setPrice(str); curState = 0 ; break ; default : return ; } } } MainActiviyt.java public class MainActivity extends Activity { public BookFeed feed; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); feed = getFeed(); showList(); } private void showList() { // TODO Auto-generated method stub ListView lView = (ListView) this .findViewById(R.id.listView1); if (feed == null ) { Log.i( "Custom Message" , "feed is null" ); return ; } SimpleAdapter adapter = new SimpleAdapter( this , feed.GetAllBooks(), android.R.layout.simple_list_item_2, new String[]{ "title" , "price" }, new int []{android.R.id.text1, android.R.id.text2}); lView.setAdapter(adapter); } public BookFeed getFeed() { try { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); XMLReader reader = parser.getXMLReader(); BookHandle handle = new BookHandle(); reader.setContentHandler(handle); InputSource iSource = new InputSource( this .getClassLoader().getResourceAsStream( "book_info.xml" )); reader.parse(iSource); return handle.getBookFeed(); } catch (ParserConfigurationException e) { // TODO: handle exception e.printStackTrace(); } catch (SAXException e) { // TODO: handle exception e.printStackTrace(); } catch (IOException e) { // TODO: handle exception e.printStackTrace(); } return null ; } } 效果图: 本文转自Work Hard Work Smart博客园博客,原文链接:http://www.cnblogs.com/linlf03/archive/2013/03/18/2966020.html,如需转载请自行联系原作者

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

Android Fragment使用全解析

Fragment的使用可谓是老生常谈了~~~ 1、概述 自API 11引入Fragment之后,Fragment可谓风靡一时,现在大部分项目都或多或少的用到了Fragment,其更轻量级,更加适用屏幕,更加方便UI设计等优势。说了这么多什么是Fragment呢? Fragment:碎片,碎片是一个应用程序的用户界面和行为能够被放置在一个活动上。在其核心,它代表了一个特定的操作或界面,运行在一个更大的活动上。代表界面是因为可作为View在布局中进行使用,代表特定操作是因为包含生命周期可进行逻辑操作。简言之,Fragment就是一个带生命周期的组件。(若有问题恳请指正!) Fragment的特点: 生命周期必须依赖于Activity,当Activity被销毁,所有的碎片将被摧毁。(自己曾经踩坑) 轻量级,轻量切换。 方便处理平板、Phone的界面差异。 2、继承结构和生命周期 继承结构: Fragment直接继承Object,有四个直接子类,我个人对它的子类使用甚少。 生命周期: Fragment的生命周期在图上标注的很清楚了就不赘述了。该图是很久之前收藏的,已忘记原出处,在此感谢原作者! 3、基本使用 1).静态使用 静态使用就是Fragment相当于控件一样在布局中使用。 TestFragment.java 继承Fragment重写onCreateView方法 /** *Createdbymagicon2016年9月27日. */ publicclassTestFragmentextendsFragment{ @Override publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer, BundlesavedInstanceState){ Viewview=inflater.inflate(R.layout.fragment_main,container); ImageViewimg=(ImageView)view.findViewById(R.id.img); img.setOnClickListener(newView.OnClickListener(){ @Override publicvoidonClick(Viewv){ Toast.makeText(getActivity(),"这是一个fragment",Toast.LENGTH_SHORT).show(); } }); returnview; } } fragment_main.xml <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:src="@drawable/img"/> </RelativeLayout> MainActivity.java 里面其实什么也没干。 /** *Createdbymagicon2016年9月27日. */ publicclassMainActivityextendsActivity{ @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } } activity_main.xml <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:id="@+id/id_fragment" android:layout_width="match_parent" android:layout_height="match_parent" class="com.magic.test_fragment.TestFragment"/> </RelativeLayout> 使用 fragment 标签添加碎片,通过class指定碎片的完整类名。 运行效果: 2).动态使用 动态使用就是向Fragment布局容器中动态添加、替换、移除、隐藏、显示Fragment。 CommonFragment.java /** *Createdbymagicon2016年9月27日.通用Fragment */ @SuppressLint("ValidFragment") publicclassCommonFragmentextendsFragment{ Stringdesc; publicCommonFragment(Stringdesc){ super(); this.desc=desc; } @Override publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer, BundlesavedInstanceState){ Viewview=inflater.inflate(R.layout.fragment_common,container,false); TextViewtev=(TextView)view.findViewById(R.id.tev); System.out.println(desc); tev.setText(desc); returnview; } } 通过构造方法传递数据的形式向TextView上设置内容。 fragment_common.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/tev" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:textColor="@color/mainOrange"/> </LinearLayout> MainActivity.java /** *Createdbymagicon2016年9月27日.底部tab+fragment */ publicclassMainActivityextendsActivityimplementsOnClickListener{ TextViewtev_tab1,tev_tab2,tev_tab3,tev_tab4; //fragment事务类 FragmentTransactionft; //fragment CommonFragmenttabFragment1,tabFragment2,tabFragment3,tabFragment4; @SuppressLint("CommitTransaction") @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); initView(); ft=getFragmentManager().beginTransaction(); tabFragment1=newCommonFragment("Tab1"); //替换 ft.replace(R.id.container,tabFragment1); //提交 ft.commit(); } //初始化控件 privatevoidinitView(){ tev_tab1=(TextView)findViewById(R.id.tev_tab1); tev_tab2=(TextView)findViewById(R.id.tev_tab2); tev_tab3=(TextView)findViewById(R.id.tev_tab3); tev_tab4=(TextView)findViewById(R.id.tev_tab4); tev_tab1.setOnClickListener(this); tev_tab2.setOnClickListener(this); tev_tab3.setOnClickListener(this); tev_tab4.setOnClickListener(this); } @Override publicvoidonClick(Viewv){ FragmentTransactionft=getFragmentManager().beginTransaction(); switch(v.getId()){ caseR.id.tev_tab1: ft.replace(R.id.container,tabFragment1); break; caseR.id.tev_tab2: if(tabFragment2==null){ tabFragment2=newCommonFragment("Tab2"); } ft.replace(R.id.container,tabFragment2); break; caseR.id.tev_tab3: if(tabFragment3==null){ tabFragment3=newCommonFragment("Tab3"); } ft.replace(R.id.container,tabFragment3); break; caseR.id.tev_tab4: if(tabFragment4==null){ tabFragment4=newCommonFragment("Tab4"); } ft.replace(R.id.container,tabFragment4); break; } //提交 ft.commit(); } } activity_main2.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:background="@color/mainTextBlack" android:orientation="horizontal"> <TextView android:id="@+id/tev_tab1" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="Tab1" android:textColor="@color/white"/> <TextView android:id="@+id/tev_tab2" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="Tab2" android:textColor="@color/white"/> <TextView android:id="@+id/tev_tab3" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="Tab3" android:textColor="@color/white"/> <TextView android:id="@+id/tev_tab4" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="Tab4" android:textColor="@color/white"/> </LinearLayout> </LinearLayout> 通过 FrameLayout 标签创建Fragment的容器,底部四个Tab添加监听事件用于动态更换FrameLayout容器中的Fragment。 运行效果: 4、相关类及主要方法 FragmentManager碎片管理器,抽象类,具体实现在Android-support-v4.jar中的FragmentManagerImpl类中。 //获取FragmentManager对象 FragmentManagermanager=getFragmentManager(); FragmentTransaction碎片事务类,抽象类,具体实现在BackStackRecord类中。添加、删除、替换等操作其实最终的实现还是在FragmentManagerImpl类中。 //获取FragmentTransaction对象 FragmentTransactiontransaction=manager.beginTransaction(); //添加fragment transaction.add(); transaction.add(containerViewId,fragment,tag); //将被添加到容器的现有fragment替换 transaction.replace(); //删除一个现有的fragment transaction.remove(); //保存当前fragment数据,避免视图重绘 transaction.hide(); //显示以前隐藏的fragment transaction.show(); //这两个方法会触发fragment中的onHiddenChanged(booleanhidden)回调 //显示之前数据实例不会被销毁,但是视图层次依然会被销毁,即会调用onDestoryView和onCreateView transaction.addToBackStack(null); //事务提交 transaction.commit(); Fragment 碎片类 Fragmentfragment=newFragment(); //返回此fragment当前关联的Activity fragment.getActivity(); //设置数据 fragment.setArguments(newBundle()); //获取数据 fragment.getArguments(); //返回与该fragment作用的FragmentManager fragment.getFragmentManager(); //获取标签名 fragment.getTag(); //当隐藏状态改变的时候回调 //onHiddenChanged(true); 有兴趣大家可以去Read The Fucking Source,反正我看的比较头大……. 5、其它 未完待续…… 本文作者:佚名 来源:51CTO

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

HBase - 建表语句解析

像所有其他数据库一样,HBase也有表的概念,有表的地方就有建表语句,而且建表语句还很大程度上决定了这张表的存储形式、读写性能。比如我们熟悉的MySQL,建表语句中数据类型决定了数据的存储形式,主键、索引则很大程度上影响着数据的读写性能。虽然HBase没有主键、索引这些概念,但在HBase的世界里,有些东西和它们一样重要! 废话不说,直接奉上一条HBase建表语句,来为各位看官分解剖析: create 'NewsClickFeedback',{NAME=>'Toutiao',VERSIONS=>1,BLOCKCACHE=>true,BLOOMFILTER=>'ROW',COMPRESSION=>'SNAPPY',TTL => ' 259200 '},{SPLITS => ['1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']} 上述建表语句表示创建一个表名为“NewsClickFeedback”的表,该表只包含一个列簇“Toutiao”。接下来重点讲解其他字段的含义以及如何正确设置。Note:因为篇幅有限本文并不讲解具体的工作原理,后续会有相关专题对其进行分析。 VERSIONS 数据版本数,HBase数据模型允许一个cell的数据为带有不同时间戳的多版本数据集,VERSIONS参数指定了最多保存几个版本数据,默认为1。假如某个用户想保存两个历史版本数据,可以将VERSIONS参数设置为2,再使用如下Scan命令就可以获取到所有历史数据: scan 'NewsClickFeedback',{VERSIONS => 2} BLOOMFILTER 布隆过滤器,优化HBase的随机读取性能,可选值NONE|ROW|ROWCOL,默认为NONE,该参数可以单独对某个列簇启用。启用过滤器,对于get操作以及部分scan操作可以剔除掉不会用到的存储文件,减少实际IO次数,提高随机读性能。Row类型适用于只根据Row进行查找,而RowCol类型适用于根据Row+Col联合查找,如下: Row类型适用于:get ‘NewsClickFeedback’,’row1′ RowCol类型适用于:get ‘NewsClickFeedback’,’row1′,{COLUMN => ‘Toutiao’} 对于有随机读的业务,建议开启Row类型的过滤器,使用空间换时间,提高随机读性能。 COMPRESSION 数据压缩方式,HBase支持多种形式的数据压缩,一方面减少数据存储空间,一方面降低数据网络传输量进而提升读取效率。目前HBase支持的压缩算法主要包括三种:GZip | LZO | Snappy,下面表格分别从压缩率,编解码速率三个方面对其进行对比: Snappy的压缩率最低,但是编解码速率最高,对CPU的消耗也最小,目前一般建议使用Snappy TTL 数据过期时间,单位为秒,默认为永久保存。对于很多业务来说,有时候并不需要永久保存某些数据,永久保存会导致数据量越来越大,消耗存储空间是其一,另一方面还会导致查询效率降低。如果设置了过期时间,HBase在Compact时会通过一定机制检查数据是否过期,过期数据会被删除。用户可以根据具体业务场景设置为一个月或者三个月。示例中TTL => ‘259200’设置数据过期时间为三天 IN_MEMORY 数据是否常驻内存,默认为false。HBase为频繁访问的数据提供了一个缓存区域,缓存区域一般存储数据量小、访问频繁的数据,常见场景为元数据存储。默认情况,该缓存区域大小等于Jvm Heapsize * 0.2 * 0.25 ,假如Jvm Heapsize = 70G,存储区域的大小约等于3.2G。需要注意的是HBase Meta元数据信息存储在这块区域,如果业务数据设置为true而且太大会导致Meta数据被置换出去,导致整个集群性能降低,所以在设置该参数时需要格外小心。 BLOCKCACHE 是否开启block cache缓存,默认开启。 SPLITS region预分配策略。通过region预分配,数据会被均衡到多台机器上,这样可以一定程度上解决热点应用数据量剧增导致系统自动split引起的性能问题。HBase数据是按照rowkey按升序排列,为避免热点数据产生,一般采用hash + partition的方式预分配region,比如示例中rowkey首先使用md5 hash,然后再按照首字母partition为16份,就可以预分配16个region。 本文转载自:http://hbasefly.com 原文链接

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

android studio lint基本解析

可访问性(accessibility) 1、Image without contentDescription图像没有内容描述 这个是需要对图片进行一个描述,不然会有警告,一般情况下进行统一的标识加入 android:c ontentDescription="@string/abc 正确性(correctness) 2、Attribute unused on older versions 旧版本中未使用的属性 3、Class is not registered in the manifest 类没有在清单中注册 没有注册的activity 4、Duplicate ids across layouts combined with include tags布局中重复的ids与包含标签相结合 引用的布局和父布局包含相同的id 5、Implied locale in date format 使用日期格式的默示语言环境 http://blog.csdn.net/revival_liang/article/details/51812723 时间声明问题 SimpleDateFormat format = new SimpleDateFormat("MM月dd日HH时mm分ss秒");//有报警问题 SimpleDateFormat format = new SimpleDateFormat("MM月dd日HH时mm分ss秒", Locale.getDefault()); 6、Incorrect order of elements in manifest 清单中元素的顺序不正确 有些权限需要写道application之前,示例极光的一个权限 <uses-permission android:name="packagename.permission.JPUSH_MESSAGE" /> 7、Layout Inflation without a Parent 父布局没有膨胀 示例 使用nullView view = inflater.inflate(R.layout.progressbar, null); 正确的使用 第三个参数设置为了true,表示将第一个参数所指定的布局添加到第二个参数的View中 LinearLayout ll = (LinearLayout) findViewById(R.id.ll); LayoutInflater inflater = LayoutInflater.from(this); inflater.inflate(R.layout.linearlayout, ll,true); 8、Missing commit() calls 失踪的commit()调用 一般报错 After creating a FragmentTransaction, you typically need to commit it as well fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.xxxx, new xxxxFragment().newInstance(xxxx),"xxxx"); fragmentTransaction.commit(); 改为(暂未测试效果) fragmentManager.beginTransaction().replace(R.id.xxxx, new xxxxFragment().newInstance(xxxx),"xxxx").commit(); 9、Missing commit() on SharedPreference editor ` SharedPreferences.Editor edit = sp.edit(); edit.putString("isFirstLogin", "0"); edit.commit(); 改为 apply() ` 这两个方法的区别在于: apply没有返回值而commit返回boolean表明修改是否提交成功 apply是将修改数据原子提交到内存, 而后异步真正提交到硬件磁盘, 而commit是同步的提交到硬件磁盘,因此,在多个并发的提交commit的时候,他们会等待正在处理的commit保存到磁盘后在操作,从而降低了效率。而apply只是原子的提交到内容,后面有调用apply的函数的将会直接覆盖前面的内存数据,这样从一定程度上提高了很多效率。 apply方法不会提示任何失败的提示。 由于在一个进程中,sharedPreference是单实例,一般不会出现并发冲突,如果对提交的结果不关心的话,建议使用apply,当然需要确保提交成功且有后续操作的话,还是需要用commit的。 10、Nested scrolling widgets 嵌套滚动窗口小部件 scrollview中嵌套了listview 11、Obsolete Gradle Dependency 过时Gradle依赖 提示android 升级高版本 12、RecyclerView Problems recycleerview的问题 在onBindviewholder方法中不能使用position 应该使用holer.getAdapterPosition()来获取position 有时候在做item换位置时直接使用postiion会发生位置错误 无法获取到变换后的位置 13、ScrollView size validation scrollview大小的验证 ScrollView里的LinearLayout的高度应该使用wrap_content 14、Reference to an id that is not in the current layout 引用不在当前布局内的id 15、Target SDK attribute is not targeting latest version 目标SDK属性不是针对最新版本的 15、Unreachable state in a <selector> In a selector, only the last child in the state list should omit a state qualifier. If not, all subsequent items in the list will be ignored since the given item will match all 在选择器中,只有状态列表中的最后一个子应该省略一个状态限定符。如果没有,则列表中的所有后续项都将被忽略,因为给定的项将匹配所有项 16、Using deprecated resources 过时的方法 17、Using inlined constants on older versions quanxu Internationalization 国际化 18、Hardcoded text 硬编码 https://toutiao.io/posts/572671/app_preview 19、TextView Internationalization java 代码中使用的汉字应使用常量来代替(个人建议) 20、 Bidirectional Text 双向设置 如 :android:paddingLeft="15dp" 需要设置两侧对应android:paddingLeft="15dp" android:paddingRight="15dp" Performance 性能 21、FrameLayout can be replaced with <merge> tag FrameLayout可以替换为<merge>标签 MergeRootFrame 如果FrameLayout是根布局,并且不提供背景或填充等,它通常可以替换为稍微更有效的<merge>标签。请注意,这取决于上下文,因此请确保在继续之前了解<merge>标记的工作原理。 22、Handler reference leaks handle引起程序泄露参考 因为同一个线程下的handler共享一个looper对象,消息中保留了对handler的引用,由于Java在生成内部类的时候,原本没有构造器的内部类会被生成一个带外部类参数的构造器,这个内部类就会持有外部类的隐式引用。Handler其实隐式的持有了Activity的引用,只要有消息在队列中,那么handler便无法被回收,如果handler不是static那么使用Handler的Service和Activity就也无法被回收。这就可能导致内存泄露 http://blog.csdn.net/liangchengfeng/article/details/51999882 23、HashMap can be replaced with SparseArray HashMap可以用SparseArray替换 ` HashMap<Integer, HashMap<String, String>> rightPopCommonList = new HashMap<Integer, HashMap<String, String>>(); 改为 HashMap<Integer, HashMap<String, String>> rightPopCommonList = new new HashMap<>(); ` 24、Inefficient layout weight 低效的权重布局 在 设置权重属性的时候相应的宽高属性应设为0dp 25、Layout hierarchy is too deep 布局层次结构太深 嵌套过多的布局不利于性能。考虑使用更平的布局(比如相对布局或GridLayout)。默认的最大深度为10,但可以使用环境变量androidlintmaxdepth配置 26、Memory allocations within drawing code 绘制代码内的内存分配 Avoid object allocations during draw/layout operations (preallocate and reuse instead) You should avoid allocating objects during a drawing or layout operation. These are called frequently, so a smooth UI can be interrupted by garbage collection pauses caused by the object allocations. The way this is generally handled is to allocate the needed objects up front and to reuse them for each drawing operation. Some methods allocate memory on your behalf (such as Bitmap.create), and these should be handled in the same way. 27、Missing baselineAligned attribute 消失的baselineAligned属性 baselineAligned属性默认为true 这是基准线设置,设置为fale时它的子控件不对齐 当linearlayout为水平时设置为fale 获取更好的性能http://blog.csdn.net/bdmh/article/details/48495583 28、Nested layout weights 嵌套布局权重 避免权重套权重,当一个非零权重的线性布局被嵌套在另一个带有非零权重的线性布局中,那么度量的数量就会呈指数增长。 29、Node can be replaced by a TextView with compound drawables 节点可以用一个带有复合绘图的TextView来替换 让只有图片和文字的一个小布局合并为一个textview 这个视情况。 30、Obsolete layout params 布局中无用的参数 31、Overdraw: Painting regions more than once 过度绘制 一般布局根背景不需要在设置bg了 子布局的背景挡住的父布局造成了过度绘制 32、Static Field Leaks 静态变量泄露 主要是上下文对象不要设置为static 33、Unused resources 无用的资源 34、Useless leaf layout 无用的布局 35、Useless parent layout无用的父布局 36、View Holder Candidates adapter没有重用子布局

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

经典的 Fork 炸弹解析

Jaromil在2002年设计了最为精简的一个Linux Fork炸弹,整个代码只有13个字符,在shell中运行后几秒后系统就会宕机: :(){:|:&};: 这样看起来不是很好理解,我们可以更改下格式: :() { :|:& }; : 更好理解一点的话就是这样: bomb() { bomb|bomb& }; bomb 因为shell中函数可以省略function关键字,所以上面的十三个字符是功能是定义一个函数与调用这个函数,函数的名称为:,主要的核心代码是:|:&,可以看出这是一个函数本身的递归调用,通过&实现在后台开启新进程运行,通过管道实现进程呈几何形式增长,最后再通过:来调用函数引爆炸弹.因此,几秒钟系统就会因为处理不过来太多的进程而死机,解决的唯一办法就是重启。 Bomb一下 秉着不作不死的心态,我们也来运行一下,于是我将矛头指向云主机,,我使用了国内的一个2G内存的云主机,首先在本地开启两个终端,在一个终端连接云主机后运行炸弹,几秒后再尝试用另外一个终端登录,效果可以看下面Gif图: 看,运行一段时间后直接报出了-bash: fork: Cannot allocate memory,说明内存不足了。并且我在二号终端上尝试连接也没有任何反应。因为是虚拟的云主机,所以我只能通过主机服务商的后台来给主机断电重启。然后才能重新登录: 炸弹危害 Fork炸弹带来的后果就是耗尽服务器资源,使服务器不能正常的对外提供服务,也就是常说的DoS(Denial of Service)。与传统1v1、通过不断向服务器发送请求造成服务器崩溃不同,Fork炸弹有种坐山观虎斗,不费一兵一卒斩敌人于马下的感觉。更吓人的是这个函数是不需要root权限就可以运行的。看到网上有帖子说某些人将个性签名改为Fork炸弹,结果果真有好奇之人中枪,试想如果中枪的人是在公司服务器上运行的话,oh,! 预防方式 当然,Fork炸弹没有那么可怕,用其它语言也可以分分钟写出来一个,例如,python版: import os while True: os.fork() Fork炸弹的本质无非就是靠创建进程来抢占系统资源,在Linux中,我们可以通过ulimit命令来限制用户的某些行为,运行ulimit -a可以查看我们能做哪些限制: ubuntu@10-10-57-151:~$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 7782 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 7782 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited 可以看到,-u参数可以限制用户创建进程数,因此,我们可以使用ulimit -u 20来允许用户最多创建20个进程。这样就可以预防bomb炸弹。但这样是不彻底的,关闭终端后这个命令就失效了。我们可以通过修改/etc/security/limits.conf文件来进行更深层次的预防,在文件里添加如下一行(ubuntu需更换为你的用户名): ubuntu - nproc 20 这样,退出后重新登录,就会发现最大进程数已经更改为20了, 这个时候我们再次运行炸弹就不会报内存不足了,而是提示-bash: fork: retry: No child processes,说明Linux限制了炸弹创建进程。 原文发布时间为:2015-06-24 本文来自云栖社区合作伙伴“Linux中国”

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

weex高性能list解析

weex是alibaba出品的用于移动端跨平台开发界面的框架,类似react-native。而ListView在移动端界面的开发中是非常重要的组件,无论是H5还是react-native都因为ListView的低性能而饱受非议。那么到底是什么样的实现让weex能拥有与众不同的ListView性能呢? List示例 首先,让我们一起来看看weex下如何使用list。 <template> <div> <list class="list"> <refresh class = "refresh-view" display="{{refresh_display}}" onrefresh="onrefresh"> <text if="{{(refresh

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

Macaca基础原理解析

导语 前面几篇文章介绍了在Macaca实践中的一些实用技巧与解决方案,今天简单分析一下Macaca的基础原理。这篇文章将以前面所分享的UI自动化Macaca-Java版实践心得中的demo为基础,进行一下实例讲解。 Macaca的基本组成 通过对源码各个模块的分析,可以帮助我们对Macaca的整体构成有一个基础的认识。Macaca已经开源,相关的源码在对应的github上都可以下载: https://github.com/macacajs。 大家会在alibaba集团的开源github上找到macaca的另一个仓库https://github.com/alibaba/macaca/,关于这两个仓库的关系这里简单讲一下,由于主仓库https://github.com/macacajs模块众多,所以在alibaba集团下的github上采用了a

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

解析阿里云容器服务

容器服务(Container Service)是一种高性能可伸缩的容器管理服务,支持在一组阿里云云服务器上通过 Docker 容器来运行或编排应用。容器服务免去了您对容器管理集群的搭建,整合了负载均衡、专有网络 (VPC) 等云产品,让咱们可以通过控制台或简单的 API(兼容 Docker API)进行容器生命周期管理。主要功能:集群管理,灵活的地域和网络环境选择;多种服务器托管方式;一站式容器生命周期管理;兼容标准 Docker API;阿里云环境特有的增值能力;高可用调度策略,打通上下游交付流程。 容器服务常用的应用场景: 1)Web 应用镜像化部署,在容器集群中加入两台云服务器和一个负载均衡,并通过云数据库 RDS 版提供数据存储,最后选择 WordPress 等容器镜像。 2)持续集成系统构建,在阿里云容器 Hub 创建一个自动构建类型的镜像仓库,选择关联代码源到 GitHub 或云 Code。镜像构建完毕后,通过调用容器服务的 OpenAPI 完成容器的部署。 3)微服务架构,将用户现有的复杂系统拆分成多个微服务,每个微服务的内容用一个镜像管理。通过 Docker Compose 模板描述服务之间的依赖关系和配置。通过容器服务选择之前创建的编排模板创建应用。 2016云栖大会上,阿里云资深专家易立从中国容器市场分析、阿里云容器服务路线图、云市场与解决方案层层深入,为我们讲解了阿里云容器服务是如何加速企业创新的。预知详情,且看下文PDF:

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

hadoop源码解析---INodeReference机制

本文主要介绍了hadoop源码中hdfs的INodeReference机制。 在hdfs2.6版本中,引入了许多新的功能,一些原有的源代码设计也有一定的改造。一个重要的更新就是引入了快照功能。但是当HDFS文件或者目录处于某个快照中,并且这个文件或者目录被重命名或者移动到其他路径时,该文件或者目录就会存在多条访问路径。INodeReference就是为了解决这个问题产生的。 问题描述 /a是hdfs中的一个普通目录,s0为/a的一个快照,在/a目录下有一个文件test。根据快照的定义,我们可以通过/a/test以及/a/snapshot/s0/test访问test文件。 但是当用户将/a/test文件重命名成/x/test1时,通过快照路径/a/snapshot/s0/test将无法访问test文件,这种情况是不符合快照规范的。 引入INodeReference 为了解决上述问题,hdfs引入了INodeReference类。图1-1给出了INodeReference的继承关系图。这里的WithName,WithCoount,DstReference都是INodeReference的子类,同时也是INodeReference的内部类。WithName对象用于替代重命名操作前源路径中的INode对象,DstReference对象则用于替代重命名操作后目标路径中的INode对象,WithName和DstReference共同指向了一个WithCount对象,WithCount对象则指向了文件系统目录树中真正的INode对象。 图1 INodeReference代码实现 INodeReference是一个抽象类,它拓展自INode类,所以INodeReference及其子类是可以添加到文件系统目录树中以替代原有的INodeFile节点的。INodeReference定义了referred字段,这个字段用于保存当前INodeReference类指向的INode节点,所以WithName和RstReference,referred字段就指向了WithCount对象,对于WithCount,referred指向了真正的INode对象。INodeReference还定义了getReferredINode()方法,在文件系统目录树的操作中,如果判断当前节点是一个引用节点,则会调用getReferredINode()方法获取INodeReference指向的INode对象。 publicabstractclassINodeReferenceextendsINode{ privateINodereferred;//指向的INode节点 publicINodeReference(INodeparent,INodereferred){ super(parent); this.referred=referred; } publicfinalINodegetReferredINode(){//获取指向的INode节点 returnreferred; } publicfinalvoidsetReferredINode(INodereferred){ this.referred=referred; } //... } 然后,我们在来看看WithCount类的实现。 WithCount类定义了一个集合字段withNameList用于保存所有指向这个WithCount对象的WithName对象集合。WithCount类还定义了addReference()方法,任何指向WithCount对象的WithName对象以及DstReference对象都需要调用这个方法来添加指向关系。对于指向这个WithCount对象的DstReference对象,addReference()方法会将这个对象设置为自己的父INode节点;而对于WithName对象,addReference()方法则将这个对象放入withNameList集合中保存。 publicstaticclassWithCountextendsINodeReference{ //保存所有指向这个WithCount对象的WithName对象的集合 privatefinalList<WithName>withNameList=newArrayList<WithName>(); publicWithCount(INodeReferenceparent,INodereferred){ super(parent,referred);//调用父类的构造方法,指向文件系统目录树中的INode Preconditions.checkArgument(!referred.isReference()); refferred.setParentReferenct(this);//设置真实INode的父节点为当前WithCount对象 } publicvoidaddReferenct(INodeReferenceref){ if(refinstanceofWithName){//如果是WithName对象,则加入withNameList WithNamerefWithName=(WithName)ref; inti=Collections.binarySearch(withNameList,refWithName,WITHNAME_COMPARATOR); Preconditions.checkState(i<0); withNameList.add(-i-1,refWithName); }elseif(refinstanceofDstReference){//如果是DstReference对象,则设置为父节点 setParentReference(ref); } } //... } 看完WithCount后,在看看WithName和DstReference。WithName类定义了name字段用于保存重命名前文件的名称,同事定义了lastSnapshotId字段用于保存WithName对象构造时源路径的快照版本号。DstReference类的实现就更简单了,只定义了一个dstSnapshotId字段用于保存重命名操作前目标路径的最新快照的版本号。WithName和DstReference在构造时都会调用父类的构造方法指向WithCount对象,同时还会调用WithCount.addReference()方法配置WithCount对象。 publicstaticclassWithNameextendINodeReference{ privatefinalbyte[]name;//重命名前的文件名 privatefinalintlastSnapshotId; publicWithName(INodeDirectoryparent,WithCountreferred,bytep[]name,intlastSnapshotId){ super(parent,referred);//调用父类构造方法,指向WithCount节点 this.name=name; this.lastSnapshotId=lastSnapshotId; referred.addReferenct(this);//调用WithCount.addReferenct() } //... } publicstaticclassDstReferenceextendsINodeReference{ privatefinalintdstSnapshotId; publicDstReference(INodeDirectoryparent,WithCountreferred,finalintdstSnapshotId){ super(parent,referred); this.lastSnapshotId=lastSnapshotId; referred.addReferenct(this);//调用WithCount.addReferenct() } //.. }

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

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

WebStorm

WebStorm

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

用户登录
用户注册