首页 文章 精选 留言 我的

精选列表

搜索[多分片],共10000篇文章
优秀的个人博客,低调大师

DataGrip 2019.2.2 发布,多引擎数据库环境

DataGrip 2019.2.2 发布了,更新内容如下: 特性 DBE-4499根据列名添加了 JOIN 完成 DBE-2640markdown 数据提取器与 DataGrip 捆绑 DBE-7315列的拖放变得更加智能:现在它添加了逗号 DBE-8239为 SQL 显示面包屑 DBE-5661,DBE-7960[PostgreSQL]改进了对分区表的支持。关键增强功能:分区表现在显示在主分区表下。 新版本还包含大量 bug 修复,详情可查看发布公告。

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

Java使用位域进行多标记(状态)管理

Android中位域的应用 在Android中,我们会经常用到或者看到以下这样的代码 : public class ExampleUnitTest { @Test public void gravityTest(LayoutParams params) { // 视图在layout中右下角显示 params.gravity = Gravity.RIGHT | Gravity.BOTTOM; } @Test public void intentFlagTest(Intent intent) { // 清空任务栈中所有旧的activity intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); // 如果activity已存在于栈中,清空该activity之上的所有任务 intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); } @Test public void windowMangerFlags(WindowManager.LayoutParams params) { // 不拦截视图以外的事件,在锁屏中显示 params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; } } 通过一个 int字段,来添加多个 标志或者状态. 一个int字段,能够管理多个标记(状态)值. 如此神奇的操作怎样实现的呢? 答案就是通过位运算来实现. 位操作基础 java中提供的基础位运算符有 与(&),或(|),非(~),异或(^),左移<<,右移(>>)和无符号右移(>>>). 除了位非(~)是一元操作符外,其它的都是二元操作符。 下面只介绍本文中,使用到的位操作 按位与 A & B : A和B对应的二进制数位都为1时,结果才为1,其他情况为0. A = 001101 // 13 B = 100101 // 37 A & B = 000101 // 5 按位或 A | B : A和B对应的二进制数位都为0时,结果才为0,其他情况为1. A = 001101 // 13 B = 100101 // 37 A | B = 101101 // 45 按位非 ~A : 将a的二进制表示每一位进行取反操作,0变1,1变0. 相当于相反数 - 1 A = 001101 // 13 ~A = 11111111111111111111111111110010 // int32位,补码表示,第一位为符号位 // 根据上诉补码转原码为 // 10000000000000000000000000001110 // -14 左移操作 A << B:将A的二进制表示的每一位向左移B位,左边超出的位截掉,右边不足的位补0。 在取值范围内,移动一位相当于乘2. A = 001101 // 13 A << 1 = 011010 // 26 原理与实践 通常情况下,如果多个状态或者标记相互之间有关联, 如布局方向,上下左右,左上,居中 ... 等.我们可能会为每一个标记设置一个变量. boolean left = false; boolean right = false; ... void setLeft(boolean b); void setRight(boolean b); ... 这种情况下, 有4个标记相互关联,并且能产生新的标记,那么我们就需要设置4个标记变量,然后只能通过一系列的set方法来转换状态.如 v.setLeft(true); v.setRight(true); 这样就会使得,各个状态不易维护和判断,状态越多,情况越复杂,代码会显得冗长难以维护. 像这种,独立状态(标记)之间相互组合可以产生新的状态(标记),且每个独立状态(标记)只有true或者false值的,我们可以使用位域的概念来管理这些状态. 它的核心思想就是将, int 数值看做是 二进制数位表示.如果有四个状态就可以像这样 0000,用四位二进制表示,每一个二进制位都可以表示一种状态. 然后通过 位运算,来提取或添加标记位.四位对应的组合状态有16个. 而我们,只需要通过一个int变量就能够管理这些状态. 当参与的状态(标记)越多时,如果使用单独的标记变量,就需要生成越多的变量,而用位域,这种独立状态为不管有多少个,都可以用一个变量表示.int类型最多存放32个独立状态 下面我们来看具体实现.(简单的模仿Gravity类的一部分功能) public class Gravity { // 二进制表示 0001 public static final int LEFT = 1; // 二进制表示 0010 public static final int RIGHT = LEFT << 1; // 二进制表示 0100 public static final int TOP = LEFT << 2; // 二进制表示 1000 public static final int BOTTOM = LEFT << 3; // 水平居中, 二进制表示 0011 public static final int HORIZONTAL_CENTER = LEFT | RIGHT; // 垂直居中, 二进制表示 1100 public static final int VERTICAL_CENTER = TOP | BOTTOM; // 居中, 二进制表示 1111 public static final int CENTER = HORIZONTAL_CENTER | VERTICAL_CENTER; // 默认左上角, 二进制表示 0101 public static final int DEFAULT = LEFT | TOP; // 存放标志位 private int mFlags = DEFAULT; // 设置标记位,会清除原来的标记 public void setFlags(int flags) { mFlags = flags; } // 添加标记位,在原来的基础上添加 public void addFlags(int flags) { mFlags |= flags; } // 清除指定的标记 public void clearFlags(int flags) { mFlags &= ~flags; } // 清除所有标记,设为默认 public void clears() { mFlags = DEFAULT; } // 判断是否存在指定的标记 public boolean hasFlags(int flags) { return (mFlags & flags) == flags; } // 判断是否 只有指定的标记 public boolean onlyFlags(int flags) { return mFlags == flags; } public void apply() { String des = "左上角"; if (hasFlags(CENTER)) { des = "整体居中"; } else if (hasFlags(HORIZONTAL_CENTER)) { if (hasFlags(BOTTOM)) des = "水平居中,竖直向下"; else des = "水平居中,竖直向下"; } else if (hasFlags(VERTICAL_CENTER)) { if (hasFlags(RIGHT)) des = "竖直居中,水平向右"; else des = "竖直居中,水平向左"; } else if (hasFlags(LEFT | BOTTOM)) { des = "左下角"; } else if (hasFlags(RIGHT | TOP)) { des = "右上角"; } else if (hasFlags(RIGHT | BOTTOM)) { des = "右下角"; } System.out.println("你选择的布局是 : " + des); } } 具体的调用实现 : public class Main { public static void main(String[] args) { Gravity gravity = new Gravity(); // 设置为 右下角 gravity.setFlags(Gravity.BOTTOM | Gravity.RIGHT); gravity.apply(); // 添加 left后,变为 水平居中,竖直向下 gravity.addFlags(Gravity.LEFT); gravity.apply(); // 判断是否 水平居中, 返回为 true gravity.hasFlags(Gravity.HORIZONTAL_CENTER); // 添加top后,变为 整体居中了 gravity.addFlags(Gravity.TOP); gravity.apply(); // 删掉 bottom和left 之后,变为右上角了 gravity.clearFlags(Gravity.BOTTOM | Gravity.LEFT); gravity.apply(); } } // 结果 你选择的布局是 : 右下角 你选择的布局是 : 水平居中,竖直向下 你选择的布局是 : 整体居中 你选择的布局是 : 右上角

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

centos6 多段Ip添加shell脚本

#!/bin/bash export device=`ifconfig|grep eth0|head -n 1|awk '{print ($1)}'` export ipcfg_pre="/etc/sysconfig/network-scripts/ifcfg-eth1-range" awktmp=`mktemp` msg=`mktemp` ip_txt=`mktemp` ifcfgs="$(find ${ipcfg_pre%/*} -name ${ipcfg_pre##*/}*)" if test ! -z "$ifcfgs";then echo "发现如下已有配置文件是否删除(yes/no)?" echo "$ifcfgs" select var in "yes" "no" do if test "$var" = "yes";then rm -f $ifcfgs break; else break; fi done fi #脚本保存进 临时文件 不再使用a.awk文件。 cat >$awktmp <<EOF #!/usr/bin/awk -f BEGIN{ ipcfg_pre="${ipcfg_pre}" #你需要修改 ipcfg_pre 为自己的路径前缀 device=ENVIRON["device"] clone_num=1; numofpc[24]=253 numofpc[24]=125 numofpc[26]=61 numofpc[27]=29 numofpc[28]=13 numofpc[29]=5 } function ip_str(iplist){ return sprintf("%s.%s.%s.%s",ip_list[1],ip_list[2],ip_list[3],ip_list[4]); } function gen_mask(num,mask_bin, _ARGVEND_,sum,bits){ #把掩码由数字转换成数组 _i=1; mask_bin[1]=0; for (;_i*8 <=num && _i<=4;_i++){ mask_bin[_i]=255; } bits=num-(_i-1)*8; sum=0; for(;bits>0;bits--){ sum=sum+2^(8-bits); } mask_bin[_i]=sum; _i++; for(;_i<=4;_i++){ mask_bin[_i]=0; } } { ipfile=sprintf("%s%s",ipcfg_pre,NR); split(\$0,ip,"/"); ip_mask=ip[2]; split(ip[1],ip_list,"."); #ip_list 列表保存了 ip 的四个 字节值 ip_start=ip_list[4]+2; ip_end=ip_start+numofpc[ip_mask]-1; printf("DEVICE=%s\n",device)>ipfile printf("BOOTPROTO=static\n")>>ipfile printf("CLONENUM_START=%d\n",clone_num)>>ipfile ip_list[4]=ip_start; printf("IPADDR_START=%s\n",ip_str(ip_list))>>ipfile ip_list[4]=ip_end; printf("IPADDR_END=%s\n",ip_str(ip_list))>>ipfile clone_num+=numofpc[ip_mask]; printf("ONBOOT=yes\n")>>ipfile gen_mask(ip_mask,ip_list) netmask=ip_str(ip_list) printf("NETMASK=%s\n",netmask)>>ipfile } EOF chmod a+x $awktmp msg=`mktemp` cat >$msg <<EOF 请输入IP地址和掩码每行一行(不可出现空白行) 如: 45.34.89.40/29 23.91.3.0/28 23.91.8.32/28 23.91.18.160/28 23.91.28.128/28 EOF vi +":!cat $msg" $ip_txt #service network restart test -e $ip_txt && awk -f $awktmp $ip_txt service network restart rm -f $awktmp $msg $ip_txt rm -f ipcfg.sh ===================================================== 此脚本只适用于 45.34.89.40/29 23.91.3.0/28 23.91.8.32/28 23.91.18.160/28 23.91.28.128/28 这种格式IP段添加,请注意脚本网卡名称和机器网卡名称是否一致 使用方法,命名为ipcfg.sh 1. 会提示IP文件是否已经存在,让选择是否删除。我们只用于第一次添加。尽量不要去补充添加。 2. 按回车键,然后按 i 进入编辑模式,输入IP段。iP段一个一行,不要有空格。 保存。

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

利用 Android Studio 和 Gradle 打包多版本APK

在项目开发过程中,经常会有需要打包不同版本的 APK 的需求。 比如 debug版,release版,dev版等等。 有时候不同的版本中使用到的不同的服务端api域名也不相同。 比如 debug_api.com,release_api.com,dev_api.com等等。 不同的版本对应了不同的 api 域名,还可能对应不同的 icon 等。 如果每次都在打包前修改我们都手动来修改,这样实在是不够方便。 但如果我们使用了 Android Studio 和 Gradle,这个麻烦就可以轻松省去。 具体方式如下: 在 Android Studio 中打开 build.gradle(Module中)的 android 节点下添加如下代码 buildTypes { //这里的名字自定义,不要求大小写 release{ // 这里是在 applicationId 中添加了一个后缀。所以『.』要加上 applicationIdSuffix ".release" // 这里的作用是选择是否混淆代码 minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } dev{ applicationIdSuffix ".dev" minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } // 这里是为了不同过的版本设置一些特殊的参数,并不直接和 buildType 关联。 //例如:使用 buildType 中的 dev 版本,也可以使用 flavors_release 里面设置的自定义参数。这需要自己按照需求制定。 productFlavors{ //自定义名字不过不能和上面buildType中相同,不然Gradle编译会不通过。在这里使用了『flavors_』前缀以便区分。 flavors_release{ // manifestPlaceholders中写到的『str』,『package_name』不支持用大写,否则Gradle编译会不通过。 // 这里所设置的变量可以直接使用在『AndroidManifest.xml』中,使用方式为:${package_name} // android:label="${package_name}" manifestPlaceholders = [str:"releaseStr",package_name:"com.sunhz.mvptest.release"] // 这里的参数是为了在 java 代码中使用,具体的使用方式为:context.getResources().getString(R.string.strKey); resValue("string" , "strKey","releaseStrValue") } flavors_dev{ manifestPlaceholders = [str:"devStr",package_name:"com.sunhz.mvptest.dev"] resValue("string" , "strKey","devStrValue") } } 上面设置完成后,我们要在哪里使用它? 使用方式如下: 在 Android Studio 的工具栏中,找到『Build』项,找到『Generate Signed APK…』。 选择 Module -> 创建 APK key,或者输入 APK key密码 -> 关键来了!如下图。 在『BuildType』处,选择我们在 build.gradle 中设置的两个 BuildType,分别是releas,dev,debug。其中『debug』为 Android Studio 自带的。 在『Flavors』处,选择我们在 build.gradle 中设置的两个Flavors,以方便直接使用定义在 build.gradle 中自定义的参数。 所以! 上面我有提到说,buildType 和 Flavors 并没有直接的联系。 他们可以根据用户需求互相配合使用。如上图,BuildType 选择了 release,但 Flavors 选择的却是 flavors_dev。 到此基本的使用就全部说完了。 这里有一个问题,打出来的不同版本的包,全部都能够在同一部手机上安装,且能够将两个包全都发布到 Google 的市场上去这是为什么呢? 这里就要提到在 BuildType 中我们所设置的『applicationIdSuffix』属性了,按照这个属性的字面翻译为:『applicationId 的后缀』,那这里又来了一个问题,『applicationId』是什么? 其实这个『applicationId』属性,实际上在项目创建完成后就存在于 build.gradle 中。在 android 节点下的 defaultConfig 节点中。而且默认的 applicationId 和 AndroidManifest.xml 中的 package 属性相同。 如下图: 我们能够看到,这两个属性的默认值是相同的。 applicationId 和 packageName 它们是什么关系? 默认创建项目后,两者相同。如果需要根据不同的需求构建不同版本的APK,这时我们通过设置『applicationIdSuffix』可以做到。 这里有一个值得注意的现象。 举个例子,我们在打包时使用了 dev 类型,将打包出来的 APK 软件安装到手机中。 使用如下代码,获取我们手机上所有程序的packageName。 PackageManager packageManager = mContext.getPackageManager(); List<PackageInfo> packageInfoList = packageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS); List<String> packageNameList = new ArrayList<String>(); for (PackageInfo packageInfo : packageInfoList) { packageNameList.add(packageInfo.packageName); } 我们打印出来的包名信息中,会出现 com.spencer_dev.test.dev 。并没有出现 com.spencer_dev.test 。 但是! 如果通过反编译工具,将 APK 包进行反编译直接查看源代码,在 java 代码所在的 src 目录中的包名,还和我们设置的一样,为 com.spencer_dev.test 。可 AndroidManifest.xml 中的 package 和 BuildConfig 类中的 APPLICATION_ID 已经变成了 com.spencer_dev.test.dev 。 applicationId 和 packageName 它们各自代表什么? 按照上面的结果来说, package 代表了 java 代码中的包名。 applicationId 代表了应用中的唯一标识。和应用签名一起用来区别和其他应用不同。我想这也就是为什么 Google 市场能够允许相同应用不同 applicationId 的原因。 长按下方二维码就可以识别关注 本文转自 小强测试帮 51CTO博客,原文链接:http://blog.51cto.com/xqtesting/1737795,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

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

腾讯云软件源

腾讯云软件源

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

Nacos

Nacos

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

WebStorm

WebStorm

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

用户登录
用户注册