一、简介

在 android 系统中,为同一管理系统的属性,设计了一个统一的属性系统。每个属性都有一个名字和值,他们都是字符串格式。属性被大量使用在 Android 系统中,用来记录系统设置或进程之间的信息交换。属性是在整个系统中全局可见的。每个进程可以 get/set 属性。在编译的过程中会将各种系统参数汇总到 build.proc 以及 default.proc 这两个文件中,主要属性集中在 build.proc 中。系统在开机后将读取配置信息并构建共享缓冲区,加快查询速度。另外一个方面,SettingProvider 会在系统第一次初始化时(刷机第一次启动)后,将从 Default.xml 中读取数据然后写入数据库 Settings.db 目录。并构建一个缓冲系统供其他应用查询。下面将详细讲述。

二、Properties Type

系统属性根据不同的应用类型,分为不可变型,持久型,网络型,启动和停止服务等。

特别属性:

  • 属性名称以 "ro." 开头,那么这个属性被视为只读属性。一旦设置,属性值不能改变。
  • 属性名称以 "persist." 开头,当设置这个属性时,其值也将写入 /data/property。
  • 属性名称以 "net." 开头,当设置这个属性时,"net.change" 属性将会自动设置,以加入到最后修改的属性名。(这是很巧妙的。netresolve 模块的使用这个属性来追踪在 net.* 属性上的任何变化。)
  • 属性 "ctrl.start" 和 "ctrl.stop" 是用来启动和停止服务。每一项服务必须在 /init.rc 中定义。系统启动时,与 init 守护进程将解析 init.rc 和启动属性服务。一旦收到设置 "ctrl.start" 属性的请求,属性服务将使用该属性值作为服务名找到该服务,启动该服务。这项服务的启动结果将会放入 "init.svc.<服务名>" 属性中。客户端应用程序可以轮训那个属性值,以确定结果。

三、Android toolbox

Android toolbox 程序提供了两个工具:setprop 和 getprop 获取和设置属性。其使用方法:

getprop <属性名>

setprop <属性名> <属性值>

Java

在 Java 应用程序可以使用 System.getProperty() 和 System.setProperty() 函数获取和设置属性。

Action

默认情况下,设置属性只会使 "init" 守护程序写入共享内存,它不会执行任何脚本或二进制程序。但是,您可以将您的想要的实现的操作与 init.rc 中某个属性的变化相关联。例如,在默认的 init.rc 中有:

# adbd on at boot in emulatoron property:ro.kernel.qemu=1start adbdon property:persist.service.adb.enbale=1start adbdon property:persist.service.adb.enable=0stop adbd

4、Properties Source

原则上,属性的设置可以出现在 make android 的任何环节。目前 Properties 的设置以 oppo 版本为例:

alps/build/target/board/generic_arm64/system.prop

alps/build/target/product/core.mk

alps/buid/tools/buildinfo.sh

编译好后,被设置的系统属性主要存放在:

这样,如果你设置 persist.service.adb.enable 为1,"init" 守护进程就知道需要采取行动:开启 adbd 服务。

/default.prop                 手机厂商自己定制使用

/system/build.prop         系统属性主要存放处

/system/default.prop       default properties,存放与 security 相关的属性

/data/local.prop                目前还没有看看到有内置的情况

/data/property

下有4个 prop 文件:persist.sys.timezone,persist.sys.language,persist.sys.country,persist.sys.localevar,里面保存着属性名称以 "persis." 开头的属性值。用户的 persist 开头的属性都会保存副本在整个目录下。

五、Properties Run

5.1、Properties init

在 linux kernel 启动时,Android 将分配一个共享内存去来存储的属性。这些是由 "init" 守护进程完成的,其源代码位于:system/core/init。"init" 守护进程将启动一个属性服务。属性服务在 "init" 守护进程中运行。每一个客户端想要设置属性时,必须连接属性服务,再向其发送信息。属性服务将会在共享内存区中修改和创建属性。客户端想获得属性信息,可以从共享内存直接读取。这提高了读取性能。

客户端应用程序可以调用 libcutils 中的 API 函数以 GET/SET 属性信息。libcutils 的源代码位于:system/core/libcutils。获取和设置属性的代码在 properties.c 里面,读取属性通过读共享内存得到,设置属性通过发送请求到 property_service 进行设置。API 函数是:

int property_get(const char *key, char *value, const char *default_value);
int property_set(const char *key, const char *value);int property_list(void(*propfn)(const char * key, const char * value, void * cookie), void * cookie);system/core/init. c= > main( ) 进程将调用= > property_init= > init_property_areavoid property_init( void ) {//ashmem_area - android shared memory area是android共享内容存的一种方式//打开ashmem设备,申请一段size大小的kernel空间内存,不去释放,以便供所有用户空间进程共享.//内核驱动位于linux/mm/ashmem.c文件[luther.gliethttp].init_property_area( ) ;
//#define PROP_PATH_RAMDISK_DEFAULT "/default.prop"//从ramdisk中读取default.prop文件,将文件中的所有java环境中使用到的propt释放到//这个共享内存中.load_properties_from_file( PROP_PATH_RAMDISK_DEFAULT) ;}

后面将调用 properties_service.c,启动最原始的 properties service。

然后通过 libc_init_common.c 的 __system_properties_init 函数完成内核的初始化工作。

5.2、属性的访问

如果在 C/C++ 层次,则可以使用 libcutils 的下列函数来访问。

int property_get(const char *key, char *value, const char *default_value);
int property_set(const char *key, const char *value);int property_list(void(*propfn)(const char * key, const char * value, void * cookie), void * cookie);

如果在 Java 层次,则可以使用 System.getProperties/setProperties。该方法(set/get)实际将调用 SystemProperties.java 进行访问,而 SystemProperties.java 通过 jni 调用 libcutils 进行访问。

5.3、Enlarge System Property

Android Default System Property 默认是可以存储 247笔 Properties。但因为我司又大量的数据被写入到这个 system property 中,导致容易出现 system property mmap 到 kernel ashmem 中的缓存 ashmem 溢出。一方面需要确认数据是否确实又必要写入 System property,另外一方面,可以扩大缓存的空间。

缓存区间可以分为两大部分(byte),Info Area,Array Area。Info Area 又分成 Header 和 Name Mapping Area。

因为,给出固定的最大笔数 N。缓存定义上要求

#define PA_COUNT_MAX    N#define PA_INFO_START   ((8+PA_COUNT_MAX) * 4)  //最好保证这个值为32的整数倍#define PA_SZE                (PA_INFO_START + (128 * PA_COUNT_MAX))

5.4、控制属性

在 system properties 中提供两个特殊的 key,ctl.start 和 ctl.stop 来启动和关闭服务。

其 API 描述是:

SystemProperties.set(“ctl.start”,serviceName);SystemProperties.set(“ctl.stop”,serviceName);

注意的是,这个 serviceName 可在 init.rc 中查询。

5.5、Init 属性

Init 属性时 System properties 中的一个特殊的属性,由 init.c 定义,init 会监控定义在 init.rc 中的服务,并定义 init.svc.xxxx 的 System properties。

具体实现,可参考 init.c 中 notify_service_state 函数。

我们除了直接 ps 来查看这些进程信息外,还可以直接通过查看 system properties 来确认这些服务的状态,如:

[init.svc.bootlogoupdater]: [stopped][init.svc.pvrsrvinit]: [stopped][init.svc.servicemanager]: [running][init.svc.vold]: [running][init.svc.netd]: [running][init.svc.netdiag]: [running][init.svc.hald]: [running][init.svc.debuggerd]: [running][init.svc.zygote]: [running][init.svc.drmserver]: [running][init.svc.media]: [running][init.svc.dbus]: [running][init.svc.installd]: [running][init.svc.keystore]: [running][init.svc.console]: [running][init.svc.adbd]: [running][init.svc.ril-daemon]: [running]

5.6、属性安全性

作为一个共享的缓存系统,并非任何 AP 都可以随意去修改其中的属性,针对这些属性,如果进行更改时,会有 UID 上的约束。

/* White list of permissions for setting property services. */
struct {const char *prefix;unsigned int uid;unsigned int gid;
} property_perms[] = {{ "net.rmnet0.",      AID_RADIO,    0 },{ "net.gprs.",        AID_RADIO,    0 },{ "net.ppp",          AID_RADIO,    0 },{ "net.qmi",          AID_RADIO,    0 },{ "net.lte",          AID_RADIO,    0 },{ "net.cdma",         AID_RADIO,    0 },{ "ril.",             AID_RADIO,    0 },{ "gsm.",             AID_RADIO,    0 },{ "persist.radio",    AID_RADIO,    0 },{ "net.dns",          AID_RADIO,    0 },{ "sys.usb.config",   AID_RADIO,    0 },{ "net.",             AID_SYSTEM,   0 },{ "dev.",             AID_SYSTEM,   0 },{ "runtime.",         AID_SYSTEM,   0 },{ "hw.",              AID_SYSTEM,   0 },{ "sys.",             AID_SYSTEM,   0 },{ "sys.powerctl",     AID_SHELL,    0 },{ "service.",         AID_SYSTEM,   0 },{ "wlan.",            AID_SYSTEM,   0 },{ "gps.",             AID_GPS,      0 },{ "bluetooth.",       AID_BLUETOOTH,   0 },{ "dhcp.",            AID_SYSTEM,   0 },{ "dhcp.",            AID_DHCP,     0 },{ "debug.",           AID_SYSTEM,   0 },{ "debug.",           AID_SHELL,    0 },{ "log.",             AID_SHELL,    0 },{ "service.adb.root", AID_SHELL,    0 },{ "service.adb.tcp.port", AID_SHELL,    0 },{ "persist.logd.size",AID_SYSTEM,   0 },{ "persist.sys.",     AID_SYSTEM,   0 },{ "persist.service.", AID_SYSTEM,   0 },{ "persist.security.", AID_SYSTEM,   0 },{ "persist.gps.",      AID_GPS,      0 },{ "persist.service.bdroid.", AID_BLUETOOTH,   0 },{ "selinux."         , AID_SYSTEM,   0 },{ "wc_transport.",     AID_BLUETOOTH,   AID_SYSTEM },{ "build.fingerprint", AID_SYSTEM,   0 },{ "partition."        , AID_SYSTEM,   0},
#ifdef DOLBY_UDC{ "dolby.audio",      AID_MEDIA,    0 },
#endif // DOLBY_UDC
#ifdef DOLBY_DAP// used for setting Dolby specific properties{ "dolby.", AID_SYSTEM,   0 },
#endif // DOLBY_DAP{ "sys.audio.init",   AID_MEDIA,    0 },{ NULL, 0, 0 }
};

具体的 UID 映射为:

#define AID_RADIO         1001  /* telephony subsystem, RIL */
#define AID_BLUETOOTH     1002  /* bluetooth subsystem */
#define AID_GRAPHICS      1003  /* graphics devices */
#define AID_INPUT         1004  /* input devices */
#define AID_AUDIO         1005  /* audio devices */
#define AID_CAMERA        1006  /* camera devices */
#define AID_LOG           1007  /* log devices */
#define AID_COMPASS       1008  /* compass device */
#define AID_MOUNT         1009  /* mountd socket */
#define AID_WIFI          1010  /* wifi subsystem */
#define AID_ADB           1011  /* android debug bridge (adbd) */
#define AID_INSTALL       1012  /* group for installing packages */
#define AID_MEDIA         1013  /* mediaserver process */
#define AID_DHCP          1014  /* dhcp client */
#define AID_SDCARD_RW     1015  /* external storage write access */
#define AID_VPN           1016  /* vpn system */
#define AID_KEYSTORE      1017  /* keystore subsystem */
#define AID_USB           1018  /* USB devices */
#define AID_DRM           1019  /* DRM server */
#define AID_MDNSR         1020  /* MulticastDNSResponder (service discovery) */
#define AID_GPS           1021  /* GPS daemon */
#define AID_UNUSED1       1022  /* deprecated, DO NOT USE */
#define AID_MEDIA_RW      1023  /* internal media storage write access */
#define AID_MTP           1024  /* MTP USB driver access */
#define AID_UNUSED2       1025  /* deprecated, DO NOT USE */
#define AID_DRMRPC        1026  /* group for drm rpc */
#define AID_NFC           1027  /* nfc subsystem */
#define AID_SDCARD_R      1028  /* external storage read access */
#define AID_CLAT          1029  /* clat part of nat464 */
#define AID_LOOP_RADIO    1030  /* loop radio devices */
#define AID_MEDIA_DRM     1031  /* MediaDrm plugins */
#define AID_PACKAGE_INFO  1032  /* access to installed package details */
#define AID_SDCARD_PICS   1033  /* external storage photos access */
#define AID_SDCARD_AV     1034  /* external storage audio/video access */
#define AID_SDCARD_ALL    1035  /* access all users external storage */
#define AID_LOGD          1036  /* log daemon */
#define AID_SHARED_RELRO  1037  /* creator of shared GNU RELRO files */

即如 persist.sys 开头的属性,只能有 system user(包括 root)进行修改,其他用户无法进行修改。

这个 user id 表定义在 /system/core/init/property_service.c 和 /system/core/include/private/android_filesystem_config.h 文件中。

6、Setting Provider

在 android framework 中还定义了 Setting Provider 来对一些比较通用的数据进行初始化,并将数据写入 Settings.db。其中在 Setting Provider 中被初始化的属性写在 defaults.xml 中:

<resources><bool name="def_dim_screen">true</bool><integer name="def_screen_off_timeout">60000</integer><bool name="def_airplane_mode_on">false</bool><!-- Comma-separated list of bluetooth, wifi, and cell. --><string name="def_airplane_mode_radios" translatable="false">cell,bluetooth,wifi</string><string name="airplane_mode_toggleable_radios" translatable="false">wifi</string><bool name="def_auto_time">true</bool><bool name="def_accelerometer_rotation">true</bool><!-- Default screen brightness, from 0 to 255.  102 is 40%. --><integer name="def_screen_brightness">102</integer><bool name="def_screen_brightness_automatic_mode">false</bool><fraction name="def_window_animation_scale">0%</fraction><fraction name="def_window_transition_scale">0%</fraction><bool name="def_haptic_feedback">true</bool><bool name="def_bluetooth_on">false</bool><bool name="def_install_non_market_apps">false</bool><!-- Comma-separated list of location providers.Network location is off by default because it requiresuser opt-in via Setup Wizard or Settings. --><string name="def_location_providers_allowed" translatable="false">gps</string><bool name="assisted_gps_enabled">true</bool><!--  0 == mobile, 1 == wifi. --><integer name="def_network_preference">1</integer><bool name="def_usb_mass_storage_enabled">true</bool><bool name="def_wifi_on">false</bool><bool name="def_networks_available_notification_on">true</bool>   <bool name="def_backup_enabled">false</bool><string name="def_backup_transport" translatable="false"></string><!-- Default value for whether or not to pulse the notification LED when there is apending notification --><bool name="def_notification_pulse">true</bool><bool name="def_mount_play_notification_snd">true</bool><bool name="def_mount_ums_autostart">false</bool><bool name="def_mount_ums_prompt">true</bool><bool name="def_mount_ums_notify_enabled">true</bool><!-- user interface sound effects --><integer name="def_power_sounds_enabled">1</integer><string name="def_low_battery_sound" translatable="false">/system/media/audio/ui/LowBattery.ogg</string><integer name="def_dock_sounds_enabled">0</integer><string name="def_desk_dock_sound" translatable="false">/system/media/audio/ui/Dock.ogg</string><string name="def_desk_undock_sound" translatable="false">/system/media/audio/ui/Undock.ogg</string><string name="def_car_dock_sound" translatable="false">/system/media/audio/ui/Dock.ogg</string><string name="def_car_undock_sound" translatable="false">/system/media/audio/ui/Undock.ogg</string><integer name="def_lockscreen_sounds_enabled">0</integer><string name="def_lock_sound" translatable="false">/system/media/audio/ui/Lock.ogg</string><string name="def_unlock_sound" translatable="false">/system/media/audio/ui/Unlock.ogg</string><!-- Default for Settings.System.VIBRATE_IN_SILENT --><bool name="def_vibrate_in_silent">true</bool></resources>

SettingProvider 将通过 DatabaseHelper 将这些数据读入 Settings.db,同时 SettingsProvider 作为控制 Settings.db 的 Provider,所有对该数据库的操作都要通过它来进行。

其他具体属性的描述都在 Settings.java 这个类中描述。

Settings 为提高访问的效率,建立了 cache,只有当 cache 中找不到时,才会调用 SettingsProvider 去查询 Settings.db 数据库。

具体的 Settings.db 中包括的数据库表有:

关键的 system 表中的数据有:

一般通过修改 default.xml 和 make 中的配置文件即可。

7、About Phone Properties

About Phone中的一些关键属性通过buildinfo.sh 来焊接(make - build), 经过测试,可修改alps\build\tools\buildinfo.sh 来修改显示的情况,整理一下如下:

修改echo "ro.build.display.id=$BUILD_DISPLAY_ID", 把 $BUILD_DISPLAY_ID 修改成其他的名称可改变 Build Nubmer. 注意此时要去除$.

修改echo "ro.product.model=$PRODUCT_MODEL",   把   $PRODUCT_MODEL 修改成其他的名称可改变 Model Nubmer.   注意此时要去除$

修改echo  "ro.build.version.release=2.1" , 中的2.1 可改变显示的Firmware version, 这个不建议修改。

Baseband Version 直接写在 modem.img 中,开机后modem 自动推送到Android端,需要专门的tool 才能修改。

Kernel Version 为linux 编译过程中产生, 按照标准的linux格式生成(compile.h), 最后版本信息写在文件/proc/version 下,所有的版本信息即在该文件的第一行,然后使用了一个正则表达式过滤了版本信息中一些字符。

8、About USER Build and Eng Build

在User <-> Eng 版本中自由切换。

郑重声明:  在出厂正式版本的时候,请务必关闭该feature, 不然将导致机器异常容易被root.

  1. 首先说明一下User Eng 版本之间的差异

eng This is the default flavor. A plain make is the same as make eng.

•        Installs modules tagged with: eng, debug, user, and/or development.

•        Installs non-APK modules that have no tags specified.

•        Installs APKs according to the product definition files, in addition to tagged APKs.

•        ro.secure=0

•        ro.debuggable=1

•        ro.kernel.android.checkjni=1

•        adb is enabled by default.

•        Setupwizard is optional

user make user

This is the flavor intended to be the final release bits.

•        Installs modules tagged with user.

•        Installs non-APK modules that have no tags specified.

•        Installs APKs according to the product definition files; tags are ignored for APK modules.

•        ro.secure=1

•        ro.debuggable=0

•        adb is disabled by default.

•        Enable dex pre-optimization for all TARGET projects in default to speed up device first boot-up

userdebug make userdebug

The same as user, except:

•        Also installs modules tagged with debug.

•        ro.debuggable=1

•        adb is enabled by default.

  2. 从安全角度来将,其差别主要是四个system properties 的设置,在正常情况下,如果不更新boot image, 那么

ro.secure

ro.allow.mock.location

ro.debuggable

是无法被修改的,即在编译的时候就已经决定了

  3. 要使得这几个值能够被修改,那么必须修改system properties 的实现,system properties 的实现上,driver 是ashmem, 上次实现是property_service.c, 需要修改的地方有两处。

  3.1 check_perms 函数中,增加下面一段,放在这个函数的最前面

//add for user -> root

if(!strcmp(name,"ro.secure") || !strcmp(name,"ro.allow.mock.location") || !strcmp(name,"ro.debuggable") || !strcmp(name,"persist.service.adb.enable")){

return 1;

}

  3.2 property_set 函数中屏蔽

/* ro.* properties may NEVER be modified once set */

//for user -> root

// if(!strncmp(name, "ro.", 3)) return -1;

至此,我们已经完全开放了property 中这四个property 的控制权, 当然如果您还想稍微加以控制,您可以增加pid, uid 等的控制,减小这个权限范围。

  4. 编写一个Application, 来实现自由调控,您可以创建一个简单的Application, 里面包括这个Activity 即可。

package com.example.user2root;import android.app.Activity;import android.os.Bundle;import android.os.SystemProperties;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;/**** This is a demo for User To Root.* If you use this app, you MUST open system properties write security.**/public class User2rootActivity extends Activity {/** Called when the activity is first created. */private Button mRootButton;private Button mUserButton;private static final String RO_SECURE = "ro.secure";private static final String RO_ALLOW_MOCK_LOCATION="ro.allow.mock.location";private static final String RO_DEBUG = "ro.debuggable";private static final String ADB_ENABLE = "persist.service.adb.enable";private OnClickListener mRootListener = new Button.OnClickListener(){@Overridepublic void onClick(View v) {SystemProperties.set(ADB_ENABLE, "1");SystemProperties.set(RO_SECURE, "0");SystemProperties.set(RO_ALLOW_MOCK_LOCATION,"1" );SystemProperties.set(RO_DEBUG, "1");Toast.makeText(User2rootActivity.this, "Update to Root Success", Toast.LENGTH_LONG).show();}};private OnClickListener mUserListener = new Button.OnClickListener(){@Overridepublic void onClick(View v) {SystemProperties.set(ADB_ENABLE, "0");SystemProperties.set(RO_SECURE, "1");SystemProperties.set(RO_ALLOW_MOCK_LOCATION,"0" );SystemProperties.set(RO_DEBUG, "0");Toast.makeText(User2rootActivity.this, "Update to User Success", Toast.LENGTH_LONG).show();}};protected void findViews(){this.mRootButton = (Button) this.findViewById(R.id.root);this.mUserButton = (Button) this.findViewById(R.id.user);}protected void setActionListener() {this.mRootButton.setOnClickListener(this.mRootListener);this.mUserButton.setOnClickListener(this.mUserListener);}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);this.findViews();this.setActionListener();}}

至此已经完成了全部的工作,把这个apk 编译进去后,您将发现您可以自由的切换user eng 了。

[Android 基础] -- Android 属性系统简介相关推荐

  1. Android 基础库 - 属性系统 - 属性应用

    属性计算 属性计算,基于javascript语法. 属性提取表示方法 值的表示方法: 定义 表示 说明 常量 0:abc:true 都是字符串,没有冒号 属性值 属性集:属性 冒号分割 扩展值 属性集 ...

  2. Android属性系统简介

    点击打开链接 1.简介 在android 系统中,为统一管理系统的属性,设计了一个统一的属性系统.每个属性都有一个名称和值,他们都是字符串格式.属性被大量使用在Android系统中,用来记录系统设置或 ...

  3. Android基础——Android系统概览

    1. Android系统架构 android大致可以分为四层架构:Linux内核层,系统运行库层.应用框架层和应用层 Linux内核层 android系统是基于Linux内核,这一层为android设 ...

  4. Android基础 : Android Service[转]

    2019独角兽企业重金招聘Python工程师标准>>> 很多情况下,一些与用户很少需要产生交互的应用程序,我们一般让它们在后台运行就行了,而且在它们运行期间我们仍然能运行其他的应用. ...

  5. Android基础 - Android Studio 添加游戏音效

    一.资源添加 在资源文件夹res中,创建raw文件夹,放置音频(mp3.wav).视频文件:New-Folder-Raw Resource Folder 文件命名格式:开头不能是数字,不能为大写字母. ...

  6. Android大厂面试题系统分类从基础到困难(BATJ,蚂蚁金服,字节跳动,网易云,QQ音乐...)

    前言 早在2017年我们就建了第一个进击BAT的Android开发进阶交流群,两年期间很多群友都分享了自己的Android面试经历.其中就有很多群友已经斩获蚂蚁金服,天猫,高德,盒马等阿里系offer ...

  7. Android SystemProperties设置/取得系统属性的用法总结

    2019独角兽企业重金招聘Python工程师标准>>> 1.Android SystemProperties简介 介绍了设置属性需要的权限,已经设置权限的方法. Systemprop ...

  8. Android平台上使用属性系统(property system)

    在使用Android的属性系统(property system)时遇到了一些问题,结合此次经历,对属性系统的使用做以简单介绍. 一.Property系统简介 属性系统是android的一个重要特性.它 ...

  9. Android开发基础——Android简介

    本系列文章主要针对Android 10(Q)进行介绍. Android系统架构 Android大致可以分为4层架构: Linux内核层 系统运行库层 应用框架层 应用层 Linux内核层 Androi ...

最新文章

  1. iostat 命令查看linux磁盘I/O
  2. iOS开发(1)写在前面的话
  3. [diary]极度自恋?
  4. SAP UI5 应用开发教程之六十九 - 如何从 SAP UI5 Not Found 页面跳转回到正常的应用页面
  5. Angular ERROR NullInjectorError: R3InjectorError(AppModule)的错误分析
  6. javascript 西瓜一期 15 数据的存储单位
  7. 实验一 命令解释程序的编写
  8. 本地 mysql 数据库 上线 服务器_MySQL把本地数据库上传到服务器
  9. python换行输出三个数中最大数_关于Python 3中print函数的换行详解
  10. python画雷达图-Python简单雷达图绘制
  11. java实现萤火虫算法_基于萤火虫算法的矢量图生成方法
  12. 轻量级日志收集转发 | fluent-bit配置详解(二)
  13. Google Code的使用指南
  14. 我是一个没有感情的杀手
  15. grpc 源码阅读之 balancer
  16. [生存志] 第71节 阖闾五战入郢
  17. 用计算机处理图像属于啥技术,计算机图像处理技术在网页设计中的应用
  18. 使用JS判断访问设备是电脑还是手机
  19. 服务器主机型号,服务器的主机型号
  20. 【ICML 2015迁移学习论文阅读】Unsupervised Domain Adaptation by Backpropagation (DANN) 无监督领域自适应

热门文章

  1. 解决新版谷歌Chrome浏览器Cookie跨域失效问题
  2. unity2018关联不到vs_vs2017里装了一个unity,现在又装了一个unity3d2018,有何区别?...
  3. java数字猜大小游戏_java实现猜数字小游戏
  4. 【Unity】Rigibody——刚体加力、刚体加扭矩力、刚体加力的几种模式
  5. 虚拟机上安装Windows操作系统
  6. 2012年度IT博客大赛50强报道:陈裕强
  7. 解析北斗/GNSS高精度数据处理暨GAMIT/GLOBK v10.75软件
  8. 软件工程概论 课堂练习【用例图——空调公司维修服务流程】
  9. Arm A-profile feature names
  10. QQ自动登录/QQ登录器/程序源代码/VS2010/VS2012/VC/MFC