Android内存优化——内存泄露检测分析方法

上一篇文章总结了一些常见的内存泄露场景及优化方案,这篇文章继续总结内存泄露的一些常用的检测和分析方法。

Lint代码检查

AndroidStudio自动Lint代码检查工具,一些常见的代码警告Lint工具都会给我们提示。使用也比较简单:

Analyze —> Inspect Code 然后选择检查范围:

Lint使用-1

Lint使用-2

Lint使用-3

比如如果存在非静态内部类的Handler,可能会导致内存泄露,检查结果就会显示在AndroidStudio的控制台。

其实,只要我们在设置里面勾选了Lint代码检查(AnroidStudio默认是勾选了的),在写代码的时候就会自动提示可能发生内存泄露。

Lint检查代码内存泄露

Lint提示内存泄露

通常在写Handler、静态字段、标记对象等可能存在的内存泄露时,Lint检查工具都会有一个警告提示信息,我们可以根据Lint检查的提示信息来避免这些有可能发生的内存泄露。

Android Monitor

在AndroidStudio中,可以通过Monitors来监控Memory、CPU、Network、GPU等。在Monitors监控中,我们可以获取内存的各种信息来分析内存泄露。

首先运行工程后,打开控制台的Android Monitor:

Android Monitor

在运行设备中使用app(各个页面的跳转,使用相应的各种功能),就可以看到内存使用的不断变化:

内存使用变化

淡蓝色和浅灰色区域就是内存分配的变化过程,浅灰色表示空闲内存,淡蓝色表示使用内存。

通常,我们在打开一个新的页面后,使用的内存就会增加,相应的,关闭一个页面后,系统执行了GC,使用的内存应该下降。如果我们在退出界面并执行GC后,内存使用并未下降明显,或者使用内存没有下降初始的使用大小,那么有可能就发生了内存泄露。

运行工程,在设备上操作app,观察Monitor中内存的变化,点击 initiate GC 触发GC,然后点击Dump Java Heap转出堆信息,稍等片刻,生成hprof文件,生成后会在Studio中自动打开。

hprof文件

点击右侧的Analyzer Tasks,再点击Perform Analyzer,展开下面分析结果
中的 Leaked Activities 就可以看到发生内存泄露的Activity了。

Monitor内存泄露分析

可以根据左侧的引用树,来查找持有Activity引用的位置,从而判断出哪个地方导致了内存泄露。

Mat

使用第三方的Mat工具来分析内存泄露,需要在官网下载独立版的Mat。

将Android Monitor生成的hprof文件导出为标准的hprof文件(必须这样导出,直接copy出来会报错的):

导出hprof文件

使用Mat打开导出的hprof文件:

Mat打开hprof文件

点击Histogram(直方图),可以看到类对应的实例数量的统计。

直方图

在Class Name下面输入需要匹配的类名,根据类来查看它的实例的引用,进而分析是否存在内存泄露。

类的实例

可以看到TestActivity和MyHandler都只有一个实例被引用。

TestActivity点击右键—>Merge Shortest Paths to GC Roots —>exclude all phantom/weak/soft etc.references。

Merge Shortest Paths to GC Roots 可以查看一个对象到RC Roots是否存在引用链相连接, 在JAVA中是通过可达性(Reachability Analysis)来判断对象是否存活,这个算法的基本思想是通过一系列的称谓"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走得路径称为引用链,当一个对象到GC Roots没有任何引用链相连则该对象被判定为可以被回收的对象,反之不能被回收,我们可以选择 exclude all phantom/weak/soft etc.references(排查虚引用/弱引用/软引用等)因为被虚引用/弱引用/软引用的对象可以直接被GC给回收。

参考自Android 性能优化之使用MAT分析内存泄露问题。

TestActivity实例 RC Roots引用链

可以看到TestActivity实例存在GC Roots链,TextActivity实例被mMessageQueue.mMessae.target.this$0持有,那么发生了内存泄露,我们可以根据引用链来在代码中找到内存泄露的位置。

LeakCanary

LeakCanary是square开源的检测内存泄露的第三方库。它最大的有点就是开发者只需要添加简单代码,app在运行时如果发生了内存泄露,就会很直观的将内存泄露的详细信息展示在通知栏上,这样避免了Android Monitor或者Mat等工具的繁琐的分析过程。

项目地址:github.com/square/leak…

在Gradle文件中添加依赖:

 dependencies {debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'}复制代码

在入口的Application中进行初始化:

public class App extends Application {// 模拟内存泄露场景public static ArrayList<Activity> sActivities = new ArrayList<>();@Overridepublic void onCreate() {super.onCreate();if (LeakCanary.isInAnalyzerProcess(this)) {// This process is dedicated to LeakCanary for heap analysis.// You should not init your app in this process.return;}LeakCanary.install(this);// Normal app init code...}
}复制代码

在Application中新建一个静态List,里面存储Activity,来模拟内存泄露案例:

public class TestActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_test);App.sActivities.add(this);}public void back(View view) {finish();}
}复制代码

运行app后,在控制台可以看到LeakCanary的日志:

04-25 10:20:46.793 D/LeakCanary: In com.xiao.memoryleakexample:1.0:1.
04-25 10:20:46.793 D/LeakCanary: * com.xiao.memoryleakexample.TestActivity has leaked:
04-25 10:20:46.793 D/LeakCanary: * GC ROOT static com.xiao.memoryleakexample.app.App.sActivities
04-25 10:20:46.793 D/LeakCanary: * references java.util.ArrayList.array
04-25 10:20:46.793 D/LeakCanary: * references array java.lang.Object[].[0]
04-25 10:20:46.793 D/LeakCanary: * leaks com.xiao.memoryleakexample.TestActivity instance
04-25 10:20:46.793 D/LeakCanary: * Retaining: 88 KB.
04-25 10:20:46.793 D/LeakCanary: * Reference Key: 915bf11a-db9f-468e-8064-d6fb103710e9
04-25 10:20:46.793 D/LeakCanary: * Device: OPPO OPPO OPPO R9 Plusm A R9PlusmA
04-25 10:20:46.793 D/LeakCanary: * Android Version: 5.1.1 API: 22 LeakCanary: 1.5 00f37f5
04-25 10:20:46.793 D/LeakCanary: * Durations: watch=5049ms, gc=207ms, heap dump=979ms, analysis=122889ms
04-25 10:20:46.793 D/LeakCanary: * Details:
04-25 10:20:46.793 D/LeakCanary: * Class com.xiao.memoryleakexample.app.App
04-25 10:20:46.793 D/LeakCanary: |   static $staticOverhead = byte[24]@314667009 (0x12c17001)
04-25 10:20:46.793 D/LeakCanary: |   static sActivities = java.util.ArrayList@315492800 (0x12ce09c0)
04-25 10:20:46.793 D/LeakCanary: |   static serialVersionUID = -920324649544707127
04-25 10:20:46.793 D/LeakCanary: |   static $change = null
04-25 10:20:46.793 D/LeakCanary: * Instance of java.util.ArrayList
04-25 10:20:46.793 D/LeakCanary: |   static $staticOverhead = byte[16]@1893824473 (0x70e177d9)
04-25 10:20:46.793 D/LeakCanary: |   static MIN_CAPACITY_INCREMENT = 12
04-25 10:20:46.793 D/LeakCanary: |   static serialVersionUID = 8683452581122892189
04-25 10:20:46.793 D/LeakCanary: |   array = java.lang.Object[12]@318048768 (0x12f50a00)
04-25 10:20:46.793 D/LeakCanary: |   size = 1
04-25 10:20:46.793 D/LeakCanary: |   modCount = 1
04-25 10:20:46.793 D/LeakCanary: * Array of java.lang.Object[]
04-25 10:20:46.793 D/LeakCanary: |   [0] = com.xiao.memoryleakexample.TestActivity@316091520 (0x12d72c80)
04-25 10:20:46.793 D/LeakCanary: |   [1] = null
04-25 10:20:46.793 D/LeakCanary: |   [2] = null
04-25 10:20:46.793 D/LeakCanary: |   [3] = null
04-25 10:20:46.793 D/LeakCanary: |   [4] = null
04-25 10:20:46.793 D/LeakCanary: |   [5] = null
04-25 10:20:46.793 D/LeakCanary: |   [6] = null
04-25 10:20:46.793 D/LeakCanary: |   [7] = null
04-25 10:20:46.793 D/LeakCanary: |   [8] = null
04-25 10:20:46.793 D/LeakCanary: |   [9] = null
04-25 10:20:46.793 D/LeakCanary: |   [10] = null
04-25 10:20:46.793 D/LeakCanary: |   [11] = null
04-25 10:20:46.793 D/LeakCanary: * Instance of com.xiao.memoryleakexample.TestActivity
04-25 10:20:46.793 D/LeakCanary: |   static $staticOverhead = byte[16]@316125185 (0x12d7b001)
04-25 10:20:46.793 D/LeakCanary: |   static serialVersionUID = 836998863274086997
04-25 10:20:46.793 D/LeakCanary: |   static $change = null
04-25 10:20:46.793 D/LeakCanary: |   mHandler = com.xiao.memoryleakexample.TestActivity$MyHandler@318005952 (0x12f462c0)
04-25 10:20:46.793 D/LeakCanary: |   mDelegate = android.support.v7.app.AppCompatDelegateImplV14@314816320 (0x12c3b740)
04-25 10:20:46.793 D/LeakCanary: |   mEatKeyUpEvent = false
04-25 10:20:46.793 D/LeakCanary: |   mResources = null
04-25 10:20:46.793 D/LeakCanary: |   mThemeId = 2131230884
04-25 10:20:46.793 D/LeakCanary: |   mCreated = true
04-25 10:20:46.793 D/LeakCanary: |   mFragments = android.support.v4.app.FragmentController@317876896 (0x12f26aa0)
04-25 10:20:46.793 D/LeakCanary: |   mHandler = android.support.v4.app.FragmentActivity$1@318005920 (0x12f462a0)
04-25 10:20:46.793 D/LeakCanary: |   mNextCandidateRequestIndex = 0
04-25 10:20:46.793 D/LeakCanary: |   mOptionsMenuInvalidated = false
04-25 10:20:46.793 D/LeakCanary: |   mPendingFragmentActivityResults = android.support.v4.util.SparseArrayCompat@318008352 (0x12f46c20)
04-25 10:20:46.793 D/LeakCanary: |   mReallyStopped = true
04-25 10:20:46.793 D/LeakCanary: |   mRequestedPermissionsFromFragment = false
04-25 10:20:46.793 D/LeakCanary: |   mResumed = false
04-25 10:20:46.793 D/LeakCanary: |   mRetaining = false
04-25 10:20:46.793 D/LeakCanary: |   mStopped = true
04-25 10:20:46.793 D/LeakCanary: |   mStartedActivityFromFragment = false
04-25 10:20:46.793 D/LeakCanary: |   mStartedIntentSenderFromFragment = false
04-25 10:20:46.793 D/LeakCanary: |   mExtraDataMap = android.support.v4.util.SimpleArrayMap@318005888 (0x12f46280)
04-25 10:20:46.793 D/LeakCanary: |   mActionBar = null
04-25 10:20:46.793 D/LeakCanary: |   mActivityInfo = android.content.pm.ActivityInfo@318009472 (0x12f47080)
04-25 10:20:46.793 D/LeakCanary: |   mActivityTransitionState = android.app.ActivityTransitionState@317937344 (0x12f356c0)
04-25 10:20:46.793 D/LeakCanary: |   mAllLoaderManagers = android.util.ArrayMap@318081312 (0x12f58920)
04-25 10:20:46.793 D/LeakCanary: |   mApplication = com.xiao.memoryleakexample.app.App@315492832 (0x12ce09e0)
04-25 10:20:46.793 D/LeakCanary: |   mCalled = true
04-25 10:20:46.793 D/LeakCanary: |   mChangeCanvasToTranslucent = false
04-25 10:20:46.793 D/LeakCanary: |   mChangingConfigurations = false
04-25 10:20:46.793 D/LeakCanary: |   mCheckedForLoaderManager = true
04-25 10:20:46.793 D/LeakCanary: |   mComponent = android.content.ComponentName@314990768 (0x12c660b0)
04-25 10:20:46.793 D/LeakCanary: |   mConfigChangeFlags = 0
04-25 10:20:46.793 D/LeakCanary: |   mContainer = android.app.Activity$1@317876848 (0x12f26a70)
04-25 10:20:46.793 D/LeakCanary: |   mCurrentConfig = android.content.res.Configuration@317856672 (0x12f21ba0)
04-25 10:20:46.793 D/LeakCanary: |   mDecor = null
04-25 10:20:46.793 D/LeakCanary: |   mDefaultKeyMode = 0
04-25 10:20:46.793 D/LeakCanary: |   mDefaultKeySsb = null
04-25 10:20:46.793 D/LeakCanary: |   mDestroyed = true
04-25 10:20:46.793 D/LeakCanary: |   mDoReportFullyDrawn = false
04-25 10:20:46.793 D/LeakCanary: |   mEmbeddedID = null
04-25 10:20:46.793 D/LeakCanary: |   mEnableDefaultActionBarUp = false
04-25 10:20:46.793 D/LeakCanary: |   mEnterTransitionListener = android.app.SharedElementCallback$1@1893595344 (0x70ddf8d0)
04-25 10:20:46.793 D/LeakCanary: |   mExitTransitionListener = android.app.SharedElementCallback$1@1893595344 (0x70ddf8d0)
04-25 10:20:46.793 D/LeakCanary: |   mFinished = true
04-25 10:20:46.793 D/LeakCanary: |   mFragments = android.app.FragmentManagerImpl@317856448 (0x12f21ac0)
04-25 10:20:46.793 D/LeakCanary: |   mHandler = android.os.Handler@318005856 (0x12f46260)
04-25 10:20:46.793 D/LeakCanary: |   mIdent = 578025123
04-25 10:20:46.793 D/LeakCanary: |   mInstanceTracker = android.os.StrictMode$InstanceTracker@317876864 (0x12f26a80)
04-25 10:20:46.793 D/LeakCanary: |   mInstrumentation = android.app.Instrumentation@315352176 (0x12cbe470)
04-25 10:20:46.793 D/LeakCanary: |   mIntent = android.content.Intent@317362304 (0x12ea9080)
04-25 10:20:46.793 D/LeakCanary: |   mLastNonConfigurationInstances = null
04-25 10:20:46.793 D/LeakCanary: |   mLoaderManager = null
04-25 10:20:46.793 D/LeakCanary: |   mLoadersStarted = false
04-25 10:20:46.793 D/LeakCanary: |   mMainThread = android.app.ActivityThread@314856000 (0x12c45240)
04-25 10:20:46.803 D/LeakCanary: |   mManagedCursors = java.util.ArrayList@318005792 (0x12f46220)
04-25 10:20:46.803 D/LeakCanary: |   mManagedDialogs = null
04-25 10:20:46.803 D/LeakCanary: |   mMenuInflater = null
04-25 10:20:46.803 D/LeakCanary: |   mParent = null
04-25 10:20:46.803 D/LeakCanary: |   mReferrer = java.lang.String@314984512 (0x12c64840)
04-25 10:20:46.803 D/LeakCanary: |   mResultCode = 0
04-25 10:20:46.803 D/LeakCanary: |   mResultData = null
04-25 10:20:46.803 D/LeakCanary: |   mResumed = false
04-25 10:20:46.803 D/LeakCanary: |   mSearchManager = null
04-25 10:20:46.803 D/LeakCanary: |   mStartedActivity = false
04-25 10:20:46.803 D/LeakCanary: |   mStopped = true
04-25 10:20:46.803 D/LeakCanary: |   mTemporaryPause = false
04-25 10:20:46.803 D/LeakCanary: |   mTitle = java.lang.String@316164352 (0x12d84900)
04-25 10:20:46.803 D/LeakCanary: |   mTitleColor = 0
04-25 10:20:46.803 D/LeakCanary: |   mTitleReady = true
04-25 10:20:46.803 D/LeakCanary: |   mToken = android.os.BinderProxy@314983040 (0x12c64280)
04-25 10:20:46.803 D/LeakCanary: |   mTranslucentCallback = null
04-25 10:20:46.803 D/LeakCanary: |   mUiThread = java.lang.Thread@1967775656 (0x7549dfa8)
04-25 10:20:46.803 D/LeakCanary: |   mVisibleBehind = false
04-25 10:20:46.803 D/LeakCanary: |   mVisibleFromClient = true
04-25 10:20:46.803 D/LeakCanary: |   mVisibleFromServer = true
04-25 10:20:46.803 D/LeakCanary: |   mVoiceInteractor = null
04-25 10:20:46.803 D/LeakCanary: |   mWindow = com.android.internal.policy.impl.PhoneWindow@315631936 (0x12d02940)
04-25 10:20:46.803 D/LeakCanary: |   mWindowAdded = true
04-25 10:20:46.803 D/LeakCanary: |   mWindowManager = android.view.WindowManagerImpl@318006848 (0x12f46640)
04-25 10:20:46.803 D/LeakCanary: |   mInflater = com.android.internal.policy.impl.PhoneLayoutInflater@317929312 (0x12f33760)
04-25 10:20:46.803 D/LeakCanary: |   mOverrideConfiguration = null
04-25 10:20:46.803 D/LeakCanary: |   mResources = android.content.res.Resources@314591360 (0x12c04880)
04-25 10:20:46.803 D/LeakCanary: |   mTheme = android.content.res.Resources$Theme@318006400 (0x12f46480)
04-25 10:20:46.803 D/LeakCanary: |   mThemeResource = 2131230884
04-25 10:20:46.803 D/LeakCanary: |   mBase = android.app.ContextImpl@317145792 (0x12e742c0)
04-25 10:20:46.803 D/LeakCanary: * Excluded Refs:
04-25 10:20:46.803 D/LeakCanary: | Field: android.view.inputmethod.InputMethodManager.mNextServedView
04-25 10:20:46.803 D/LeakCanary: | Field: android.view.inputmethod.InputMethodManager.mServedView
04-25 10:20:46.803 D/LeakCanary: | Field: android.view.inputmethod.InputMethodManager.mServedInputConnection
04-25 10:20:46.803 D/LeakCanary: | Field: android.view.inputmethod.InputMethodManager.mCurRootView
04-25 10:20:46.803 D/LeakCanary: | Field: android.animation.LayoutTransition$1.val$parent
04-25 10:20:46.803 D/LeakCanary: | Field: android.view.textservice.SpellCheckerSession$1.this$0
04-25 10:20:46.803 D/LeakCanary: | Field: android.support.v7.internal.widget.ActivityChooserModel.mActivityChoserModelPolicy
04-25 10:20:46.803 D/LeakCanary: | Field: android.widget.ActivityChooserModel.mActivityChoserModelPolicy
04-25 10:20:46.803 D/LeakCanary: | Field: android.accounts.AccountManager$AmsTask$Response.this$1
04-25 10:20:46.803 D/LeakCanary: | Field: android.media.MediaScannerConnection.mContext
04-25 10:20:46.803 D/LeakCanary: | Field: android.os.UserManager.mContext
04-25 10:20:46.803 D/LeakCanary: | Field: android.media.AudioManager$1.this$0
04-25 10:20:46.803 D/LeakCanary: | Field: android.widget.Editor$Blink.this$0
04-25 10:20:46.803 D/LeakCanary: | Field: android.net.ConnectivityManager.sInstance
04-25 10:20:46.803 D/LeakCanary: | Field: android.view.Choreographer$FrameDisplayEventReceiver.mMessageQueue (always)
04-25 10:20:46.803 D/LeakCanary: | Static field: android.text.TextLine.sCached
04-25 10:20:46.803 D/LeakCanary: | Thread:FinalizerWatchdogDaemon (always)
04-25 10:20:46.803 D/LeakCanary: | Thread:main (always)
04-25 10:20:46.803 D/LeakCanary: | Thread:LeakCanary-Heap-Dump (always)
04-25 10:20:46.803 D/LeakCanary: | Class:java.lang.ref.WeakReference (always)
04-25 10:20:46.803 D/LeakCanary: | Class:java.lang.ref.SoftReference (always)
04-25 10:20:46.803 D/LeakCanary: | Class:java.lang.ref.PhantomReference (always)
04-25 10:20:46.803 D/LeakCanary: | Class:java.lang.ref.Finalizer (always)
04-25 10:20:46.803 D/LeakCanary: | Class:java.lang.ref.FinalizerReference (always)复制代码

日志当中展示了详细的内存泄露信息。同时,在运行设备上,会以通知的形式展示内存泄露:

LeakCanary内存泄露通知

点击通知栏后会展示消息的内存泄露信息,包括泄露的具体实例、以及发生在哪个类中的具体引用位置:

LeakCanary内存泄露详细信息-1

LeakCanary内存泄露详细信息-2

最后

Lint、Android Monitor、Mat,以及LeakCanary都能让我们在平常的开发过程中非常有效的避免内存泄露,至于选择哪个工具,那种方式,就看自己平常的习惯了。个人还是更喜欢使用LeakCanary,只需要简单的集成,就可以更加快速,直观展示内存泄露的信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/396097.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ImageLoader加载图片

先导universal-image-loader-1.9.3包 在application配置 android:name".MyApplication" intent权限 1 package com.ch.day13_imageloaderdemo;2 3 import java.io.File;4 5 import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache; 6 impor…

hackintosh黑苹果_为什么您的下一个Mac应该是Hackintosh?

hackintosh黑苹果by Sebastian Dobrincu塞巴斯蒂安多布林库(Sebastian Dobrincu) 为什么您的下一个Mac应该是Hackintosh&#xff1f; (Why Your Next Mac Should Be a Hackintosh ?) I just finished a 48-hour Hackintosh building marathon. It was a fun experience and I…

一张图解释什么是遗传算法_遗传算法简介及代码详解

(allele)数据值&#xff0c;属性&#xff0c;值基因座(locus)位置&#xff0c;iterator位置表现型(phenotype)参数集&#xff0c;解码结构&#xff0c;候选解染色体&#xff1a;又可以叫做基因型个体(individuals)群体/种群(population)&#xff1a;一定数量的个体组成&#xf…

c语言程序设计学生程序查询,《c语言程序设计报告-学生信息管理系统》.doc

《c语言程序设计报告-学生信息管理系统》中南大学??C语言程序设计实践报告?????题 目 学生信息管理系统学生姓名 张眼指导教师 刘伟荣学 院 信息科学与工程学院专业班级 电气信息1113班完成时间 2012年6月28日星期四?1.设计任务及设计目标学生信息管理系统是基于系统主…

ListString 和 ArrayListString的区别

最近对这两个问题比较懵逼&#xff0c;关于List和ArrayList、List<String> list new ArrayList<String>(); 好了&#xff0c;先搞明白List 和 ArrayList吧。 List是一个接口&#xff0c;是Collection接口的一个子接口&#xff0c;是一个有序的集合。 ArrayList是L…

java城市级联一次查询_我的城市没有任何设计活动,所以我自己组织了一次。...

java城市级联一次查询by Marty Laurita由Marty Laurita 我的城市没有任何设计活动&#xff0c;所以我自己组织了一次。 (There weren’t any design events in my city, so I organized one myself.) “The meeting of two personalities is like the contact of two chemical…

Access denied for user 'root'@'localhost' (using password: YES) 问题解决小记

初学php&#xff0c;按照视频安装后好mysql后 终端运行命令 mysql -u root -p 然后输入安装mysql时输入的密码六个1&#xff0c;会报这样的错误&#xff1a;Access denied for user rootlocalhost (using password: YES) &#xff1b; 百度了一大堆&#xff0c;大海捞针一般找…

汇编总结2

一、寄存器 一个典型的cpu是由运算器&#xff0c;控制器&#xff0c;寄存器等器件组成的。 内部总线实现CPU内部各个器件之间的联系 外部总线实现cpu和主板上其他器件的联系 AX,BX,CX,DX通用寄存器 SI,DI,BP,SP基址和变址寄存器 CS,SS,DS,ES段寄存器 IP,FLAGS指令指针和标志寄存…

创业者具备的五大技能_一、如今大学生创业需要具备哪些知识与技能?

我参加过两次互联网&#xff0b;大赛&#xff0c;分别获得过省赛的金奖与银奖&#xff0c;还曾参加山东省大大小小比赛26场&#xff0c;金奖累计获得12次。对当代创业的大学生所应具备哪些基本素质深有体会。&#xff08;1&#xff09;技能&#xff1a;1、自我认知及科学规划能…

c语言定时器回调函数的参数,定时器的简单实现即回调函数的运用

&#xfeff;&#xfeff;这两天在 研究回调函数就想实现简单的定时器&#xff0c;如下是鄙人的程序望指教。ios#include #include using namespace std;app#define MAXNUM 256函数typedef void (*timerProcessFunc)(void*);spatypedef struct{unsigned int id;int timeout; /…

BZOJ3387栅栏行动

首先&#xff0c;很容易想到Dp。设f[i][0]表示第i个栅栏走左边的最短路&#xff0c;f[i][1]表示第i个栅栏走右边的最短路。 所以&#xff0c;我们要找一个刚好在第i个栅栏的左右边界下面的栅栏。如图所示&#xff1a; 则有&#xff1a; f[i][0] min(f[k][0] |Left[i] - Left[…

udacity开源的数据_评论:Udacity数据分析师纳米学位计划

udacity开源的数据by David Venturi大卫文图里(David Venturi) 评论&#xff1a;Udacity数据分析师纳米学位计划 (Review: Udacity Data Analyst Nanodegree Program) Udacity’s Data Analyst Nanodegree program was one of the first online data science programs in the …

凌晨四点钟深圳的风景

科比有过一句很励志的故事&#xff1a;凌晨四点钟洛杉矶的风景。 很多人把科比当成榜样&#xff0c;不仅仅因为他精湛的球技&#xff0c;更是因为他远超常人的职业精神。 其实做到这一点&#xff0c;并不难&#xff0c;难的是坚持。坚持那么早时间起床&#xff0c;坚持十年如一…

小程序沉浸式_古北水镇红叶祭嵌入戏精学院 全新文旅沉浸模式让游客嗨起来...

2020年10月17日-24日&#xff0c;古北水镇第二届红叶祭火热来袭。今年除了“超级漫展二次元度假”的模式&#xff0c;古北水镇与顶级沉浸互动体验运营方——INX戏精学院合作&#xff0c;在深度体验空间的同时&#xff0c;加入了互动式的实景游戏体验&#xff0c;通过演员互动&a…

又拍云刘平阳,理性竞争下的技术品牌提升之道

云服务市场趋渐平稳&#xff0c;在这种情况下&#xff0c;就需要通过对某一项技术的深入应用来实现服务的精致化。同时&#xff0c;对品牌的打造和包装也必不可少。\\又拍云在2010年开始提供云服务&#xff0c;经过多年的发展&#xff0c;以及市场策略的转变&#xff0c;决定对…

编写代码的工作在哪找_编写事件代码如何帮助我获得了出色的工作

编写代码的工作在哪找Everyone kept telling me about the importance of networking, but it was always something I blew off. I’m pretty quiet and introverted, particularly when meeting strangers. I thought I just wasn’t built for networking.每个人都在不断告诉…

int x = 0x13 c语言,2004年7月全国高等教育自学考试微型计算机原理与接口技术试题...

课程代码&#xff1a;02205第一部分 C语言程序设计一、单项选择题(在每小题的四个备选答案中&#xff0c;选出一个正确答案&#xff0c;并将正确答案的序号填在题干的括号内。每小题2分&#xff0c;共10分)1.4位无符号二进制数表示的数的范围是( )。A.0&#xff5e;9999 B.…

iOS开发简单高效的数据存储

在iOS开发过程中&#xff0c;不管是做什么应用&#xff0c;都会碰到数据保存的问题&#xff0c;你是用什么方法来持久保存数据的&#xff1f;这是在几乎每一次关于iOS技术的交流或讨论都会被提到的问题&#xff0c;而且大家对这个问题的热情持续高涨。本文主要从概念上把“数据…

Oracle中Date和Timestamp的区别

Date和Timestamp精度不一样&#xff1a; 01&#xff09;Timestamp精确到了秒的小数点&#xff08;如&#xff1a;2018-11-13 16:40:03.698&#xff09;&#xff1b; 02&#xff09;Date只精确到整数的秒&#xff08;如&#xff1a;2018-11-13 16:40:03&#xff09; 转载于:http…

table偏见和HTML仇外心理

by Anthony Ng由Anthony Ng <table>偏见和HTML仇外心理 (<table> prejudice and HTML xenophobia) I was looking over some HTML with a student the other day when we stumbled onto a <table>.前几天&#xff0c;当我偶然发现一个<table>时&#…