快速了解Android回答

網(wǎng)絡(luò)篇:

1.TCP的三次握手和四次揮手:

答:
三次握手:為了知道雙方已經(jīng)準(zhǔn)備好發(fā)送數(shù)據(jù)了平项,二次握手會(huì)造成延遲到達(dá)的請(qǐng)求到達(dá)服務(wù)端使服務(wù)端進(jìn)入等待狀態(tài),造成浪費(fèi)栗菜,而三次握手可以識(shí)別是首次握手和第三次握手(第一次握手發(fā)送seq=x;第二次握手ack=x+1,seq=y庇茫,第三次握手發(fā)送seq=x+1,ack=y+1螃成,這次握手其實(shí)可以攜帶數(shù)據(jù))旦签。
四次揮手:為了知道雙方已經(jīng)結(jié)束發(fā)送數(shù)據(jù),客戶端通知服務(wù)端自己已經(jīng)不能發(fā)送數(shù)據(jù)寸宏,需要知道服務(wù)端是否收到宁炫,這個(gè)需要兩次握手,反之服務(wù)端也需要通過兩次握手才能知道(為什么不能第二次的時(shí)候直接發(fā)送關(guān)閉請(qǐng)求呢氮凝,這樣不是三次就夠了嗎羔巢? 因?yàn)檫@個(gè)時(shí)候不確定是否不能確定服務(wù)端不能發(fā)送信息,所以只是一個(gè)應(yīng)答的過程)罩阵,客戶端等待2個(gè)傳遞時(shí)間的原因:客戶端接收到服務(wù)端的傳送結(jié)束響應(yīng)竿秆,這個(gè)時(shí)候可能有前一個(gè)數(shù)據(jù)還沒到客戶端。

第一次握手


image.png

第二次握手


image.png

第三次握手
image.png

https解決的問題:正確獲得服務(wù)端的共鑰稿壁,采用證書機(jī)制袍辞,另外為了優(yōu)化解密速度,采取對(duì)稱加密

2.TCP流量控制:

答:
解決方案:滑動(dòng)窗口常摧,滑動(dòng)窗口的原理:
接收窗口動(dòng)態(tài)改變


image.png

3.TCP擁塞控制:

答:
指數(shù)增長(zhǎng)階段稱之為慢啟動(dòng)搅吁。
線性增長(zhǎng)階段稱之為擁塞避免
快重傳算法首先要求接收方每收到一個(gè)失序的報(bào)文段后就立即發(fā)出重復(fù)確認(rèn)(為的是使發(fā)送方及早知道有報(bào)文段沒有到達(dá)對(duì)方)而不要等到自己發(fā)送數(shù)據(jù)時(shí)才進(jìn)行捎帶確認(rèn)落午。

4.Https:

答:添加證書機(jī)制谎懦,目的獲取正確的共鑰對(duì)一個(gè)隨機(jī)數(shù)加密傳給服務(wù)端,之后用這個(gè)隨機(jī)數(shù)加密通信過程(加快解密速度)溃斋。

第三方庫(kù):

1.EventBus:

用于線程間通信界拦,訂閱模式(觀察者模式)的經(jīng)典應(yīng)用。
原理速講:

//在activity里注冊(cè)梗劫,這個(gè)就相當(dāng)于把發(fā)布者(EventBus.getDefault())和 訂閱者(activity)聯(lián)系起來
EventBus.getDefault().register(this);

看看register怎么做的(版本不同 大體思路差不多 根據(jù)V2版本)


EventBus.png
 public void register(Object subscriber) {
        // 暫時(shí)不考慮粘后兩個(gè)參數(shù)性事件和優(yōu)先級(jí)
        this.register(subscriber, false, 0);
    }

主體部分享甸,代碼都很簡(jiǎn)潔截碴,往下看

 private synchronized void register(Object subscriber, boolean sticky, int priority) {
        // 獲取這個(gè)Activity對(duì)應(yīng)的SubscriberMethod的列表 ,SubscriberMethod是一個(gè)描述當(dāng)前Activity對(duì)應(yīng)的訂閱方法的類蛉威,有成員變量method日丹,methodString,eventType蚯嫌,threadMode哲虾,這幾個(gè)變量就可以確認(rèn)具體是哪個(gè)訂閱方法
        List<SubscriberMethod> subscriberMethods = this.subscriberMethodFinder.findSubscriberMethods(subscriber.getClass());
        Iterator i$ = subscriberMethods.iterator();
        while(i$.hasNext()) {
            SubscriberMethod subscriberMethod = (SubscriberMethod)i$.next();
            // subscribe 訂閱方法是核心 單獨(dú)拿出來分析一下也很簡(jiǎn)潔
            this.subscribe(subscriber, subscriberMethod, sticky, priority);
        }
    }

接著看下subscribe方法,去掉了粘性相關(guān)代碼

private void subscribe(Object subscriber, SubscriberMethod subscriberMethod, boolean sticky, int priority) {
        // 獲取方法的eventType
        Class<?> eventType = subscriberMethod.eventType;
       // Subscription是一個(gè)描述activity和對(duì)應(yīng)訂閱方法的類 择示,這里獲取所有訂閱了這個(gè)方法的Subscription對(duì)象
        CopyOnWriteArrayList<Subscription> subscriptions = (CopyOnWriteArrayList)this.subscriptionsByEventType.get(eventType);
        // 創(chuàng)建了一個(gè)本次Activity對(duì)應(yīng)的Subscription對(duì)象
        Subscription newSubscription = new Subscription(subscriber, subscriberMethod, priority);
        // 檢測(cè)是否已經(jīng)有不同的的activity訂閱過這方法束凑,沒有就新建,相同activity訂閱就拋異常栅盲。
        if (subscriptions == null) {
            subscriptions = new CopyOnWriteArrayList();
            this.subscriptionsByEventType.put(eventType, subscriptions);
        } else if (subscriptions.contains(newSubscription)) {
            throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event " + eventType);
        }

        int size = subscriptions.size();
        // 按照優(yōu)先級(jí)插入對(duì)應(yīng)的位置(包含該訂閱方法的集合)
        for(int i = 0; i <= size; ++i) {
            if (i == size || newSubscription.priority > ((Subscription)subscriptions.get(i)).priority) {
                subscriptions.add(i, newSubscription);
                break;
            }
        }
        // typesBySubscriber是一個(gè)activity包含所有訂閱方法的集合
        List<Class<?>> subscribedEvents = (List)this.typesBySubscriber.get(subscriber);
        if (subscribedEvents == null) {
            subscribedEvents = new ArrayList();
            this.typesBySubscriber.put(subscriber, subscribedEvents);
        }
        ((List)subscribedEvents).add(eventType);
    }

這里可以看到有兩個(gè)集合 一個(gè)是包含相同事件的對(duì)象集合 一個(gè)是某個(gè)activity包含所有訂閱方法的集合汪诉。說到底, 注冊(cè)過程就是往集合里添加數(shù)據(jù)的一個(gè)過程,可以猜想post發(fā)送事件谈秫,是一個(gè)從集合里獲取對(duì)象執(zhí)行的一個(gè)過程扒寄,取消注冊(cè),就是一個(gè)從集合remove事件的過程孝常。
EventBus可以從下面幾點(diǎn)開講:
1.觀察者模式
2.線程切換
3.事件優(yōu)先級(jí)
4.APT技術(shù)(之前的版本用的是反射獲取信息)

2. Glide圖片緩存

從下面幾點(diǎn)分散開講:
1.圖片緩存 - 內(nèi)存緩存,硬盤緩存
2.線程切換 - 請(qǐng)求圖片的時(shí)候放在子線程蚓哩,設(shè)置Imageview的時(shí)候轉(zhuǎn)換到主線程
3.OOM問題 - 弱引用构灸,LRuCache
4.內(nèi)存泄漏

3.OkHttp

里面幾個(gè)重要的組成部分:

1.RealCall:

2.Dispatcher:

3.OkHttpClient:

4.Interceptor:

攔截器設(shè)計(jì),是OkHttp最重要的設(shè)計(jì)

Android高頻問題

1.消息機(jī)制

通常消息機(jī)制的幾個(gè)大佬:Handler岸梨,Looper,MessageQueue 喜颁,Message
分析代碼看的不是很清楚,借用下大佬畫的圖還有我自己的圖

消息機(jī)制

消息機(jī)制

這邊一般會(huì)展開講為什么Loop()無限循環(huán)不會(huì)造成卡頓曹阔,首先一個(gè)點(diǎn)app不退出的條件就是依賴于這個(gè)Loop循環(huán)半开,退出循環(huán)意味著app就停止工作了,那為什么不會(huì)造成卡頓呢赃份?線程在沒有事件的時(shí)候是會(huì)進(jìn)入阻塞狀態(tài)寂拆。

2.相關(guān)優(yōu)化

內(nèi)存優(yōu)化:內(nèi)存泄漏,大圖優(yōu)化
UI優(yōu)化:過渡渲染抓韩,View Inspecter查看層級(jí)
網(wǎng)絡(luò)優(yōu)化: 減少請(qǐng)求次數(shù)纠永,圖片按需請(qǐng)求,數(shù)據(jù)緩存谒拴,弱網(wǎng)情況下不加載圖片等尝江。
ANR:耗時(shí)方法分析Systrace

3.自定義View

對(duì)于自定義View需要知道的基礎(chǔ)大概有這么幾點(diǎn):
1.了解一個(gè)View的MeasureSpec怎么來的,通常是這么一張圖


父View對(duì)子View的MeasureSpec影響

2.了解measure layout draw三個(gè)過程的作用
measure過程主要是測(cè)量控件的大小英上,單個(gè)View或者ViewGroup都需要自己去實(shí)現(xiàn)onMeasure方法實(shí)現(xiàn)自己的大小炭序。
layout過程啤覆,主要是用于ViewGroup布局子View,單個(gè)View不需要重寫惭聂。
draw過程:主要是用于單個(gè)View繪制內(nèi)容窗声。

4.React Native的原理(Android角度)

從兩個(gè)角度分析:UI繪制
UI繪制:
Android的頁面就是一個(gè)Activity與主體視圖c

protected void loadApp(String appKey) {
    if (mReactRootView != null) {
      throw new IllegalStateException("Cannot loadApp while app is already running.");
    }
    mReactRootView = createRootView();
    mReactRootView.startReactApplication(
      getReactNativeHost().getReactInstanceManager(),
      appKey,
      getLaunchOptions());
    getPlainActivity().setContentView(mReactRootView);
  }

看下mReactRootView是怎么實(shí)現(xiàn)的?
mReactRootView整個(gè)看下來就是一個(gè)繼承SizeMonitoringFrameLayout的普通View彼妻,布局子View交給了 UIManagerModule

 @Override
  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    // No-op since UIManagerModule handles actually laying out children.
  }

UIManagerModule里面很多注冊(cè)的交互事件比如更新View


  @ReactMethod
  public void updateView(int tag, String className, ReadableMap props) {
    if (DEBUG) {
      String message =
          "(UIManager.updateView) tag: " + tag + ", class: " + className + ", props: " + props;
      FLog.d(ReactConstants.TAG, message);
      PrinterHolder.getPrinter().logMessage(ReactDebugOverlayTags.UI_MANAGER, message);
    }
    mUIImplementation.updateView(tag, className, props);
  }

Js會(huì)把一些操作通過JsBridge(C++實(shí)現(xiàn))傳遞給UIManagerModule進(jìn)行操作嫌佑。
1.js調(diào)用java代碼是從NativeModules.xxxModule.xxxMethod()

2.JSCExecutor::getNativeModule>()獲取js所要調(diào)用的java層的方法的配置表

3.NativeModules.js根據(jù)得到的配置表調(diào)用BatchedBridge.enqueueNativeCall(),將module:moduleID, methodID, params等參數(shù)傳遞到c層

4.c層遍歷獲取對(duì)應(yīng)moduleId的javamoudlewrapper侨歉,通過反射調(diào)用ReactContextBaseJavaModule中的代碼

參考:https://blog.csdn.net/kakaxiqianxin/article/details/80666443

5.觸摸事件分發(fā)

主要角色:ViewGroup`` View
他們分別都有dispatchTouchEvent事件的實(shí)現(xiàn)屋摇,
ViewGroup主要做了幾件事:
1.判斷是否攔截
2.沒有攔截則在子View中查看響應(yīng)子View
3.有的話執(zhí)行子View的dispatchTouchEvent,mFirstTarget不為空,
View主要做的是響應(yīng)事件的事:
OnTouch先于onTouchEvent執(zhí)行,onTouchEvent中執(zhí)行onClick方法
子View可點(diǎn)擊幽邓,必會(huì)返回true炮温。
面試考察點(diǎn):不同的觸摸情況,對(duì)應(yīng)什么樣的事件牵舵。eg:子View響應(yīng) DOWN事件柒啤,但是父View攔截了MOVE事件,這個(gè)時(shí)候畸颅,還是會(huì)有事件傳遞到子View担巩,但是是CANCEL事件。

6.UI卡頓相關(guān):

卡頓原因
1.應(yīng)用會(huì)在要繪制的時(shí)候會(huì)請(qǐng)求vsync信號(hào)没炒,收到的時(shí)候會(huì)往消息隊(duì)列插入一條消息涛癌,此時(shí)主線程前一條消息要是耗時(shí)久的話會(huì)造成doframe無法在16ms內(nèi)被執(zhí)行。

doframe 繪制超復(fù)雜UI送火,消耗超過16ms拳话。

7. 啟動(dòng)加速:

1.可以影響的有Application的onCreate方法,一般會(huì)把不重要的操作放到子線程中初始化种吸。
2.還有一個(gè)障眼法弃衍,就是給啟動(dòng)頁面換一個(gè)背景,造成瞬間響應(yīng)點(diǎn)擊圖標(biāo)啟動(dòng)的操作

8.Activity和Window,DecorView的關(guān)系

想要記住很容易坚俗,可以從Activity的setContentView入手

public void setContentView(@LayoutRes int layoutResID) {
        // 這個(gè)是PhoneWindow
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
    }

PhoneWindow----getWindow().setContentView(layoutResID);

@Override
    public void setContentView(int layoutResID) {
        // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
        // decor, when theme attributes and the like are crystalized. Do not check the feature
        // before this happens.
        if (mContentParent == null) {
            // 首次肯定先執(zhí)行這 看下DecorView
            installDecor();
        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            mContentParent.removeAllViews();
        }

        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
                    getContext());
            transitionTo(newScene);
        } else {
            
            mLayoutInflater.inflate(layoutResID, mContentParent);
        }
        mContentParent.requestApplyInsets();
        final Callback cb = getCallback();
        if (cb != null && !isDestroyed()) {
            cb.onContentChanged();
        }
        mContentParentExplicitlySet = true;
    }

installDecor就是創(chuàng)建DecorView的代碼镜盯,前面可以看出來Activity包含PhoneWindow

if (mDecor == null) {
            mDecor = generateDecor(-1);
            mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
            mDecor.setIsRootNamespace(true);
            if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
                mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
            }
        } else {
            mDecor.setWindow(this);
        }

總結(jié):
Activity包含了一個(gè)PhoneWindow,PhoneWindow就是繼承于Window
Activity通過setContentView將View設(shè)置到了DecorView上
PhoneWindow里面包含了DecorView猖败,最終布局被添加到Decorview上.

9. ViewRootImpl,WindowManager,WindowManagerService(WMS)形耗,SurfaceFlinger之間的關(guān)系

想要說明這三個(gè)的關(guān)系需要先明白這三個(gè)分別有什么作用:

ViewRootImpl:里面有兩個(gè)個(gè)重要的類

1.W:負(fù)責(zé)和WindowManagerService交互,接受觸摸事件(這里服務(wù)端通過Socket傳遞給客戶端)等辙浑。
2.ViewRootHandler:接受W的異步消息激涤。
除此之外也負(fù)責(zé)和服務(wù)端交互,負(fù)責(zé)更新View

WindowManager:

addView等API與服務(wù)端交流,感覺是個(gè)為了解耦而出現(xiàn)的類倦踢,具體的邏輯都是通過其他類完成與Service的交互送滞。

WindowManagerService:

服務(wù)端負(fù)責(zé)Window的管理,不負(fù)責(zé)View繪制
他們之間的關(guān)系可以從一下這段代碼開始分析

SurfaceFlinger:

服務(wù)端負(fù)責(zé)圖層的管理
他們之間的關(guān)系可以從一下這段代碼開始分析

 (WindowManager)wm.addView(mDecor, getWindow().getAttributes());

看下addView

final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
        root = new ViewRootImpl(view.getContext(), display);
        view.setLayoutParams(wparams);
        mViews.add(view);
        mRoots.add(root);
        mParams.add(wparams);
    }
    try {
        root.setView(view, wparams, panelParentView);
    }           


public ViewRootImpl(Context context, Display display) {
    mContext = context;
    // 首先通過getWindowManagerService 獲取WMS的代理辱挥,之后通過WMS的代理在服務(wù)端open一個(gè)Session犁嗅,并在APP端獲取該Session的代理
    mWindowSession = WindowManagerGlobal.getWindowSession();
    mWindow = new W(this);
}

很明顯在addView的時(shí)候創(chuàng)建了ViewRootImpl,看下ViewRootImpl如何通過setView將視圖添加到WMS的:

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
        synchronized (this) {
            if (mView == null) {
                mView = view;
                // requestLayout是在addWindow之后執(zhí)行的
                requestLayout();
                if ((mWindowAttributes.inputFeatures
                        & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
                    mInputChannel = new InputChannel();
                }
                try {
                    // IPC操作 通過Session add一個(gè)View
                    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(),
                            mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                            mAttachInfo.mOutsets, mInputChannel);
                } catch (RemoteException e) {
}
}

看下如何addView的
代碼在以下路徑 代碼很長(zhǎng)精簡(jiǎn)一些 /frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

....
// win是WIndowState 這一步會(huì)向SuraceFlinger申請(qǐng)Suface
win.attach();
....

主要是對(duì)窗口分組晤碘,判斷是否添加過窗口等操作褂微。
之后WMS會(huì)向SurfaceFlinger申請(qǐng)Suface,這一步也是一個(gè)IPC的過程

總的流程:
首先APP端新建一個(gè)Surface圖層的容器殼子园爷,
APP通過Binder通信將這個(gè)Surface的殼子傳遞給WMS宠蚂,
WMS為了填充Surface去向SurfaceFlinger申請(qǐng)真正的圖層,
SurfaceFlinger收到WMS請(qǐng)求為APP端的Surface分配真正圖層
將圖層相關(guān)的關(guān)鍵信息Handle及Producer傳遞給WMS
之后更新UI就可以通過代理和SurfaceFlinger進(jìn)行通信了


image.png

參考:http://www.reibang.com/p/40776c123adb

10.一個(gè)App的啟動(dòng)流程:

從點(diǎn)擊App的圖標(biāo)開始
1.點(diǎn)擊App圖標(biāo) Launcher進(jìn)程發(fā)送startActivity IPC請(qǐng)求到AMS
2.AMS startProcessLocked 會(huì)去請(qǐng)求Zygote進(jìn)程(socket方式)去創(chuàng)建進(jìn)程
3.Zygote進(jìn)程fork一個(gè)新的進(jìn)程
4.被創(chuàng)建的app會(huì)執(zhí)行ActivityThread的main方法

 public static void main(String[] args) {
       // 展示主體代碼
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);
        Looper.loop();
    }

Looper這個(gè)看著是不是很熟悉童社,這個(gè)就是UI線程Looper求厕,所以在UI線程不需要Looper.loop()
thread.attach這個(gè)方法進(jìn)行了IPC

 RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                // 這里把ApplicationThread這個(gè)Binder傳遞給遠(yuǎn)程服務(wù),這個(gè)時(shí)候相當(dāng)于本身app變成遠(yuǎn)程服務(wù)端扰楼,Service變成發(fā)起者呀癣。常規(guī)Binder需要向ServiceManager獲取遠(yuǎn)程Service的代理。
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }

5.Service會(huì)往App發(fā)送BIND_APPLICATION弦赖,創(chuàng)建Application
6.接著會(huì)往App發(fā)送LAUNCH_ACTIVITY项栏,反射創(chuàng)建Activity

Java基礎(chǔ)篇:

1.線程篇:

線程并發(fā)基礎(chǔ)知識(shí)
三個(gè)特性:
原子性:由于操作不是一步完成:打個(gè)比方加法的CPU指令,現(xiàn)在寄存器中計(jì)算結(jié)果蹬竖,這個(gè)可以被中斷沼沈,原子性意味著加法操作是整個(gè)完成或者就沒執(zhí)行。
有序性:代碼的順序和虛擬機(jī)執(zhí)行順序不一定一樣
可見性:Java的內(nèi)存模型決定案腺,變量都存儲(chǔ)在主內(nèi)存庆冕,線程中存儲(chǔ)的是一份copy康吵。
如何保證這三個(gè)特性劈榨?:
volatile可以保證可見性(lock指令 cpu執(zhí)行到時(shí)馬上刷新數(shù)據(jù)到主內(nèi)存,并馬上通知其他線程數(shù)據(jù)地址失效)晦嵌,也可以防止指令重排序同辣,不能保證原子性,通過內(nèi)存屏障防止指令排序惭载。
Synchronized:悲觀鎖旱函,可以保證同一時(shí)間只有一個(gè)線程可以訪問代碼段,實(shí)現(xiàn)原理: monitorenter 和 monitorexit
執(zhí)行同步代碼塊描滔,首先會(huì)執(zhí)行monitorenter指令棒妨,然后執(zhí)行同步代碼塊中的代碼,退出同步代碼塊的時(shí)候會(huì)執(zhí)行monitorexit指令 含长。
CAS:樂觀鎖券腔,compare and set伏穆,變量volatile保證可見性,unsafe操作保證原子性纷纫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末枕扫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子辱魁,更是在濱河造成了極大的恐慌烟瞧,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件染簇,死亡現(xiàn)場(chǎng)離奇詭異参滴,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)剖笙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門卵洗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人弥咪,你說我怎么就攤上這事过蹂。” “怎么了聚至?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵酷勺,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我扳躬,道長(zhǎng)脆诉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任贷币,我火速辦了婚禮击胜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘役纹。我一直安慰自己偶摔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布促脉。 她就那樣靜靜地躺著辰斋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瘸味。 梳的紋絲不亂的頭發(fā)上宫仗,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音旁仿,去河邊找鬼藕夫。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的毅贮。 我是一名探鬼主播梭姓,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼嫩码!你這毒婦竟也來了誉尖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤铸题,失蹤者是張志新(化名)和其女友劉穎铡恕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丢间,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡探熔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了烘挫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诀艰。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖饮六,靈堂內(nèi)的尸體忽然破棺而出其垄,到底是詐尸還是另有隱情,我是刑警寧澤卤橄,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布绿满,位于F島的核電站,受9級(jí)特大地震影響窟扑,放射性物質(zhì)發(fā)生泄漏喇颁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一嚎货、第九天 我趴在偏房一處隱蔽的房頂上張望橘霎。 院中可真熱鬧,春花似錦殖属、人聲如沸姐叁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽七蜘。三九已至谭溉,卻和暖如春墙懂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背扮念。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工损搬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓巧勤,卻偏偏與公主長(zhǎng)得像嵌灰,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子颅悉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359