[Dev Tip] Web Api Generic MediaTypeFormatter for File Upload

I’m currently working on a personal project which uses Asp.net WebApi and .net 4.5. I have found several nice examples utilizing the Multipartformdatastreamprovider. I discovered quickly though that using this in a controller was going to multiply boilerplate code. It would be much more efficient to use a custom MediaTypeFormatter to handle the form data and pass me back the information I need in a memorystream which can be directly saved.

Jflood.net Original Code

Jflood.net provides a nice starting point to what I needed to do. However, I had a few more requirements of mine which included a JSON payload in the datafield. I also extended his ImageMedia class into a generic FileUpload class and exposed a few simple methods.

1
2
3
4
5
6
7
8
 public HttpResponseMessage Post(FileUpload<font> upload)
        {
            var FilePath = "Path";
            upload.Save(FilePath); //save the buffer
            upload.Value.Insert(); //save font object to DB
 
            return Request.CreateResponse(HttpStatusCode.OK, upload.Value);
        }

This is the file upload class. Like Jflood’s it includes a payload for the file to be stored and written in memory. I have added a simple save method which performs a few checks and saves to disk. I also have some project specific code that checks if the T type has a property named filename, if so it passes the name to it. Since my Value field is of Type T it is automatically deserialized by Json.net.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
    public class FileUpload<T>
    {
        private readonly string _RawValue;
 
        public T Value { get; set; }
        public string FileName { get; set; }
        public string MediaType { get; set; }
        public byte[] Buffer { get; set; }
 
        public FileUpload(byte[] buffer, string mediaType, string fileName, string value)
        {
            Buffer = buffer;
            MediaType = mediaType;
            FileName = fileName.Replace("\"","");
            _RawValue = value;
 
            Value = JsonConvert.DeserializeObject<T>(_RawValue);
        }
 
        public void Save(string path)
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            var NewPath = Path.Combine(path, FileName);
            if (File.Exists(NewPath))
            {
                File.Delete(NewPath);
            }
 
            File.WriteAllBytes(NewPath, Buffer);
 
            var Property = Value.GetType().GetProperty("FileName");
            Property.SetValue(Value,FileName, null);
        }
    }

This is essentially the same thing as jflood is doing, however, I have added a section to parse out my “data” field that contains json.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
    public class FileMediaFormatter<T> : MediaTypeFormatter
    {
 
        public FileMediaFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data"));
        }
 
        public override bool CanReadType(Type type)
        {
            return type == typeof(FileUpload<T>);
        }
 
        public override bool CanWriteType(Type type)
        {
            return false;
        }
 
        public async override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
 
            if (!content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }
 
            var Parts = await content.ReadAsMultipartAsync();
            var FileContent = Parts.Contents.First(x =>
                SupportedMediaTypes.Contains(x.Headers.ContentType));
 
            var DataString = "";
            foreach (var Part in Parts.Contents.Where(x => x.Headers.ContentDisposition.DispositionType == "form-data" 
                                                        && x.Headers.ContentDisposition.Name == "\"data\""))
            {
                var Data = await Part.ReadAsStringAsync();
                DataString = Data;
            }
 
            string FileName = FileContent.Headers.ContentDisposition.FileName;
            string MediaType = FileContent.Headers.ContentType.MediaType;
 
            using (var Imgstream = await FileContent.ReadAsStreamAsync())
            {
                byte[] Imagebuffer = ReadFully(Imgstream);
                return new FileUpload<T>(Imagebuffer, MediaType,FileName ,DataString);
            }
        }
 
        private byte[] ReadFully(Stream input)
        {
            var Buffer = new byte[16 * 1024];
            using (var Ms = new MemoryStream())
            {
                int Read;
                while ((Read = input.Read(Buffer, 0, Buffer.Length)) > 0)
                {
                    Ms.Write(Buffer, 0, Read);
                }
                return Ms.ToArray();
            }
        }
 
 
    }

Finally in your application_start you must include this line below.

1
GlobalConfiguration.Configuration.Formatters.Add(new FileMediaFormatter<font>());

Now it is really simple to accept uploads from other controllers. Be sure to tweak the MIME type for your own needs. Right now this only accepts application/octet-stream but it can easily accept other formats by adding other MIME types.

Update – How to add model validation support.

Quick update for the fileupload class. I’ve seen a few posts on stackoverflow about how to not only deserialize your object using a method such as mine, but also maintain the data annotation validation rules. That turns out to be pretty easy to do. Basically combine reflection and TryValidateProperty() and you can validate properties on demand. In my example it shows how you can get the validation messages. It simply puts them into an array. Here is sample below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class FileUpload<T>
    {
        private readonly string _RawValue;
 
        public T Value { get; set; }
        public string FileName { get; set; }
        public string MediaType { get; set; }
        public byte[] Buffer { get; set; }
 
        public List<ValidationResult> ValidationResults = new List<ValidationResult>(); 
 
        public FileUpload(byte[] buffer, string mediaType, string fileName, string value)
        {
            Buffer = buffer;
            MediaType = mediaType;
            FileName = fileName.Replace("\"","");
            _RawValue = value;
 
            Value = JsonConvert.DeserializeObject<T>(_RawValue);
 
            foreach (PropertyInfo Property in Value.GetType().GetProperties())
            {
                var Results = new List<ValidationResult>();
                Validator.TryValidateProperty(Property.GetValue(Value),
                                              new ValidationContext(Value) {MemberName = Property.Name}, Results);
                ValidationResults.AddRange(Results);
            }
        }
 
        public void Save(string path, int userId)
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            var SafeFileName = Md5Hash.GetSaltedFileName(userId,FileName);
            var NewPath = Path.Combine(path, SafeFileName);
            if (File.Exists(NewPath))
            {
                File.Delete(NewPath);
            }
 
            File.WriteAllBytes(NewPath, Buffer);
 
            var Property = Value.GetType().GetProperty("FileName");
            Property.SetValue(Value, SafeFileName, null);
        }
    }

Ref: http://lonetechie.com/2012/09/23/web-api-generic-mediatypeformatter-for-file-upload/#comments

[Dev Tip] Passing multiple POST parameters to Web API Controller Methods

ASP.NET Web API introduces a new API for creating REST APIs and making AJAX callbacks to the server. This new API provides a host of new great functionality that unifies many of the features of many of the various AJAX/REST APIs that Microsoft created before it – ASP.NET AJAX, WCF REST specifically – and combines them into a whole more consistent API. Web API addresses many of the concerns that developers had with these older APIs, namely that it was very difficult to build consistent REST style resource APIs easily.

While Web API provides many new features and makes many scenarios much easier, a lot of the focus has been on making it easier to build REST compliant APIs that are focused on resource based solutions and HTTP verbs. But  RPC style calls that are common with AJAX callbacks in Web applications, have gotten a lot less focus and there are a few scenarios that are not that obvious, especially if you’re expecting Web API to provide functionality similar to ASP.NET AJAX style AJAX callbacks.

RPC vs. ‘Proper’ REST

RPC style HTTP calls mimic calling a method with parameters and returning a result. Rather than mapping explicit server side resources or ‘nouns’ RPC calls tend simply map a server side operation, passing in parameters and receiving a typed result where parameters and result values are marshaled over HTTP. Typically RPC calls – like SOAP calls – tend to always be POST operations rather than following HTTP conventions and using the GET/POST/PUT/DELETE etc. verbs to implicitly determine what operation needs to be fired.

RPC might not be considered ‘cool’ anymore, but for typical private AJAX backend operations of a Web site I’d wager that a large percentage of use cases of Web API will fall towards RPC style calls rather than ‘proper’ REST style APIs. Web applications that have needs for things like live validation against data, filling data based on user inputs, handling small UI updates often don’t lend themselves very well to limited HTTP verb usage. It might not be what the cool kids do, but I don’t see RPC calls getting replaced by proper REST APIs any time soon.  Proper REST has its place – for ‘real’ API scenarios that manage and publish/share resources, but for more transactional operations RPC seems a better choice and much easier to implement than trying to shoehorn a boatload of endpoint methods into a few HTTP verbs.

In any case Web API does a good job of providing both RPC abstraction as well as the HTTP Verb/REST abstraction. RPC works well out of the box, but there are some differences especially if you’re coming from ASP.NET AJAX service or WCF Rest when it comes to multiple parameters.

Action Routing for RPC Style Calls

If you’ve looked at Web API demos you’ve probably seen a bunch of examples of how to create HTTP Verb based routing endpoints. Verb based routing essentially maps a controller and then uses HTTP verbs to map the methods that are called in response to HTTP requests. This works great for resource APIs but doesn’t work so well when you have many operational methods in a single controller. HTTP Verb routing is limited to the few HTTP verbs available (plus separate method signatures) and – worse than that – you can’t easily extend the controller with custom routes or action routing beyond that.

Thankfully Web API also supports Action based routing which allows you create RPC style endpoints fairly easily:

RouteTable.Routes.MapHttpRoute(
    name: "AlbumRpcApiAction",
    routeTemplate: "albums/{action}/{title}",
    defaults: new
    {
        title = RouteParameter.Optional,
        controller = "AlbumApi",
        action = "GetAblums"
    }
);

This uses traditional MVC style {action} method routing which is different from the HTTP verb based routing you might have read a bunch about in conjunction with Web API. Action based routing like above lets you specify an end point method in a Web API controller either via the {action} parameter in the route string or via a default value for custom routes.

Using routing you can pass multiple parameters either on the route itself or pass parameters on the query string, via ModelBinding or content value binding. For most common scenarios this actually works very well. As long as you are passing either a single complex type via a POST operation, or multiple simple types via query string or POST buffer, there’s no issue. But if you need to pass multiple parameters as was easily done with WCF REST or ASP.NET AJAX things are not so obvious.

Web API has no issue allowing for single parameter like this:

[HttpPost]
public string PostAlbum(Album album)
{
    return String.Format("{0} {1:d}", album.AlbumName, album.Entered);
}

There are actually two ways to call this endpoint:

albums/PostAlbum

Using the Model Binder with plain POST values

In this mechanism you’re sending plain urlencoded POST values to the server which the ModelBinder then maps the parameter. Each property value is matched to each matching POST value. This works similar to the way that MVC’s  ModelBinder works. Here’s how you can POST using the ModelBinder and jQuery:

$.ajax(
{
    url: "albums/PostAlbum",
    type: "POST",
    data: { AlbumName: "Dirty Deeds", Entered: "5/1/2012" },
    success: function (result) {
        alert(result);
    },
    error: function (xhr, status, p3, p4) {
        var err = "Error " + " " + status + " " + p3;
        if (xhr.responseText && xhr.responseText[0] == "{")
            err = JSON.parse(xhr.responseText).message;
        alert(err);
    }
});

Here’s what the POST data looks like for this request:

FireBug

The model binder and it’s straight form based POST mechanism is great for posting data directly from HTML pages to model objects. It avoids having to do manual conversions for many operations and is a great boon for AJAX callback requests.

Using Web API JSON Formatter

The other option is to post data using a JSON string. The process for this is similar except that you create a JavaScript object and serialize it to JSON first.

album = {
    AlbumName: "PowerAge",
    Entered: new Date(1977,0,1)
}
$.ajax(
{
    url: "albums/PostAlbum",
    type: "POST",
    contentType: "application/json",
    data: JSON.stringify(album),
    success: function (result) {
        alert(result);
    }
});

Here the data is sent using a JSON object rather than form data and the data is JSON encoded over the wire.

JsonPost

The trace reveals that the data is sent using plain JSON (Source above), which is a little more efficient since there’s no UrlEncoding that occurs.

BTW, notice that WebAPI automatically deals with the date. I provided the date as a plain string, rather than a JavaScript date value and the Formatter and ModelBinder both automatically map the date propertly to the Entered DateTime property of the Album object.

Passing multiple Parameters to a Web API Controller

Single parameters work fine in either of these RPC scenarios and that’s to be expected. ModelBinding always works against a single object because it maps a model. But what happens when you want to pass multiple parameters?

Consider an API Controller method that has a signature like the following:

[HttpPost]
public string PostAlbum(Album album, string userToken)

Here I’m asking to pass two objects to an RPC method. Is that possible? This used to be fairly straight forward either with WCF REST and ASP.NET AJAX ASMX services, but as far as I can tell this is not directly possible using a POST operation with WebAPI.

There a few workarounds that you can use to make this work:

Use both POST *and* QueryString Parameters in Conjunction

If you have both complex and simple parameters, you can pass simple parameters on the query string. The above would actually work with:

/album/PostAlbum?userToken=sekkritt

but that’s not always possible. In this example it might not be a good idea to pass a user token on the query string though. It also won’t work if you need to pass multiple complex objects, since query string values do not support complex type mapping. They only work with simple types.

Use a single Object that wraps the two Parameters

If you go by service based architecture guidelines every service method should always pass and return a single value only. The input should wrap potentially multiple input parameters and the output should convey status as well as provide the result value. You typically have a xxxRequest and a xxxResponse class that wraps the inputs and outputs.

Here’s what this method might look like:

public PostAlbumResponse PostAlbum(PostAlbumRequest request)
{
    var album = request.Album;
    var userToken = request.UserToken;

    return new PostAlbumResponse()
    {
         IsSuccess = true,
         Result = String.Format("{0} {1:d} {2}", album.AlbumName, album.Entered,userToken)
    };
}

with these support types:

public class PostAlbumRequest
{
    public Album Album { get; set; }
    public User User { get; set; }
    public string UserToken { get; set; }
}

public class PostAlbumResponse
{
    public string Result { get; set; }
    public bool IsSuccess { get; set; }
    public string ErrorMessage { get; set; }
}

To call this method you now have to assemble these objects on the client and send it up as JSON:

var album = {
    AlbumName: "PowerAge",
    Entered: "1/1/1977"
}
var user = {
    Name: "Rick"
}
var userToken = "sekkritt";


$.ajax(
{
    url: "samples/PostAlbum",
    type: "POST",
    contentType: "application/json",
    data: JSON.stringify({ Album: album, User: user, UserToken: userToken }),
    success: function (result) {
        alert(result.Result);
    }
});

I assemble the individual types first and then combine them in the data: property of the $.ajax() call into the actual object passed to the server, that mimics the structure of PostAlbumRequest server class that has Album, User and UserToken properties.

This works well enough but it gets tedious if you have to create Request and Response types for each method signature. If you have common parameters that are always passed (like you always pass an album or usertoken) you might be able to abstract this to use a single object that gets reused for all methods, but this gets confusing too: Overload a single ‘parameter’ too much and it becomes a nightmare to decipher what your method actual can use.

Use JObject to parse multiple Property Values out of an Object

If you recall, ASP.NET AJAX and WCF REST used a ‘wrapper’ object to make default AJAX calls. Rather than directly calling a service you always passed an object which contained properties for each parameter:

{ parm1: Value, parm2: Value2 }

WCF REST/ASP.NET AJAX would then parse this top level property values and map them to the parameters of the endpoint method.

This automatic type wrapping functionality is no longer available directly in Web API, but since Web API now uses JSON.NET for it’s JSON serializer you can actually simulate that behavior with a little extra code. You can use the JObject class to receive a dynamic JSON result and then using the dynamic cast of JObject to walk through the child objects and even parse them into strongly typed objects.

Here’s how to do this on the API Controller end:

[HttpPost]
public string PostAlbum(JObject jsonData)
{
    dynamic json = jsonData;
    JObject jalbum = json.Album;
    JObject juser = json.User;
    string token = json.UserToken;

    var album = jalbum.ToObject<Album>();
    var user = juser.ToObject<User>();

    return String.Format("{0} {1} {2}", album.AlbumName, user.Name, token);
}

This is clearly not as nice as having the parameters passed directly, but it works to allow you to pass multiple parameters and access them using Web API.

JObject is JSON.NET’s generic object container which sports a nice dynamic interface that allows you to walk through the object’s properties using standard ‘dot’ object syntax. All you have to do is cast the object todynamic to get access to the property interface of the JSON type.

Additionally JObject also allows you to parse JObject instances into strongly typed objects, which enables us here to retrieve the two objects passed as parameters from this jquery code:

var album = {
    AlbumName: "PowerAge",
    Entered: "1/1/1977"
}
var user = {
    Name: "Rick"
}
var userToken = "sekkritt";


$.ajax(
{
    url: "samples/PostAlbum",
    type: "POST",
    contentType: "application/json",
    data: JSON.stringify({ Album: album, User: user, UserToken: userToken }),
     success: function (result) {
        alert(result);
    }
});

Summary

ASP.NET Web API brings many new features and many advantages over the older Microsoft AJAX and REST APIs, but realize that some things like passing multiple strongly typed object parameters will work a bit differently. It’s not insurmountable, but just knowing what options are available to simulate this behavior is good to know.

Now let me say here that it’s probably not a good practice to pass a bunch of parameters to an API call. Ideally APIs should be closely factored to accept single parameters or a single content parameter at least along with some identifier parameters that can be passed on the querystring. But saying that doesn’t mean that occasionally you don’t run into a situation where you have the need to pass several objects to the server and all three of the options I mentioned might have merit in different situations.

For now I’m sure the question of how to pass multiple parameters will come up quite a bit from people migrating WCF REST or ASP.NET AJAX code to Web API. At least there are options available to make it work.

Ref: http://weblog.west-wind.com/posts/2012/May/08/Passing-multiple-POST-parameters-to-Web-API-Controller-Methods

[Discovery] Những thông số cơ bản của Amply

Amply là một thiết bị âm thanh phổ biến mà chúng ta có thể bắt gặp ở nhiều nơi. Với một người chơi âm thanh, bất kể là loa hay là tai nghe thì amply vô cùng quan trọng trong việc phối ghép một hệ thống nghe. Khi lựa chọn một chiếc Amply cho loa hay là một chiếc mini Amply cho headphones thì việc đọc thông số để lựa chọn cho phù hợp là rất quan trọng, và hơn thế nữa, hiểu và nắm rõ bản chất của các thông số là điều cần thiết mà một người chơi âm thanh phải có. Bài viết này sẽ giúp các bạn hiểu rõ hơn về ý nghĩa của những thông số trên một chiếc Amply.

Những thông số cơ bản của Amply

CÔNG SUẤT

CÔNG SUẤT AMPLI PHÁT RA TÍNH THEO ĐƠN VỊ RMS. CẦN PHÂN BIỆT VỚI CÔNG SUẤT ĐỈNH PMPO LỚN HƠN RẤT NHIỀU VỚI CÔNG SUẤT HOẠT ĐỘNG CỦA AMPLI (MỘT SỐ NHÀ SẢN XUẤT QUẢNG CÁO CÔNG SUẤT PMPO RẤT LỚN LÊN TỚI HÀNG NGHÌN W NHƯNG THỰC TẾ CÔNG SUẤT HIỆU DỤNG LẠI RẤT THẤP).

RMS là thuật ngữ viết tắt của Root Mean Square, tức ‘trung bình nhân’. Đây là một thông số tính toán mức công suất trung bình tạo ra liên tục trong một khoản thời gian. Đánh giá công suất ampli mạnh hay yếu không phải đo tại một thời điểm nhất thời và phải tính trung bình từ nhiều mẫu khác nhau trong một chuỗi thời gian. Chung quy lại, đây là một thông số quan trọng cần phải lưu ý khi chọn Amply, còn P.M.P.O (Peak Music Power Output , công suất cực đại) không phải là yếu tố khẳng định độ mạnh – yếu của một chiếc Amply.

ĐỘ LỢI CÔNG SUẤT (GAIN).

Tỷ số tính theo hàm logarit giữa công suất đầu vào và công suất đầu ra của ampli, có đơn vị là dB. Độ lợi thể hiện khả năng khuyếch đại của ampli.

Những thông số cơ bản của Amply

Amly đèn dùng cho loa

ĐÁP ỨNG TẦN SỐ (FREQUENCY RESPONSE).

Đây là thông số mô tả khoảng tần số tín hiệu đầu vào mà ampli hoạt động ổn định tuyến tính. Thông thường các ampli tốt có đáp ứng tần số trong từ 20Hz đến 20kHz là khoảng âm thanh tai người có thể cảm nhận được. Đáp ứng tần số càng “phẳng” sẽ thể hiện khả năng tái tạo âm thanh càng tốt.

HIỆU SUẤT (EFFICIENCY)

Khả năng đưa ra công suất âm thanh theo công suất đầu vào của ampli. Khi cung cấp công suất điện cho ampli, chỉ một phần được khuyếch đại ra công suất âm thanh. Các ampli có thiết kế nguyên lý classA có hiệu suất thấp từ 10% đến 25% (điều đó có nghĩa khi bạn cung cấp 100W điện tới ampli chỉ có 25W công suất âm thanh được phát ra), class AB có hiệu suất 35 đến 50%, class D có hiệu suất 85-90%.

MÉO HÀI TỔNG (THD)

So sánh tổng hài các tần số giữa tín hiệu đầu vào và âm thanh đầu ra sau khi qua ampli. Các hài bậc cao sẽ gây méo và làm giảm tính trung thực của âm thanh vì vậy THD càng thấp thì ampli càng tái tạo âm thanh trung thực, thông thường THD phải nhỏ hơn 0,5%.

TRỞ KHÁNG RA (OUTPUT IMPEDANCE).

Trở kháng ra của ngõ ampli ra loa. Khi ghép nối ampli phải cùng trở kháng của loa, thông thường khi trở kháng loa giảm một nửa thì công suất ampli cần tăng gấp đôi nếu ghép nối lệch trở kháng.

Những thông số cơ bản của Amply

Một chiếc DIY Amply

PHÂN BIỆT OTL VÀ OPT

OTL là viết tắt của cụm từ tiếng Anh: Output Transformer Less (tạm dịch: không dùng biến thế xuất âm). Mạch OTL đầu tiên được cấp bằng sáng chế là do kỹ sư Julius Futterman người Mỹ phát minh năm 1954. Sau đó, mạch điện này đã có nhiều biến thể và một thời từng khá thịnh hành trong công nghiệp chế tạo các thiết bị dùng đèn điện tử. Cho đến khi bán dẫn ra đời, OTL gần như biến mất, không được ai sử dụng, do việc dùng nó “tốn” quá nhiều bóng và hiệu suất thấp.

Bóng đèn điện tử chân không là linh kiện có nội trở cao, hoạt động trong điều kiện điện áp cao và dòng điện thấp. Chính vì những đặc tính đó của đèn điện tử, để tăng dòng và phối hợp trở kháng với các thiết bị có trở kháng thấp và dòng điện cao như loa, người ta phải dùng biến thế hạ áp ở đầu ra, được gọi nôm na là biến thế xuất âm. Biến thế xuất âm (OPT) được các tín đồ âm thanh ưa chuộng vì nó tạo ra hài âm bậc chẵn vốn là loại âm thanh khá nhạy cảm với tai người, khuếch đại những những tiếng lóc cóc, leng keng và các chi tiết vi mô của bản nhạc.

Những thông số cơ bản của Amply

Amply đèn đang dần trở thành một phong trào trong giới chơi âm thanh

Song, ưu điểm đối với người này lại là nhược điểm đối với người khác. Những người theo trường phái trọng kỹ thuật không thích OPT vì nó sinh ra hiện tượng méo âm, làm hạn chế băng thông và dải động của âm thanh. Họ cho rằng OTL là một lựa chọn đúng hơn so với việc dùng OPT. Do không phải đi qua một linh kiện to lớn, cồng kềnh với các cuộn dây rất nhiều vòng ở đầu ra, mạch điện OTL có thể khắc phục một số nhược điểm của mạch điện dùng OPT, như tốc độ, cường độ, dải động của âm thanh. Đặc biệt, băng thông của OTL cực rộng, có thể lên tới hàng trăm KHz chứ không bị suy giảm ở khoảng tần số mười mấy KHz như đối với OPT. Chính vì thế, những năm gần đây, thiết kế OTL lại xuất hiện trở lại trong nhiều sản phẩm hi-end và được dân chơi âm thanh nồng nhiệt đón nhận.

[Discovery] Những sự thật thú vị về trí thông minh

Trò chơi trí tuệ không giúp con người thông minh hơn, các bài kiểm tra IQ không mang tính đánh giá tuyệt đối. Những kết luận này được tạp chí Medical đưa ra, có thể khiến bạn ngạc nhiên vì chúng khác với những gì ta từng biết.

Tác dụng của trò chơi trí tuệ

Tỷ lệ mắc bệnh Alzheimer và các hội chứng mất trí nhớ khác đang có xu hướng ngày càng gia tăng. Trước thực tế này, một số công ty như Lumosity đã giới thiệu mô hình trò chơi trí tuệ được cho là hữu ích với não bộ. Các trò chơi này khá đơn giản, thường liên quan đến ghi nhớ từ hoặc đưa đối tượng tượng hình vào đúng vị trí, từ đó tạo ảnh hưởng tích cực đến trí nhớ và sự tập trung.

Theo các chuyên gia, mặc dù giải pháp trên đúng về mặt lý thuyết, nhưng vẫn còn nhiều quan niệm sai lầm cho rằng trò chơi có thể cải thiện trí thông minh. Trò chơi trí tuệ được giới thiệu với cam kết giúp tăng cường khả năng ghi nhớ, tập trung và kỹ năng giải quyết nhiều công việc cùng lúc. Tuy nhiên trên thực tế, đối với trí thông minh tổng thể ở con người thì những trò chơi này không có có tác dụng.

Trong nghiên cứu, tình nguyện viên được yêu cầu thực hiện một trong ba nhiệm vụ có độ khó khác nhau, bao gồm ghi nhớ nhóm đồ vật khi đang tiến hành nhiệm vụ phức tạp khác, nhắc lại đồ vật theo theo thứ tự mà họ nhìn thấy trước đó, hoặc tìm kiếm đồ vật đặc biệt trong nhóm.

Kết quả cho thấy người tham gia hoàn thành nhiệm vụ ban đầu có dấu hiệu cải hiện trí nhớ làm việc (working memory), tuy nhiên khả năng giải quyết vấn đề mới, lý luận hay nhận dạng (fluid intelligence) thì không thay đổi.

Trò chơi trí tuệ không có tác dụng giúp con người thông minh hơn

Mối liên hệ giữa trí tuệ và bệnh thần kinh

John Nash, nhà bác học nổi tiếng người Mỹ, là một trong những nhà kinh tế học có ảnh hưởng nhất thế kỷ 20 với những cống hiến to lớn trong nhiều lĩnh vực: kinh tế thị trường, sinh học tiến hóa, trí tuệ nhân tạo…, nhưng John Nash lại mắc chứng tâm thần phân liệt. Một số người nổi tiếng khác trên thế giới từng mắc các bệnh tâm thần có thể kể đến như Abraham Lincoln, Isaac Newton hay Ernest Hemingway.

Nghiên cứu một loại gene có nhiệm vụ mã hóa protein kết nối canxi gọi là NCS-1, các nhà khoa học phát hiện rằng loại gene này cũng liên quan đến tính dẻo dai của khớp thần kinh. Một cách tình cờ, nghiên cứu đồng thời chỉ ra rằng sự tăng cường điều chỉnh của NCS-1 có liên quan đến chứng tâm thần phân liệt và rối loạn lưỡng cực.

Điều này có nghĩa rằng tính dẻo dai càng lớn, con người có thể thông minh hơn nhưng cũng có nguy cơ mắc bệnh tâm thần cao hơn. Trong một nghiên cứu khác vào năm 2005, các nhà khoa học nhận thấy những người làm bài kiểm tra toán học có kết quả cao hơn có nhiều khả năng bị rối loạn lưỡng cực.

Người thức đêm có thể thông minh hơn

Không ít nghiên cứu đã được thực hiện và chứng minh tác hại của việc thức đêm. Ảnh hưởng từ ánh sáng của máy tính, tivi, hay đơn giản là thức khuya khi nhịp độ sinh học cảnh báo rằng cơ thể cần được nghỉ ngơi thì đều gây cản trở đến một số quá trình sinh học trong cơ thể. Nguy cơ mắc tiểu đường, ung thư và các vấn đề sinh sản do đó cũng sẽ cao hơn.

Tuy nhiên theo nghiên cứu năm 2009, vì các hoạt động chỉ diễn ra vào ban ngày và ban đêm là thời gian ngủ nên những người có hoạt động vào đêm có thể sẽ thông minh hơn. Trong một nghiên cứu khác được tiến hành năm ngoái, các chuyên gia nhận thấy người thức đêm thường có điểm số cao hơn trong bài kiểm tra lập luận quy nạp. Đây là một chỉ số đánh giá trí thông minh nói chung ở người.

Các yếu tố đánh giá thông minh đều mang tính độc lập

Kiểm tra IQ không đánh giá hoàn toàn chính xác trí thông minh

Theo nghiên cứu với sự hỗ trợ về mặt ý tưởng của Canada năm 2012, trí thông minh được xác định bằng trí nhớ ngắn hạn, khả năng lý luận và ngôn ngữ của mỗi người. Những yếu tố này đều có tính độc lập và không thể xác định hoàn toàn bằng một bài kiểm tra IQ.

Trong bài phỏng vấn với Scientific American, nhà tâm lý học W. Joel Schneider cho biết tính hiệu quả của bài kiểm tra IQ phụ thuộc vào những gì được kiểm tra. Đối với kỹ năng học tập, phương pháp kiểm tra IQ không có hiệu quả bởi khả năng này có thể chịu tác động từ cơ hội, khác biệt về văn hóa, gia đình hay tính cách của mỗi người.

Theo Báo diễn đàn đầu tư